Vue 3

# Vue 3

可以在 https://github.com/vuejs/rfcs 看具体改动。

源码学习:https://juejin.cn/post/6925668019884523534

  • 响应式

    • 采用了ES2015的Proxy来代替Object.defineProperty,可以做到监听对象属性的增删和数组元素和长度的修改,还可以监听Map、Set、WeakSet、WeakMap,同时还实现了惰性的监听,不会在初始化的时候创建所有的Observer,而是会在用到的时候才去监听。
  • 模板

    • 2.x的机制导致作用域插槽变了,父组件会重新渲染,而3.0把作用于插槽改成了函数的方式,这样只会影响子组件的重新渲染,提升了渲染的性能。
  • 目前的代码 98% 以上使用 TypeScript 编写。

[TOC]

# 一、基础知识

# 1.1 watch 和 watchEffect的区别

参考链接 (opens new window)

# 1.1.1 watch

  • 用法:watch( source, cb, [options] )
    • source:可以是表达式或函数,用于指定监听的依赖对象
    • cb:依赖对象变化后执行的回调函数
    • options:可参数,可以配置的属性有 immediate(立即触发回调函数)、deep(深度监听)
  • 监听单个数据
<script>
import {reactive, watch} from 'vue'
export default {
    setup() { 
        const state = reactive({count: 0})

        watch(() => state.count, (newValue, oldValue) => {
          console.log(`原值为${oldValue}`)
          console.log(`新值为${newValue}`)
          /* 1秒后打印结果:
                  原值为0
                  新值为1
          */
        })

        // 1秒后将state.count的值+1
        setTimeout(() => {
          state.count ++
        }, 1000)
    }
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
  • 监听多个数据
<script>
import {reactive, watch} from 'vue'
export default {
    setup() { 
        const state = reactive({ count: 0, name: 'zs' })

         watch(
            [() => state.count, () => state.name], 
            ([newCount, newName], [oldvCount, oldvName]) => {
              console.log(oldvCount) // 旧的 count 值
              console.log(newCount) // 新的 count 值
              console.log(oldName) // 旧的 name 值
              console.log(newvName) // 新的 name 值
            }
          )

          setTimeout(() => {
            state.count ++
            state.name = 'ls'
          }, 1000)
    }
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# 1.1.2 watchEffect

<script>
import {reactive, watchEffect} from 'vue'
export default {
    setup() { 
          const state = reactive({ count: 0, name: 'zs' })

          watchEffect(() => {
          console.log(state.count)
          console.log(state.name)
          /*  初始化时打印:
                  0
                  zs

            1秒后打印:
                  1
                  ls
          */
          })

          setTimeout(() => {
            state.count ++
            state.name = 'ls'
          }, 1000)
    }
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

# 1.1.3 watchEffect相对于watch的区别

  1. 不需要手动传入依赖
  2. 每次初始化值会执行一次回调函数,以自动获取函数
  3. 无法获取到原值,只能得到变化后的值

# 1.2 toRefs避免es6结构消除props响应式

import { toRefs } from 'vue'

setup(props) {
	const { title } = toRefs(props)
	console.log(title.value)
}
1
2
3
4
5
6