readonly & shallowReadonlyreadonly(响应性数据)readonly 修饰的数据,不可被修改<template>
<p>obj.name: {{ obj.name }}p>
<button @click="obj.name += '!'">修改 obj.namebutton>
<hr />
<p>reObj.name: {{ reObj.name }}p>
<button @click="reObj.name += '!'">修改 reObj.namebutton>
template>
<script>
import { reactive, readonly } from "vue";
export default {
name: "App",
setup() {
let obj = reactive({ name: "superman" });
let reObj = readonly(obj);
return { obj, reObj };
},
};
script>
shallowReadonly
shallowReadonly(响应性数据)shallowReadonly 修饰的数据,浅层数据不可被修改,但深层数据可以被修改<template>
<p>obj.name: {{ obj.name }}p>
<button @click="obj.name += '!'">修改 obj.namebutton>
<p>reObj.name: {{ reObj.name }}p>
<button @click="reObj.name += '!'">修改 reObj.namebutton>
<hr />
<p>obj.girlfriend.name: {{ obj.girlfriend.name }}p>
<button @click="obj.girlfriend.name += '!'">
修改 obj.girlfriend.name
button>
<p>reObj.girlfriend.name: {{ reObj.girlfriend.name }}p>
<button @click="reObj.girlfriend.name += '!'">
修改 reObj.girlfriend.name
button>
template>
<script>
import { reactive, shallowReadonly } from "@vue/reactivity";
export default {
name: "App",
setup() {
let obj = reactive({
name: "superman",
girlfriend: { name: "superwoman" },
});
let reObj = shallowReadonly(obj);
return { obj, reObj };
},
};
script>
toRaw & markRawreactive 修饰的响应式数据变为普通数据:toRaw(响应式数据)<template>
<p>obj.name: {{ obj.name }}p>
<button @click="obj.name += '!'">修改 obj.namebutton>
<hr />
<p>raObj.name: {{ raObj.name }}p>
<button @click="raObj.name += '!'">修改 raObj.namebutton>
template>
<script>
import { reactive, toRaw } from "@vue/reactivity";
export default {
name: "App",
setup() {
let obj = reactive({ name: "superman" });
let raObj = toRaw(obj);
return { obj, raObj };
},
};
script>
可以发现,toRaw 修饰的数据,会变为普通数据,修改普通数据,页面不会重新渲染
但是数据是已经被改变了的,页面如果重新渲染的话,还是会显示最新数据
markRaw
<template>
<p>obj: {{ obj }}p>
<p>
第一步: 选择接收数据
<button @click="changeObj">changeObjbutton> |
<button @click="maChangeObj">maChangeObjbutton>
p>
<p>
第二步: 选择改变的数据
<button @click="changeName">changeNamebutton> |
<button @click="changeGirl">changeGirlbutton>
p>
template>
<script>
import { markRaw, reactive } from "vue";
export default {
name: "App",
setup() {
// 定义响应式数据
let obj = reactive({ name: "superman" });
// 假设通过 Ajax 接收一个对象数据
function changeObj() {
let girl = { name: "superwoman" };
obj.girlfriend = girl;
}
// 假设通过 Ajax 接收一个对象数据,并用 markRaw 修饰
function maChangeObj() {
let girl = markRaw({ name: "superwoman" });
obj.girlfriend = girl;
}
// 改变接收的数据
function changeGirl() { obj.girlfriend.name += "!" }
// 改变原数据
function changeName() { obj.name += "!" }
return {
obj,
changeObj,
changeGirl,
maChangeObj,
changeName,
};
},
};
script>
可以发现,正常接收的对象数据,是可以被修改并渲染到页面上的;
但是,用 markRaw 修饰的对象数据,数据会被修改,但不会被渲染到页面上(当然,页面重新渲染时,还是会显示最新数据)
provide & injectprovide 用于传递数据给后代组件:provide("XXX", 数据值)inject 用于接收祖先组件传递的数据:inject("XXX")
App: {{ obj }}
Son: {{ msg }}
此时,不论在哪个组件修改数据,数据都会被修改成功,并渲染到页面上
如果想后代组件无法修改并渲染数据,可以使用 toRaw 修饰数据:
此时,后代组件无法修改并渲染接收的数据,但是数据是已经被修改了的,页面重新渲染的话,还是会显示最新数据
App: {{ obj }}
如果不允许修改数据,可以使用 readonly 修饰数据:
此时,只有父级组件可以修改数据,后代组件不能修改接收的数据
App: {{ obj }}
isRef - 检查一个值是否由 ref 修饰isReactive - 检查一个对象是否由 reactive 修饰isReadonly - 检查一个对象是否由 readonly 修饰isProxy - 检查一个对象是否由 reactive / readonly 修饰<script>
import { isProxy, isReactive, isReadonly, isRef, reactive, readonly, ref } from 'vue';
export default {
name: "App",
setup() {
let person = reactive({ name: "superman" });
let num = ref(0);
let readonly_num = readonly(num);
console.log(isReactive(person)); // true
console.log(isRef(num)); // true
console.log(isReadonly(readonly_num)); // true
console.log(isProxy(readonly_num)); // true
},
};
script>