3.0 特性
# 3.0 特性
# 生命周期
// 3.0中 只有卸载的生命周期的改变了名称,其他的没有变。
beforeDestroy ---> beforeUnmount
destroyed ---> unmounted
// 在 setup 函数中导入生命周期函数需一致加 on 前缀。
// setup 导入生命函数实例
setup -> beforeCreate
-> beforeCreated
beforeMount ---> onBeforeMount
mounted ---> onMounted
beforeUpdate ---> onBeforeUpdate
updated ---> onUpdated
beforeUnMount ---> onBeforeUnmount
unmounted ---> onUnmounted
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# v-model
// 2.x
<input v-model="msg" placeholder="请输入内容" />
// 底层实现。
<input :value={value} @input="value = $event.target.value" placeholder="请输入内容">
<script>
// 在 2.0 中 可以通过 model 配置项来改变 value 绑定的值, 默认值是 value
export default {
model: {
value: 'value',
event: 'input'
},
props: {
value: String
}
}
</script>
// 3.x
<input v-model:text="value" placeholder="请输入内容" />
// 底层实现。
<input :value={value} @update:text="value = $event.target.value" placeholder="请输入内容" />
<script>
// 在 3.0 值移除了 model 配置项,如需更改在 v-model 后面传递要修改的 prop 名。
export default {
props: {
text: String
}
}
</script>
// 注意点:在 3.x 中 .sync 移除了。合并到 v-model冒号绑定的值一起了。
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
27
28
29
30
31
32
33
# ref
3.x 中创建值类型数据为响应式。
<template>
<div>{{ count }}</div>
</template>
<script lang="ts">
import { ref } from 'vue'
export default {
setup() {
// 通过 ref 创建的数据,返回的格式是 { value: 0 }。
// 在 setup 中使用中需通过 .value 形式使用。模板中使用 count 不用 .value 形式,vue 会帮我们 .value。
const count = ref(0)
// 修改了 count 的值,页面使用到时,自动改变 count。
count.value = 333
return {
count
}
}
}
</script>
// 注意点:
// ref 也可以接受对象或者数组参数,返回格式就是 { value: 对象或数组 }。
// ref 创建的数据本质上还是通过 reactive 函数包裹然后再 value 中接受传过来的参数。
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# toRef
3.x 中将响应式对象中的某个属性转换成 ref 的形式,两者之间修改值都会改变,并触发响应式
<template>
<div>{{ nameRef }}</div>
</template>
<script lang="ts">
import { reactive, toRef } from 'vue'
export default {
setup() {
const state = reactive({
name: 123
})
const nameRef = toRef(state, 'name')
setTimeout(() => {
state.name = 222 // nameRef会改变
nameRef.value = 333 // state.name 会改变
}, 1500)
return {
nameRef
}
}
}
</script>
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
# toRefs
3.x 中将响应式对象的全部属性转换成 ref 形式,两者之间修改值都会改变,并触发响应式
<template>
<div>{{ ageRef }}</div>
</template>
<script lang="ts">
import { reactive, toRefs } from 'vue'
export default {
setup() {
const state = reactive({
age: 20
})
const stateRef = toRefs(state)
setTimeout(() => {
state.age = 30 // stateRef.age会改变
stateRef.age = 50 // state.age 会改变
}, 1500)
return stateRef
}
}
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# reactive
3.x 中创建引用类型数据的响应式
<template>
<div class="list">
<div v-for="(item, index) in countData" :key="index">{{ item }}</div>
</div>
</template>
<script lang="ts">
import { reactive } from 'vue'
export default {
setup() {
// 通过 reactive 创建的数据,返回的格式就是传过来的格式。
// 在使用中不需要 .value 形式。
const countData = reactive({
list: []
})
countData.list = [{a: 1, b: 2, c: 3}]
return {
countData
}
}
}
</scrip>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# watch
监听某个数据的变化,初始化时不会触发,并且要指定监听的数据。
<template>
<span>{{ numRef }}</span>
</template>
<script lang="ts">
import { watch, ref, reactive } from 'vue'
export default {
setup() {
// 监听多个数据 watch 第一个参数传数组 [newRef, numRef]
// 监听 ref 数据
const numRef = ref(0)
watch(
numRef,
(newVal, oldVal) => {
console.log(newVal)
},
{
deep: true
}
)
setTimeout(() => numRef.value = 5, 1500)
// 监听 reactive 数据
const state = reactive({
num: 0,
age: 10
})
watch(
() => state.num,
(newVal, oldVal) => {
console.log(newVal)
},
{
deep: true
}
)
setTimeout(() => state.num = 5, 1500)
}
}
</script>
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# watchEffect
对传入的回调函数里面的数据进行监听,并会在初始化时触发,进行收集依赖。
<template>
<span>{{ numRef }}}</span>
</template>
<script>
import { watchEffect, ref, reactive } from 'vue'
export default {
setup() {
const numRef = ref(0)
const state = reactive({
age: 0,
num: 10
})
// 初始化时会触发回调函数
watchEffect(() => {
if (numRef.value === 3) {
console.log('watchEffect执行了', numRef.value)
}
})
setTimeout(() => numRef.value = 3, 1500)
}
}
</script>
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
# 响应式
在 2.x 中 Vue 实现响应式是通过 Object.defineProtry 函数来劫持 data 中数据的获取和改变,并在其中订阅依赖和发布依赖来触发页面上数据的改变。他的缺点是不能监听新增和删除的操作,只有通过 Vue.set 和 Vue.delete 函数来触发响应式。
在 3.x 中 Vue,通过 new Proxy 函数来劫持。这个函数可以监听到新增和删除的操作。并且他还有更多的方法如:get, set, deleteProto 等来监听数据。但他本身是 ES6 才出现的,所以在 IE 浏览器不是兼容的。
# Vue3 比 Vue2 快在那些方面(体积小)
PatchFlag在编译时对节点进行标记,区分静态文本节点和动态节点。在 diff 算法比对中,如果是静态文本节点就不对对比,直接对比动态节点。hoistStatic将静态节点的定义,提升到父级作用域,进行缓存。多个相邻的静态节点,会被合并起来。cacheHandler将节点的事件进行缓存,下次如果有事件,直接取缓存的事件。SSR优化针对静态节点直接编译成字符串形式,不走 Vdom 流程。tree-shaking针对模板中使用的指令,或其他东西,引入对应的 API, 从而减少体积。