Heavy! ! ! Responsive syntactic sugar in Vue3 (official website update)

Recently, the official website of vue has been updated, mainly to introduce some responsive optimization solutions.
The following is a summary of the knowledge points updated on the official website.

1. Syntactic sugar -- responsive variable $ref()

We used ref() to define a simple responsive data before, but when using it, we need to keep .value, which will cause more cumbersome.
$ref() solves this problem.

chestnut:

    let count=$ref(0)        //使用$ref()定义数据
    function increment() {
          count++        //此处就不需要再count.value了
    }

In fact, the use of $ref() is so simple, we only need to pay attention to:

Every reactive API that returns a ref ($ref, $computed, etc.) has a corresponding macro function prefixed with $.

as follows:

2. Destructuring through $()

We all know that the data defined by reactive will be lost when encountering destructuring/direct assignment! ! !
In response to the disadvantage of ref/reactive structure loss responsiveness, $() was introduced.

Chestnut 1: The response type deconstructed by hooks

//引入自定义的hooks函数
import { useMouse } from '@vueuse/core'
//解构出x,y  并且使用$()包裹赋予响应式。
const { x, y } = $(useMouse())
//这样解构出来的x,y都是响应式的了。
console.log(x, y)

//注意:
x 如果已经是一个 ref,则会简单地返回它本身,而不会再创建新的 ref。
如果一个被解构的值不是 ref (例如是一个函数),也仍然可以使用,这个值会被包装进一个 ref,因此其他代码都会正常工作。

Responsive props deconstruction

The use of defineProps in <script setup> has two pain points:
1. In order to maintain responsiveness, you always need to access these props as props.x. This means that you cannot destructure the return value of defineProps because the resulting variable will not be reactive and will not be updated.
2.
When using the declaration of type -based props , it is not convenient to declare the default value of these props. For this we provide the withDefaults() API, but it is still clumsy to use.

When defineProps is used with destructuring, we can work around these issues by applying compile-time transformations,

chestnut:

<script setup lang="ts">
//定义props的类型
  interface Props {
    msg: string
    count?: number
    foo?: string
  }

//从defineProps中解构值,并且默认赋值可以使用,解构时起别名也可以使用。
  const {
    msg,
    // 默认值正常可用
    count = 1,
    // 解构时命别名也可用
    // 这里我们就将 `props.foo` 命别名为 `bar`
    foo: bar
  } = defineProps<Props>()

//监听打印
  watchEffect(() => {
    // 会在 props 变化时打印
    console.log(msg, count, bar)
  })
</script>

3. Problems with syntax sugar of $ref()

Although reactive variables allow us to no longer be troubled by .value, it also makes it possible for us to cause "responsive loss" problems when passing reactive variables between functions. as follows:

Lost Response --

Scenario 1: Pass in a function as a parameter

//此处x是限制了个Ref类型,并且又需要是number类型的参数
function trackChange(x: Ref<number>) {
  watch(x, (x) => {
    console.log('x 改变了!')
  })
}

//定义一个响应式对象
let count = $ref(0)

//传入count错误
trackChange(count) // 无效!



//分析原因:
1.因为在执行trackChange(count)的时候,
  其实代码被编译成了:trackChange(count.value)
2.这里的 count.value 是以一个 number 类型值的形式传入,然而 trackChange 期望接收的是一个真正的 ref,所以传入的类型错误。

Scenario 2: As a function return value

//如果将响应式变量直接放在返回值表达式中会丢失掉响应性:
function useMouse() {
  let x = $ref(0)
  let y = $ref(0)

  // 不起效!
  return {x,y}
}

//分析原因:
1.上面的语句实际上被编译为了:
return {
  x: x.value,
  y: y.value
}
2.实际上是把一个number类型的值返回出去了,而不是返回真正的 ref。

Then, $$() appeared for these two scenarios

4. Keep the responsiveness when passing between functions --$$()

For the above scenarios of loss of responsiveness, vue launched $$() to solve it. Let's look at the solution of scenario 1 first.

To solve scenario one:

let count = $ref(0)
//trackChange(count)  此处不要再这样了

//而是变成$$()进行包裹,
++ trackChange($$(count))

//$$() 的效果就像是一个转义标识:$$() 中的响应式变量不会追加上 .value。

Solve scenario two:

function useMouse() {
  let x = $ref(0)
  let y = $ref(0)


  // 返回的时候用$$()进行包裹,,修改后起效
  return $$({
    x,
    y
  })
}
//$$() 调用时任何对响应式变量的引用都会保留为对相应 ref 的引用

Using $$() on destructured props

$$() also works with destructured props, since they are also reactive variables.
//定义声明props
const { count } = defineProps<{ count: number }>()

//使用$$()对结构出的props进行包裹
passAsRef($$(count))

5. Note: Responsive syntactic sugar needs to be enabled explicitly!!!

5.1 In Vite -- open in vite.config.js

// vite.config.js
export default {
  plugins: [
    vue({
      reactivityTransform: true
    })
  ]
}

5.2 TS integration -- open in env.d.ts

If you are also using TS, then you also need to enable the display in TS.

 <reference types="vue/macros-global" />

PS: If you explicitly import macro functions from vue/macros, you don't need to declare them globally like this.


Hurry up and practice, brother dei, if you don't practice, you will be useless!

Remember to support me, okay, I wish you good things in pairs~~~~~~

Guess you like

Origin blog.csdn.net/Yan9_9/article/details/128917765