Vue3基础之响应式原理
我们通过使用proxy来实现一个对象A对另外一个对象B的代理,通过对A的修改来实现定义B的响应式修改
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script type="text/javascript">
//源数据
let person={
name:'张三',
age:18
}
//模拟Vue3中的响应式
const p=new Proxy(person,{
//有人读取p的属性时调用
get(target,propName){
return target[propName]
},
//有人修改或是追加时调用
set(target,propName,value){
return target[propName]=value
},
//有人删除时调用
deleteProperty (target,propName){
console.log('有人删除了person的${propName}属性')
return delete target[propName]
}
})
</script>
</body>
</html>
Reflect使用
在我们就行重复的添加属性的时候,如果使用之前的Object的话,就会出现报错
但是使用Refclect就不会出现
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Setup
1.setup的执行时间比beforecreated还要早,并且,里面的this是undefined
<template>
<h1>一个人的消息</h1>
<h2 v-show="person.name">姓名:{{ person.name }}</h2>
<h2 v-show="person.age">年龄:{{ person.age }}</h2>
</template>
<script>
import { reactive, ref } from 'vue';
export default {
name: 'Demo',
beforeCreate(){
console.log(`-----beforeCreate-----`)
},
setup() {
console.log(`-----setup-----`,this)
// 使用reactive包裹整个person对象
let person = reactive({
name: ref('张三'),
age: ref(30),
});
// 返回一个对象
return {
person,
};
}
}
</script>
2.参数
props:值为参数,包含组件传递的参数
context:上下文对象
attrs:值为对象,包含父组件传递过来的但是没有在props中声明的属性,类似于this.$attrs
slots:收到的插槽内容
emit:分发自定义事件函数
父组件App.vue
<template>
<Demo @hello="showHelloMsg" msg="你好啊" school="尚硅谷">
<span>尚硅谷</span>
</Demo>
</template>
<script>
import Demo from './components/demo.vue';
export default {
components: { Demo },
name: 'App',
setup(){
function showHelloMsg(value){
alert(`触发了一个hello事件,收到的参数为:${value}`)
}
return{
showHelloMsg
}
}
}
</script>
子组件Demo.vue
<template>
<h1>一个人的消息</h1>
<h2 v-show="person.name">姓名:{{ person.name }}</h2>
<h2 v-show="person.age">年龄:{{ person.age }}</h2>
<p>消息:{{ msg }}</p>
<p>学校:{{ school }}</p>
<button @click="test">测试触发Demo组件中的hello事件</button>
</template>
<script>
import { reactive, ref } from 'vue';
export default {
name: 'Demo',
props: ['msg', 'school'],
emits:['hello'],
setup(props,context) {
// console.log(props);
// console.log(context);
// console.log(context.attrs);//props中没有申明的就会出现在这里
// console.log(context.emit);//触发自定义事件的
// console.log(context.slots);//插槽
// 使用reactive包裹整个person对象
let person = reactive({
name: ref('张三'),
age: ref(30),
});
function test(){
context.emit('hello',666)
}
// 返回一个对象,包括person和props
return {
person,
msg: props.msg,
school: props.school,
test
};
}
}
</script>
<style>
</style>