vue经历从2.0到3.0更新之后,简而言之就是变得更轻,更快,使用起来更加方便。接下来我会着重于开发者来说⼀下两个不同版本的区别。
生命周期的变化
创建vue实例
main.js核心代码如下:
1 2 3 4 5 6 7 8
| import { createApp } from 'vue' import App from './App.vue'
const app = createApp(App) app.mount("#app")
|
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()
的get
和set
实现数据代理。
reactive使用Proxy实现数据代理,并且通过Reflect操作源对象内部的数据。
从使用方面
ref操作数据需要.value,template模板中不需要。
reactive都不需要.value
setup定义数据
1 2 3 4 5 6 7 8 9
| setup(){ let name='张三' let age=18 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(){ 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
| computed:{ fullName(){ return this.person2.firstName+'-'+this.person2.lastName } },
|
vue3计算属性:
1 2 3 4 5
| 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}){ console.log(attrs) console.log(slots) console.log(emit) console.log(expose) return {} },
|
shallowReactive
- 如果数据是服务器返回的LIST数据,而且只显示、不变更,那么最好是使用shallowRef来包装数据,可以节能。如果会有变更,那么应该用ref
- shallow的中文意义是“浅层的”,shallowReactive不代理深层property,只会指向原始对象的深层property。
- shallowReactive的用途是:如果一个对象的深层不可能变化,那么就没必要深层响应,这时候用shallowReactive可以节省系统开销。(印证第一点)
附录
引用文章:
vue2.0和vue3.0的区别
vue2.0和vue3.0的区别