readonly
在Vue 3中,readonly
是一个用于创建只读响应式对象的函数。它可以应用于普通对象或响应式对象,将其转换为只读对象,这意味着不能对这个对象进行修改操作。
这个函数返回一个代理对象,该代理对象与原始对象具有相同的结构,但所有的属性都变成了只读的。这样一来,任何尝试修改代理对象的操作都会触发警告,并且不会真正地修改原始对象。
这是很有用的,它可以被传递给那些只需要读取数据而不需要修改的组件或函数。这样做有助于确保它们不会在意外的情况下修改数据。例如,如果你有一个组件只负责显示投票结果,而不会进行投票操作,你可以将只读版本的数据传递给该组件,以确保它只能读取数据而无法修改。
基本使用
请看下面的组件
import { reactive, readonly } from 'https://cdn.bootcdn.net/ajax/libs/vue/3.3.4/vue.esm-browser.js'
let template = `
<table>
<tr>
<td>姓名</td>
<td>票数</td>
</tr>
<tr v-for='(person, index) in readonly_votes_number' :key='index'>
<td>{{person.name}}</td>
<td v-on:click='person.votes++'>{{person.votes}}</td>
</tr>
</table>
`
export default {
setup: function () {
let votes_number = reactive({
optionA: {
name: 'Jon',
votes: 22,
},
optionB: {
name: 'Amy',
votes: 25,
},
})
let readonly_votes_number = readonly(votes_number)
return {readonly_votes_number}
},
template
}
我们有一个投票结果的数据votes_number,这个数据需要传递给模板展示,但这个数据是不应该还能被修改的,这时候我们就可以使用readonly包装一下votes_number,返回一个只读的版本,然后我们再把这个版本交给模板展示。可以看到我在模板加了一个点击事件尝试修改投票数,但结果是未能成功的
主要用途
- 如上所述,提供只读视图
- 提供警告和提示: 尽管只读对象不会阻止直接修改原始对象,但在试图修改只读对象时,Vue 会生成警告。这对于开发阶段发现潜在的问题非常有用。在开发期间,你会收到有关试图修改只读对象的提示,以便更早地识别潜在的错误。
shallowReadonly
readonly你可以看作是深只读,相应的就会有shallowReadonly浅只读。深只读有深层级的转换,浅只读没有,只有根层级的属性变为了只读。
import { reactive, shallowReadonly } from 'https://cdn.bootcdn.net/ajax/libs/vue/3.3.4/vue.esm-browser.js'
let template = `
<div v-on:click='copyObject.name="张三"'>{{copyObject.name}}</div>
<div v-on:click='copyObject.info.age++'>{{copyObject.info.age}}</div>
`
export default {
setup: function () {
let originalObject = reactive({
name: 'John',
info: {
age: 25
}
})
let copyObject = shallowReadonly(originalObject)
return { copyObject }
},
template,
}
我们的originalObject有两个层级,由于使用shallowReadonly根层级的属性变为了只读,所以修改name是不能成功的,但是修改age是没有问题的。
为什么可能需要 shallowReadonly:
-
灵活性: 有时候,你可能希望在确保顶层不可变的同时允许修改嵌套对象的属性。这在某些场景下可能是有用的,比如在某个特定层级以下的数据是可变的情况下。
-
性能优化: 如果你知道只有顶层属性会被修改,使用 shallowReadonly 可能比使用 readonly 更高效,因为它不会递归冻结整个对象。
isReadonly
isReadonly
是 Vue 3 提供的一个函数,用于检查一个对象是否是只读的。它返回一个布尔值,指示给定的对象是否是通过 readonly
或 shallowReadonly
创建的只读对象。
下面是一个简单的例子:
import { reactive, readonly, isReadonly } from 'vue';
const originalObject = reactive({
name: 'John',
age: 25,
});
const readOnlyObject = readonly(originalObject);
console.log(isReadonly(originalObject)); // 输出 false
console.log(isReadonly(readOnlyObject)); // 输出 true
在上述例子中,originalObject
是一个普通的响应式对象,而 readOnlyObject
是通过 readonly
创建的只读对象。通过调用 isReadonly
函数,你可以检查一个对象是否是只读的。
isReadonly
对于在运行时检查对象的状态非常有用,特别是在开发和调试阶段。它可以帮助你确保你的代码中正确地使用了只读对象,并避免了对只读对象的意外修改。