崇序猿的取经之路 vue3(三)

122 阅读3分钟

1666611198148.jpg

1 toRef | toRefs 延续响应式

1.1toRef

  • 针对一个响应式对象(reactive)的prop

  • 创建一个ref,具有响应式

  • 两者保持引用关系

    使用前提:针对的是响应式对象(reactive封装的)非普通对象
    

1.2 应用场景

  1. 想让响应式数据和以前的数据管理起来,并且更新响应式数据之后还不想更新ui
  2. 要将响应式对象中的某个属性提供给外部使用时

1.3 语法

    const name = toRef(obj,'name')

1.4 toRef vs ref

  • ref : 接受一个原始值,返回一个具有响应式的对象, 修改响应式数据不会影响以前的数据,数据发送变化,界面就会自动更新, 本质是拷贝
  • toRef : 接受一个响应式数据值,并把该属性包裹成ref对象,使其和原对象产生链接,一种引用关系

1.5 toRefs

 特性和toRefs一致

唯一不同的点

  • toRef: 复制 reactive 里的单个属性并转成 ref
  • toRefs: 复制 reactive 里的所有属性并转成 ref

hooks

2.1 hooks 的定义

顾名思义,Hook就是“钩子”的意思。

Hooks就是把某个目标结果钩到某个可能会变化的数据源或者事件源上,那么当被钩到的数据或者事件发生变化时,产生这个目标结果的代码会重新执行,产生更新后的结果。

核心工作 抽离: 抽离复用其实正是hooks擅长的部分   

hooks的设计初衷就是因为以前复用逻辑的方法都有一定的问题(如vue的mixin,react的高阶组件和renderProps模式),所以才搞出hooks让逻辑复用更方便,算是大家的一个通识 下面会提到vue mixin的痛处

要抽离复用,只要把抽离的部分再次封装成一个hooks,然后在需要复用的地方调用该hooks即可(hooks里面也可以直接调用另一个hooks

hooks本质其实就是一个包含状态的函数,所以函数做的它都能做,任何地方都可以复用,比mixin更容易追踪数据和逻辑的来源,且完全支持typescript的类型推断

2.2 命名规范 use

hooks 的命名都是以 use 作为开头,这个规范也包括了那么我们自定义的 hooks

2.3 为什么使用hooks

在拥有 Hooks 之前,我首先会想到的解决方案一定是 mixin

mixins 虽然有状态复用的能力,但它的弊端实在太多了

弊端一:难以追溯的方法与属性!

 export  default{
    mixins: [ a, b, c, d, e, f, g ],  // 当然,这只是表示它混入了很多能力`
    mounted() {
        console.log(this.name)
        // mmp!这个 this.name 来自于谁?我难道要一个个混入看实现?
    }
}

又或者:

a.js mixins: [b.js]
b.js mixins: [c.js]
c.js mixins: [d.js]

// 你猜猜看, this.name 来自于谁?
// 求求你别再说了,我血压已经上来了

弊端二:覆盖、同名?

当我同时想混入 mixin-a.js 和 mixin-b.js 以同时获得它们能力的时候,不幸的事情发生了:

由于这两个 mixin 功能的开发者惺惺相惜,它们都定义了 this.name 作为属性。

这种时候,你会深深怀疑,mixins 究竟是不是一种科学的复用方式。

弊端三:代价很大

仍然说上面的例子,如果我的需求发生了改变,我需要的不再是一个简单的状态 name,而是分别需 要 firstName 和 lastName

此时 name-mixin.js 混入的能力就会非常尴尬,因为我无法两次 mixins 同一个文件。

当然,也是有解决方案的,如:

// 动态生成mixin
function genNameMixin(key, funcKey) {
  return {
    data() {
      return {
        [key]: genRandomName()
      }
    },
    methods: {
      [funcKey]: function(v) {
        this.[key] = v
      } 
    }
  }
}
export default {
  mixins: [
    genNameMixin('firstName', 'setFirstName'),
    genNameMixin('lastName', 'setLastName'),
  ]
}

确实通过动态生成 mixin 完成了能力的复用,但这样一来,无疑更加地增大了程序的复杂性,降低了可读性。

因此,一种新的 “状态逻辑复用” 就变得极为迫切了——它就是 Hooks!

文章仅为学习记录所用