1》所有的组合API函数都在这里使用,只在初始化的时候执行一次;
2》函数如果返回对象,对象中的属性和方法,模板中可以直接使用
基本语法结构
setup(props,{attrs,slots,emit}){
return {}
}
setup的执行时机
在beforeCreate之前执行一次
由于在beforeCreate之前执行,所以this为undefined,也就不能通过this来访问data method computed prop
所有的composition API都不可以
setup的返回值
一般都返回一个对象
setup对象中的属性和data返回的对象中的属性都可以在html模板中使用,会合并为组件对象的属性
setup对象中的方法和method中的方法会合并为组件对象的方法
在Vue3中尽量不要混合使用data和setup,methods和setup;如果有重名,setup优先
setup不能是一个async函数,因为返回值不再是return的对象,二是promise对象了
在mounted等原来vue就有的钩子函数,方法等里面,是可以通过this来访问setup中的属性,调用里面的方法,而且不需要通过value来获取;但是在setup内部方法访问内部属性,需要通过value来获取
setup的参数
1>props:是一个对象,里面有父组件向子组件传递的数据,并且是在子组件中使用props接收到的所有属性
2>context:是一个对象,里面有attrs对象 ,emit方法,slots对象
2.1>attars:获取当前对象组件标签上的所有属性,但是这些属性是在props中没有声明接收的
2.2>emit方法:用来定义和分发事件,相当于this.$emit
2.3>slots对象:插槽
作用1:定义一个简单数据(基本数据)类型的响应式;其实也可以定义复杂数据,只不过使用起来没那么方便
const name=ref(value)
返回一个ref对象,如果是在js中则需要通过操作ref对象的value值来操作这个变量,如果是html中则不需要
作用2:获取元素
ref获取页面元素
定义复杂数据类型(引用型)的响应式
const proxy=reactive(obj)
响应式是”深层的“,内部是通过ES6的Proxy实现的
ref和reactive简单使用实例:
setup以及ref,reactive的基本使用
{{ count }}
性名:{{ proxyObj.name }}
女友:{{ proxyObj.girlfriend.name }}
点击后页面会同步变化
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bdeZeYtI-1646054589096)(C:\Users\lucas\Desktop\学习\图片\xiangyingshi.jpg)]
如果操作代理对象,目标对象中的数据也会随之变化
所以如果想要在 操作数据的时候,界面也要跟着重新变化,就使用代理对象
ref和reactive对比
ref用来处理基本数据类型,reactive用来处理复杂数据类型(递归深度响应式)
ref其实也可以传入对象或数组,不过内部会自动将其转换为reactive的代理对象,所以对象或数组直接使用reactive就行,ref在setup中获取还需要点value
ref内部通过给value属性添加getter和setter来实现数据劫持,reactive内部通过proxy来实现对对象内部所有数据的劫持,并通过reflect操作对象内部数据
vue2:defineProperty
缺点:给对象或数组添加数据的时候,不是响应式的,需要使用$set来修改
vue3:Proxy和Reflect
let obj = {
name: "张三",
age: 25,
wife: {
name: "马冬梅",
age: 24,
creatrues: ["funny", "big eyes", "brave"],
},
};
const proxyObj = new Proxy(obj, {
get(targetObj, prop) {
return Reflect.get(targetObj, prop);
},
// 不仅可以修改属性,还能添加属性
set(targetObj, prop, val) {
return Reflect.set(targetObj, prop, val);
},
deleteProperty(targetObj, prop) {
return Reflect.deleteProperty(targetObj, prop);
},
});
app组件
请输入姓:
请输入名:
computed计算属性姓名fullName:
computed计算属性姓名fullName2:
watch监听姓名fullName3:
watchEffect监听姓名fullName4:
computed:接收回调函数;如果只有一个回调,则只读,如果有两回调(get,set),则是可读可改的响应式
watchEffect会默认执行一次(immediate),而且自带deep深度监听
1》都写在setup里面,切且加了 on ;接收一个回调函数
2》没有了beforeCreated和created;这里的操作可以直接写在setup中
3》beforeDestroy/destroyed变为了beforeUnmounted/unmounted
4》setup中对应的钩子比vue2中写的对应钩子要先执行
使用vue3组合API封装的可复用的功能函数;类似于vue2中的mixin
vue组件
x:{{ x }}
y:{{ y }}
hook.js文件
import { ref, onMounted, onBeforeUnmount } from "vue";
export default function () {
const x = ref(0);
const y = ref(0);
function handleClick(e) {
x.value = e.clientX;
y.value = e.clientY
}
onMounted(() => {
window.addEventListener("click", handleClick);
});
onBeforeUnmount(() => {
window.removeEventListener("click", handleClick);
});
return {
x,
y,
};
}
将响应式对象变为一个普通对象 ,但是里面每一个属性都是ref对象,仍然是响应式的
如果直接结构一个响应式对象,那么得到的属性就不具有响应式
使用场景:hook返回的是一个响应式对象,我们想直接结构使用时
() => {
// 方案1 return 的时候,对user结构赋值
// user.name += “=”;
// console.log(user.name);
// 方案 2:不是响应式
// name += “=”;
// console.log(name);
// 方案3:使用 toRefs
name.value += “=”;
}, 2000);
return {
// …user, 方案1,出来的时候结构赋值,但是这样结构出来的就不是响应式的数据了
name,
age,
name2,
age2,
};
},
});