​ vue经历从2.0到3.0更新之后,简而言之就是变得更轻,更快,使用起来更加方便。接下来我会着重于开发者来说⼀下两个不同版本的区别。


生命周期的变化

imgTitle


创建vue实例

​ main.js核心代码如下:

1
2
3
4
5
6
7
8
import { createApp } from 'vue'
import App from './App.vue'

//简写:createApp(App).mount('#app')
const app = createApp(App)
app.mount("#app")
//app.use(store)可以引入vuex
//app.use(router)可以引入路由

​ vue3中的app单文件不再强制要求必须有根元素。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<template>
<!-- Vue3组件中的模板结构可以没有根标签 -->
<h3>我是App组件</h3>
<h3>姓名:{{person.name}}</h3>
<h3>年龄:{{person.age}}</h3>
<h3>工作职位:{{person.job.type}}</h3>
<h3>薪水:{{person.job.salary}}</h3>
<h3>爱好:{{person.hobby}}</h3>
<h3>测试的数据c:{{person.job.a.b.c}}</h3>
<button @click="changeInfo">修改信息</button>
<hr>
<h3>一个人的信息</h3>
姓:<input type="text" v-model="firstName">
名:<input type="text" v-model="lastName">
全名:<input type="text" v-model="fullName">
<hr>
<use-point/>
</template>

setup()函数

​ setup是所有Composition API(组合API)“表演的舞台”,所有数据、方法均配置在setup中。相当于vue2中data与methods的组合。

ref与reactivate函数

从定义数据方面

​ ref通常用来定义基本类型数据,而reactive用来定义对象或者数组类型的数据。

​ ref也可以定义对象或数组类型,只不过它内部会智能地通过reactive转为代理对象

从原理方面

​ ref通过Object.defineProperty()getset实现数据代理。
​ reactive使用Proxy实现数据代理,并且通过Reflect操作源对象内部的数据。

从使用方面

​ ref操作数据需要.value,template模板中不需要。
​ reactive都不需要.value

setup定义数据

1
2
3
4
5
6
7
8
9
setup(){  
let name='张三'
let age=18
//ref函数定义,调用时为job.value.XXXX
let job=ref({
type:"前端工程师",
salary:'30K'
})
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
setup(){
//reactive函数构造
let person=reactive({
name:'张三',
age: 18,
job:{
type:"前端工程师",
salary:"30K",
a:{
b:{
c:666
}
}
},
hobby:['抽烟','喝酒','打牌']
})

let person2=reactive({
firstName:'张',
lastName:'三',
fullName:''
})
}

计算属性

​ vue2计算属性使用方法:

1
2
3
4
5
6
//Vue2计算属性使用方法
computed:{
fullName(){
return this.person2.firstName+'-'+this.person2.lastName
}
},

​ vue3计算属性:

1
2
3
4
5
//引入vue.computed之后计算属性的定义法
//未考虑计算属性fullName被修改的情况
person.fullName=computed(()=>{
return person2.firstName+'-'+person2.lastName
})
1
2
3
4
5
6
7
8
9
10
11
//完整写法(考虑读和写)
person2.fullName=computed({
get(){
return person2.firstName+'-'+person2.lastName
},
set(value){
const nameArr=value.split('-')
person2.firstName=nameArr[0]
person2.lastName=nameArr[1]
}
})

函数方法(代替vue2中的methods)

​ 直接在setup里定义:

1
2
3
4
5
6
7
8
function changeInfo(){
person.name='李四',
person.age=48,
person.job.type='UI设计师',
person.job.salary='60K',
person.job.a.b.c=999,
person.hobby[0]="学习"
}

props

​ 因为props是响应式的,所以不能使用ES6解构,会消除prop的响应性,如果需要解构prop,可以在setup函数中使用toRefs。

  • 使用toRefs和toRef的区别:
    • 如果想要解构全部的可以使用toRefs(返回对象中所有属性都是响应式的,但是会耗性能)
    • 解构其中的某个属性可以用toRef(将对象的某一个属性作为引用返回)
1
2
3
4
5
6
7
setup(props){
let title1=reactive(props.title)
let {name}=toRefs(title1)
return {
name
}
}

​ 或者:

1
2
3
4
5
6
7
setup(props){
let title1=reactive(props.title)
let name = toRef(title1,'name')
return {
name
}
}

Context

​ context是一个普通的javascript对象,也就是说,他不是响应式的,可以安全的对context使用es6解构。

1
2
3
4
5
6
7
8
9
10
11
setup(props, {attrs,slots,emit,expose}){
//Attribute (非响应式对象,等同于$attrs)
console.log(attrs)
//插槽(非响应式对象,等同于$slots)
console.log(slots)
//触发事件(方法,等同于$emit)
console.log(emit)
//暴露公共property(函数)
console.log(expose)
return {}
},

shallowReactive

  • 如果数据是服务器返回的LIST数据,而且只显示、不变更,那么最好是使用shallowRef来包装数据,可以节能。如果会有变更,那么应该用ref
  • shallow的中文意义是“浅层的”,shallowReactive不代理深层property,只会指向原始对象的深层property。
  • shallowReactive的用途是:如果一个对象的深层不可能变化,那么就没必要深层响应,这时候用shallowReactive可以节省系统开销。(印证第一点)

附录

引用文章:

vue2.0和vue3.0的区别

vue2.0和vue3.0的区别