Vue3 第四节 自定义hook函数以及组合式API

1.自定义hook函数

2.toRef和toRefs

3.shallowRef和shallowReactive

4.readonly和shallowReadonly

5.toRaw和markRaw

6.customref

一.自定义hook函数

① 本质是一个函数,把setup函数中使用的Composition API 进行了封装,类似于vue2.x中的mixin

自定义hook函数可以进行代码复用,让setup中的逻辑更清晰

② 代码实现

(1)新建hooks

(2) 将相关功能和接口写入

usePoint.js

javascript 复制代码
import { reactive, onMounted, onBeforeUnmount } from "vue"
export default function () {
  let point = reactive({
    x: 0,
    y: 0
  })

  function savePoint (event) {
    console.log(event.pageX, event.pageY)
    point.x = event.pageX
    point.y = event.pageY
  }
  onMounted(() => {
    window.addEventListener('click', savePoint)
  })

  onBeforeUnmount(() => {
    window.removeEventListener('click', savePoint)
  })

  return point
}

(3)引入和使用

(4)代码汇总

Demo.vue

javascript 复制代码
<template>
  <h2>当前求和为:{{ sum }}</h2>
  <button @click="sum++">点我+1</button>
  <hr />
  <h2>当前点击时鼠标的坐标为:x : {{ point.x }} y:{{ point.y }}</h2>
</template>
<script>
import usePoint from '../hooks/usePoint'
import { reactive, ref, onMounted, onBeforeUnmount } from 'vue'
export default {
  name: 'Demo',
  // 数据
  setup () {
    let sum = ref(0)
    let point = usePoint()
    return {
      sum,
      point
    }
  },
}
</script>

<style>
</style>

Test.vue

javascript 复制代码
<template>
  <h2>我是Test组件</h2>
  <h2>当前点击时鼠标的坐标为:x : {{ point.x }} y:{{ point.y }}</h2>
</template>

<script>
import usePoint from '../hooks/usePoint'
export default {
  name: 'Test',
  setup () {
    const point = usePoint()
    return { point }
  }

}
</script>

二. toRef和toRefs

① 作用:创建一个ref对象,其value值指向另一个对象中的某个属性

② 应用: 要将响应式对象中的某个属性单独提供给外部使用,不想丢失响应式

toRef与toRefs功能一致,toRefs可以批量创建多个ref对象,处理这个对象中的所有属性

③ 代码

javascript 复制代码
<template>
  <h4>{{ person }}</h4>
  <h2>姓名:{{ name }}</h2>
  <h2>年龄:{{ age }}</h2>
  <h2>薪资:{{ job.j1.salary }}</h2>
  <button @click="name += '~'">修改姓名</button>
  <button @click="age++">增长年龄</button>
  <button @click="job.j1.salary++">涨薪</button>
</template>
<script>
import { reactive, ref, toRef, toRefs } from 'vue'
export default {
  name: 'Demo',
  // 数据
  setup () {
    let person = reactive({
      name: '张三',
      age: 18,
      job: {
        j1: {
          salary: 20
        }
      }
    })
    return {
      person,
      // name: toRef(person, 'name'),
      // age: toRef(person, 'age'),
      // salary: toRef(person.job.j1, 'salary')
      ...toRefs(person)
    }
  }
}
</script>

<style>
</style>

三.shallowRef和shallowReactive

引入:import { shallowReactive, shallowRef } from 'vue'

① shallowReactive:只处理对象最外层属性的响应式(浅响应式)

② shallowRef: 只处理基本数据类型的响应式,不进行对象的响应式处理

③ 使用场景:

  • 如果有一个对象数据,结构比较深,但变化只是外层属性变化的时候使用shallowReactive
  • 如果有一个对象数据,后续功能不会修改对象中的属性,而是生成新的对象替换 => shallowRef

四.readonly和shallowReadonly

应用场景:不希望数据被修改

① readonly: 让一个响应式数据变成只读的(深只读)

② shallowReadonly:只限制对象中的第一层数据

对ref的对象同样有用

五.toRaw和markRaw

① toRaw

  • 作用:将一个由reactive生成的响应式对象转为普通对象
  • 使用场景:用于读取响应式对象对应的普通对象,对这个普通对象的所有操作,不会引起页面更新

② markRaw

  • 作用:标记一个对象,使其永远不会再成为响应式对象
  • 应用场景

1.有些值不应该被设置为响应式的,例如复杂的第三方类库等

2.当渲染具有不可变数据源的大列表时,跳过响应式转换可以提高性能

操作数据,数据确实发生变化了,但是界面不会发生变化,没有响应式

六.customref

作用:创建一个自定义的ref,并对其依赖项跟踪和更新触发进行显式控制

实现防抖效果代码实现:

javascript 复制代码
<template>
  <input type="text" v-model="keyWord" />
  <h3>{{ keyWord }}</h3>
</template>

<script>
import { ref, customRef } from 'vue'
import Demo from './components/Demo.vue'
export default {
  name: 'App',
  setup () {
    // 自定义ref
    function myRef (value, delay) {
      let timer
      return customRef((track, trigger) => {
        return {
          get () {
            track() // 通知Vue追踪value的变化
            console.log('有人从myRef中读取数据了')
            return value
          },
          set (newValue) {
            console.log('有人把myRef中的数据改了')
            clearTimeout(timer)
            timer = setTimeout(() => {
              value = newValue
              trigger() // 通知vue去重新解析模板
            }, delay)
          }
        }
      })
    }
    let keyWord = myRef('hello', 500)
    return { keyWord }
  }
}
</script>
相关推荐
一 乐9 分钟前
校园二手交易|基于springboot + vue校园二手交易系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端
科技D人生19 分钟前
Vue.js 学习总结(20)—— Vue-Office 实战:word、pdf、excel、ppt 多种文档的在线预览
vue.js·word·vue-pdf·stylesheet·docx-preview·vue-office
vx1_Biye_Design21 分钟前
基于Spring Boot+Vue的学生管理系统设计与实现-计算机毕业设计源码46223
java·vue.js·spring boot·spring·eclipse·tomcat·maven
vx_Biye_Design22 分钟前
基于Spring Boot+vue的湖北旅游景点门票预约平台的设计--毕设附源码29593
java·vue.js·spring boot·spring cloud·servlet·eclipse·课程设计
hedley(●'◡'●)22 分钟前
基于cesium和vue的大疆司空模仿程序
前端·javascript·vue.js·python·typescript·无人机
qq5_81151751524 分钟前
web城乡居民基本医疗信息管理系统信息管理系统源码-SpringBoot后端+Vue前端+MySQL【可直接运行】
前端·vue.js·spring boot
百思可瑞教育25 分钟前
构建自己的Vue UI组件库:从设计到发布
前端·javascript·vue.js·ui·百思可瑞教育·北京百思教育
百锦再25 分钟前
Vue高阶知识:利用 defineModel 特性开发搜索组件组合
前端·vue.js·学习·flutter·typescript·前端框架
hdsoft_huge27 分钟前
1panel面板中部署SpringBoot和Vue前后端分离系统 【图文教程】
vue.js·spring boot·后端
CappuccinoRose1 小时前
JavaScript 学习文档(二)
前端·javascript·学习·数据类型·运算符·箭头函数·变量声明