- 安装
npm install -g @vue/cli
vue --version
vue create vue-test
- Proxy、Reflect
- 通过window的Proxy对象实现代理,因为目的是要知道数据何时变化,再变化之后要去更改视图随之变化,再Proxy中使用了Reflect(反射),通俗来理解和obj.a没有什么区别,但是对于框架封装来说,他的返回值是Boolean类型,比起Object.defineProperty不断的try…catch更加方便,值得注意的是新增属性与修改属性都会触发set,set被触发,自然会有一系列操作去更新视图。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
const person = {
name:'hhh'
}
let p = new Proxy(person,{
get(target, propName){
console.log('读取了数据')
return Reflect.get(target, propName)
},
set(target, propName, newValue){
console.log('修改/新增更新视图')
Reflect.set(target, propName, newValue)
},
deleteProperty(target, propName){
console.log('删除更新视图')
return delete Reflect.deleteProperty(target, propName)
}
})
console.log(p)
</script>
</body>
</html>
<template>
<span>{{ sum }}</span>
<button @click="onChangeNum">点我+1</button>
<br />
<div>
<span>{{ msg }}</span>
<button @click="msg += '!'">点我+1</button>
</div>
</template>
<script>
import { reactive, ref, watch } from 'vue';
export default {
name: 'App',
setup() {
let sum = ref(0);
let msg = ref('hh');
function onChangeNum() {
sum.value++;
}
watch(
sum,
(newValue, oldValue) => {
console.log(newValue);
console.log(oldValue);
},
{ immediate: true },
);
watch(
[sum, msg],
(newValue, oldValue) => {
console.log(newValue);
console.log(oldValue);
},
{ immediate: true },
);
return {
sum,
msg,
onChangeNum,
};
},
};
</script>
- 监视reative所定义的响应式数据
- 直接监视reactive对象(此处同理ref对象写法,因为ref对于对象形式,内部依然使用了reactive,所以结果一致,唯一有区别的的就是watch时需要监视sum.value || msg.value)
watch(
sum.value,
(newValue, oldValue) => {
console.log(newValue);
console.log(oldValue);
},
{ immediate: true },
);
<template>
<span>{{ sum.count }}</span>
<button @click="onChangeNum">点我+1</button>
<br />
<div>
<span>{{ msg }}</span>
<button @click="msg.text += '!'">点我+1</button>
</div>
</template>
<script>
import { reactive, ref, watch } from 'vue';
export default {
name: 'App',
setup() {
let sum = reactive({
count: 0,
});
let msg = reactive({
text: 'hhhh',
});
function onChangeNum() {
sum.count++;
}
watch(sum, (newValue, oldValue) => {
console.log(newValue);
console.log(oldValue);
});
watch([sum, msg], (newValue, oldValue) => {
console.log(newValue);
console.log(oldValue);
});
return {
sum,
msg,
onChangeNum,
};
},
};
</script>
-监视reactive定义的数据,无论嵌套多深,默认开启了deep:true
<div>
<span>{{ msg }}</span>
<button @click="msg.job.text += '!'">点我+1</button>
</div>
watch(
msg,
(newValue, oldValue) => {
console.log(newValue);
console.log(oldValue);
},
{ immediate: true },
);
- 监视reactive定义的某一个属性应写成函数形式(此时oldValue好用了)
watch(
()=> msg.job.text,
(newValue, oldValue) => {
console.log(newValue);
console.log(oldValue);
},
{ immediate: true },
);
- 监视reactive定义的某些个属性应写成数组嵌套函数形式(此时oldValue好用了)
watch(
[() => msg.job.text, () => msg.text],
(newValue, oldValue) => {
console.log(newValue);
console.log(oldValue);
},
{ immediate: true },
);
- 监视reactive定义的某个数据(对象形式),此时直接()=> msg.job是检测不到的,数据变化了,但是检测不到,此时应开启deep:true(此时oldValue不好用了)
let msg = reactive({
text:'hhhh',
job: {
text: 'xxx',
},
});
watch(
() => msg.job,
(newValue, oldValue) => {
console.log(newValue);
console.log(oldValue);
},
{ immediate: true, deep: true },
);
- watchEffect 初始化执行一次,相当于immediate: true,内部响应式数据变化,重新执行,注重过程,computed注重结果,这里他的x值是改变后值,
let msg = reactive({
text: 'hhhh',
job: {
text: 'xxx',
arr: [1, 2],
},
});
watchEffect(() => {
const x = msg.text;
console.log('执行了');
});
此时objectToRef 是一个RefImpl对象,其中value属性为msg中的text值
setup() {
let sum = ref({
count: 0,
});
let msg = reactive({
text: 'hhhh',
job: {
text: 'xxx',
arr: [1, 2],
},
});
function onChangeNum() {
sum.value.count++;
}
console.log(objectToRef);
return {
text: toRef(msg, 'text'),
jobText: toRef(msg.job, 'text'),
sum,
msg,
onChangeNum,
};
},
- toRefs 直接返回对象形式,通过…扩展运算符直接return出去,内部无论多深都是proxy对象
setup() {
let sum = ref({
count: 0,
});
let msg = reactive({
text: 'hhhh',
job: {
text: 'xxx',
arr: [1, 2],
},
});
function onChangeNum() {
sum.value.count++;
}
const objectToRef = toRefs(msg);
console.log(objectToRef);
return {
...objectToRef,
sum,
msg,
onChangeNum,
};
|