vue.js - 使用 vue getter/setter 指向 localStorage 时的奇怪行为
问题描述
我从这段代码中得到了奇怪的行为。我想使用 getter 和 setter 指向本地存储。
第一次呈现应用程序时,会正确检索项目。之后,当向列表中添加新项目时,它不会被渲染。此外,当添加一个项目时,它只会在添加第一个项目后交换前一个项目的索引处的值。
<input type="text" v-model="term" @keyup.enter="submit()" />
<ul>
<li v-for="(item, i) in history" :key="i">{{item}}</li>
</ul>
const app = new Vue({
el: '#app',
data: {
term: '',
},
computed: {
history: {
get() {
return JSON.parse(localStorage.getItem('history')) || [];
},
set(value) {
localStorage.setItem('history', JSON.stringify(value));
},
},
},
methods: {
submit() {
this.history = [...this.history, this.term];
this.term = '';
},
},
});
您可以在此处查看代码,因为 SO 不允许访问 localStorage。请记住在添加第一项后刷新页面,并调查 localStorage 内部发生的情况。
https://codepen.io/bluebrown/pen/dyMMRKj?editors=1010
这段代码是一些 alpinejs 项目的移植。它在那里奏效了。
也就是说,当我像下面这样写它时,我可以让它工作。但是,我现在很好奇,为什么上面的例子会这样。
const app = new Vue({
el: '#app',
data: {
term: '',
history: [],
},
created() {
this.history = JSON.parse(localStorage.getItem('history')) || [];
},
watch: {
history: {
deep: true,
handler(value) {
localStorage.setItem('history', JSON.stringify(value));
},
},
},
methods: {
submit() {
this.history = [...this.history, this.term];
this.term = '';
},
},
});
解决方案
之所以不起作用,是因为 Vue 只能观察普通对象。localStorage
Vue 无法观察到诸如此类的原生对象。如果您将某些内容放入本地存储中,Vue 不会知道它,并且您的视图不会自动更新以显示这些更改。
Vue 在该对象的文档中提到了这个限制data
:
Vue 实例的数据对象。Vue 会递归地将其属性转换为 getter/setter 以使其“反应”。对象必须是普通的:浏览器 API 对象和原型属性等原生对象将被忽略。一个经验法则是数据应该只是数据——不建议观察具有自己状态行为的对象。
这些限制适用于 Vue 的整个反应系统,包括computed
属性。
推荐阅读
- c# - 如何将 ObservableCollection 的字典绑定到 DataGrid?
- reactjs - 当我在 macOS 上按 command + S 时,我的 HTML 代码因 VSCode 问题而改变
- swiftui - 我们在 SwiftUI 中有填充 defaultValue 吗?
- webpack - 处理 babel 配置和插件
- oracle - AWS DMS oracle 完全加载失败
- typescript - 打字稿用联合推断通用参数类型
- websocket - Janus 无效会话 (null)
- javascript - 如何在php中获取ajax post请求数据
- java - 我需要将表单数据输入数据库,但显示语法错误
- javascript - 您可能需要一个合适的加载器来处理这个文件类型,目前没有加载器被配置来处理这个文件,当导入 html 文件时