一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第21天,点击查看活动详情
Composition API也叫组合式API,是Vue3的新特性。如果是小型项目,可以不使用Composition API。但是如果项目大了,像之前的vue相关代码需要配置到option的指定位置,找起来麻烦,后期维护复杂,复用性不高,则选择Composition API是更好的,几百个组件,共享和重用代码就尤为重要了。 以下会逐一用最简单的语言总结解析vue3的组合式API。
Setup的使用
setup接受两个参数,一个是props,一个是context上下文
使用setup定义变量和方法,不需要在data中定义变量,或者在methods中定义方法,可以直接返回,即可在模板中使用。
setup 为created实例被完全初始化之前被调用,无法调用外部的方法(如下实例methods中的myname函数),也没有this,但是setup可以被外部的方法执行。
<script>
const app = Vue.createApp({
template:`
<div @click="handle">name:{{name}} </div>
`,
methods:{
myname(){
console.log('hh');
}
}
mountd(){
console.log(this.$options.setup());//可以打印出{name:'vivi',handle:f}
}
setup(props,context){
this.myname();//无法执行,报错。
return {
name:'vivi',
handle:()=>{
console.log('vivi');
}
}
}
});
const vm = app.mount("#root");
</script>
-
props参数:父组件传递过来的属性值
-
context参数:context参数中有attrs,slots,emit
attrs:是一个None-Props属性,接收到除prop以外的属性
slots:关于插槽的内容。
emit:用于触发自定义事件
ref reactive 响应式的引用
setup中返回的数据是没有响应式的。
如下,name两秒后并不会变成小新。
<script>
const app = Vue.createApp({
template:`
<div>name:{{name}} </div>
`,
setup(props,context){
let name = 'vivi';
setTimeout(()=>{
name="小新";
},2000)
return {
name
}
}
});
const vm = app.mount("#root");
</script>
此时,就需要ref或者reactive进行包装,让其有响应式的引用。
原理:通过proxy对数据进行封装,当数据变化时,触发模板内容的更新
-
ref 处理基础类型数据
如下,"vivi"变成Proxy({value:"vivi"})
那么name两秒后就会变成小新
<script>
const app = Vue.createApp({
template:`
<div>name:{{name}} </div>
`,
setup(props,context){
const {ref} = Vue;
let name = ref('vivi');
setTimeout(()=>{
name.value = "小新";
},2000)
return {
name
}
}
});
const vm = app.mount("#root");
</script>
-
reactive 处理非基础数据类型
{name:'vivi'}变成proxy({name:'vivi'})
那么name两秒后就会变成小新
<script> const app = Vue.createApp({ template:` <div>name:{{nameObj.name}} </div> `, setup(props,context){ const {reactive} = Vue; let nameObj = reactive({name:'vivi'}); setTimeout(()=>{ nameObj.name = "小新"; },2000) return { nameObj } } }); const vm = app.mount("#root"); </script>
如果不想数据变成响应式,可以使用readonly把响应式变量设置为只读。修改后则会报错。
如引入const {readonly}=Vue后,设置readonly:let name1 = readonly(name)
toRefs/toRef
-
toRefs
如果想直接解构reactive的值,需要使用toRefs,如果直接解构会失去响应式功能。
将proxy({name:'vivi',sex:'女'})解构成:
name:proxy(value:'vivi')和sex:proxy(value:'女')
-
toRef
对于没有原先没有的属性可以使用toRef,否则也是没有响应式的。(已经有的属性也可以)。
<script>
const app = Vue.createApp({
template:`
<div>name:{{name}} </div>
<div>sex:{{sex}} </div>
<div>age:{{age}} </div>
`,
setup(props,context){
const {reactive} = Vue;
let nameObj = reactive({name:'vivi',sex:'女'});
const {name,sex} = toRefs(nameObj);
const {age} = toRef(nameObj,'age');
setTimeout(()=>{
name.value = "小新";
sex.value = "男";
age.value = '18'
},2000)
return {
name,sex,age
}
}
});
const vm = app.mount("#root");
</script>