vue3初体验和心得

137 阅读1分钟

最近因为跳槽换了公司,公司项目是v3.4的,发现hooks封装极其重,让我脑海中仅存的v2的语法感觉很别扭,即便是从react转过来的,但是还是有很多地方第一眼没明白,主要是钩子和宏太多了,当初只是大概过了一下v3最初版本的语法,没去延申扩展性。以下是实操v3几天的笔记,生命周期钩子我就不提了。主要是记录自己的一些觉得有趣的地方。

1.$和$$宏的区别

const data = $computed(() => data?.data);
  return {
    status: $$(data?.status),
    data: $$(data),
    refetch,
  };

第一眼看到这$computed是啥啊,$$(data)又是啥啊,啥玩意这是。导致我一脸懵逼,于是查阅了vue3官方文档,再这儿有明确的解释,我是看了2遍才彻底理解: 在vue中传参默认情况如下:

function trackChange(x: Ref<number>) {
  watch(x, (x) => {
    console.log('x 改变了!')
  })
}

let count = $ref(0)
trackChange(count) // 无效!

调用函数的时候 使用 func(a)是能保证响应式的,a传过去是一个ref对象的响应式对象

但是在后续版本中 为了减少ref声明的变量 使用中使用 .value 的复杂写法 升级了一个宏

每一个会返回 ref 的响应式 API 都有一个相对应的、以 $ 为前缀的宏函数。包括以下这些 API:

  • ref -> $ref
  • computed -> $computed
  • shallowRef -> $shallowRef
  • customRef -> $customRef
  • toRef -> $toRef

假设有一个期望接收一个 ref 对象为参数的函数:

function trackChange(x: Ref<number>) {
  watch(x, (x) => {
    console.log('x 改变了!')
  })
}

let count = $ref(0)
trackChange(count) // 无效!

上面的例子不会正常工作,因为代码被编译成了这样:因为$ 这个宏在编译的时候 自动携带了.value所以导致我们最后编译成了一个原始值

let count = ref(0)
trackChange(count.value)

这里的 count.value 是以一个 number 类型值的形式传入,然而 trackChange 期望接收的是一个真正的 ref。要解决这个问题,可以在将 count 作为参数传入之前,用 () 包装:() 包装: 就是再吧$简写的对象找到他的对应的ref对象 进行传参 属于 负负得正的写法

let count = $ref(0)
- trackChange(count)
+ trackChange($$(count))

上面的代码将被编译成:

import { ref } from 'vue'

let count = ref(0)
trackChange(count)

以上是官网的例子,我个人的理解是:$宏语法是为了让我们更加简便使用,从而再使用过程中少写.value,这种再当前模板作为变量使用确实是没问题的,但是涉及到传参等问题,因为最后编译,识别到宏后会自动追加.value,所以倒是传参过去的实参失去了ref,这种就需要$$来找回引用的原ref响应对象。属于 负负得正的写法。

2.项目中使用了vueusejs而非pina实现数据共享

官网

项目中几乎使用的是createSharedComposable 实现数据共享,本意只创造一个hooks观察器,多初使用 只需要调用当前hooks即可,不会重新生成一个观察器,逻辑代码也基本写再这里面了。

export const useGlobalState = createSharedComposable(
  () => {
    const count = ref(0)
    return { count }
  }
)

使用:

const { count } = $(useGlobalState())

这样的语法 使其返回的count的ref对象也识别成响应式不用再去写.value即可