shallowReactive
与shallowRef
shallow:浅的,和deep相反shallowReactive
:只处理对象最外层属性的响应式shallowRef
:只处理基本数据类型的响应式,不进行对象的响应式处理
如果有一个对象数据,结构比较深,但是变化只对外层属性变化:使用shallowReactive
如果有一个对象数据,后序不会修改对象中的属性,而是生成新的对象来替换:使用shallowRef
<template>
<h4>当前的x.y值是:{{ x.y }}</h4>
<button @click="x={y:888}">点我替换x</button>
<button @click="x.y++">点我x.y++</button>
<hr>
<h4>{{ person }}</h4>
<h2>姓名:{{ person.name }}</h2>
<h2>年龄:{{ person.age }}</h2>
<h2>薪资:{{ person.job.j1.salary }}K</h2>
<button @click="person.name+='~'">修改姓名</button>
<button @click="person.age++">增长年龄</button>
<button @click="person.job.j1.salary++">涨薪</button>
</template>
<script>
import {shallowReactive, shallowRef} from 'vue'
export default {
name: 'App',
setup() {
//数据
let person = shallowReactive({// 只考虑第一层数据的响应式,在修改salary的时候,是修改不成功的
name: '张三',
age: 18,
job: {
j1: {
salary: 20
}
}
})
let x = shallowRef({
y: 0
});
console.log('******', x)
//返回一个对象(常用)
return {
x,
person
}
}
}
</script>
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
readonly
与shallowReadonly
readonly
:让一个响应式数据变成只读(深只读)shallowReadonly
:让一个响应式数据变成只读(浅只读)
<template>
<h4>当前求和为:{{ sum }}</h4>
<button @click="sum++">点我++</button>
<hr>
<h2>姓名:{{ person.name }}</h2>
<h2>年龄:{{ person.age }}</h2>
<h2>薪资:{{ person.job.j1.salary }}K</h2>
<button @click="person.name+='~'">修改姓名</button>
<button @click="person.age++">增长年龄</button>
<button @click="person.job.j1.salary++">涨薪</button>
</template>
<script>
import {reactive, readonly, ref, shallowReadonly} from 'vue'
export default {
name: 'App',
setup() {
//数据
let sum = ref(0)
let person = reactive({
name: '张三',
age: 18,
job: {
j1: {
salary: 20
}
}
})
person = readonly(person);// person里的任何东西都改不了
person = shallowReadonly(person);// 浅层次的readonly,深层次的可以修改
sum = readonly(sum);// sum改不了
sum = shallowReadonly(sum);// sum改不了
//返回一个对象(常用)
return {
sum,
person
}
}
}
</script>
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
toRaw
与markRaw
toRaw
:将一个reactive
生成的响应式对象转为普通对象,用于读取响应式对象对应的普通对象,对这个普通对象的操作,页面都不会更新。markRaw
:标记一个对象,使其永远不会成为响应式对象,当有些值没必要设置成响应式的时候,可以跳过响应式转换提高性能,例如复杂的第三方类库等。
<template>
<h4>当前求和为:{{ sum }}</h4>
<button @click="sum++">点我++</button>
<hr>
<h2>姓名:{{ name }}</h2>
<h2>年龄:{{ age }}</h2>
<h2>薪资:{{ job.j1.salary }}K</h2>
<h3 v-show="person.car">座驾信息:{{ person.car }}</h3>
<button @click="name+='~'">修改姓名</button>
<button @click="age++">增长年龄</button>
<button @click="job.j1.salary++">涨薪</button>
<button @click="showRawPerson">输出最原始的person</button>
<button @click="addCar">给人添加一台车</button>
<button @click="person.car.name+='!'">换车名</button>
<button @click="changePrice">换价格</button>
</template>
<script>
import {markRaw, reactive, ref, toRaw, toRefs} from 'vue'
export default {
name: 'App',
setup() {
//数据
let sum = ref(0)
let person = reactive({
name: '张三',
age: 18,
job: {
j1: {
salary: 20
}
}
});
function showRawPerson() {
const p = toRaw(person);
p.age++;
console.log(p);
}
function addCar() {
let car = {name: '奔驰', price: 40};
person.car = markRaw(car);
}
function changePrice() {
person.car.price++;
console.log(person.car.price);
}
//返回一个对象(常用)
return {
sum,
person,
...toRefs(person),
showRawPerson,
addCar,
changePrice
}
}
}
</script>
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
- 55.
- 56.
- 57.
- 58.
- 59.
- 60.
- 61.
- 62.
- 63.
customRef
自定义ref
,可以对ref
包装的数据改动,显示的进行跟踪和触发更新。
写一个效果,写一个input和一个h3,在input里输入内容后,h3的内容等待1秒后展示。
<template>
<input type="text" v-model="keyword">
<h3>{{ keyword }}</h3>
</template>
<script>
import {customRef} from 'vue'
export default {
name: 'App',
setup() {
// 自定义一个myRef
function myRef(value, delay) {
let timer;
// 通过customRef去实现自定义
return customRef((track, trigger) => {
return {
get() {
console.log(`通过get方法读取${value}`);
track();// 告诉Vue这个value值是需要被“追踪”的
return value;
},
set(newValue) {
clearTimeout(timer);
timer = setTimeout(() => {
value = newValue;
console.log(`通过set方法设置${newValue}`);
trigger();// 告诉Vue去更新界面
}, delay);
}
}
});
}
let keyword = myRef('hello', 1000);// 使用程序员自定义的ref
return {
keyword
}
}
}
</script>
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
provide
与inject
实现祖先和后代的组件间通信,祖先组件通过provide
将数据提供出去,后代组件通过inject
注入数据。
App.vue(祖先组件)
<template>
<div id="App">
<h1>我是祖先组件</h1>
<h2>{{ value }}</h2>
<button @click="value+=1">点我加1</button>
<Child></Child>
</div>
</template>
<script>
import Child from "./components/Child.vue";
import {provide, ref} from "vue";
export default {
name: 'App',
components: {Child},
setup() {
let value = ref(1);
provide('value', value);
return {
value
}
}
}
</script>
<style scoped>
#App {
background-color: red;
padding: 10px;
}
</style>
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
Child.vue(子组件)
<template>
<div id="Child">
<h1>我是子组件</h1>
<GrandChild></GrandChild>
</div>
</template>
<script>
import GrandChild from "./GrandChild.vue";
export default {
name: "Child",
components: {GrandChild}
}
</script>
<style scoped>
#Child {
background-color: green;
padding: 10px;
}
</style>
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
GrandChild.vue(孙组件)
<template>
<div id="GrandChild">
<h1>我是孙组件</h1>
<h1>{{ value }}</h1>
</div>
</template>
<script>
import {inject} from "vue";
export default {
name: "GrandChild",
setup() {
let value = inject("value");
return {
value
}
}
}
</script>
<style scoped>
#GrandChild {
background-color: yellow;
padding: 10px;
}
</style>
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
响应式数据的判断
isRef
:检查一个值是否是一个ref对象isReactive
:检查一个对象是否是由reactive
创建的响应式代理isReadonly
:检查一个对象是否是由readonly
创建的只读代理isProxy
:检查一个对象是否是由reactive
或readonly
方法创建的代理
<template>
<div>
</div>
</template>
<script>
import {isProxy, isReactive, isReadonly, isRef, reactive, readonly, ref} from "vue";
export default {
name: 'App',
setup() {
let car = reactive({name:"奔驰",price:100});
let sum = ref(0);
let car2 = readonly(car);
console.log(isRef(sum));
console.log(isReactive(car));
console.log(isReadonly(car2));
console.log(isProxy(car));
console.log(isProxy(sum));
}
}
</script>
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.