Vue2开发待办应用时如何合并API与用户输入数组并存储到localStorage
问题梳理
- 生命周期执行逻辑错误:created生命周期优先级高于mounted,当前代码中created请求接口后直接覆盖items,mounted又读取本地存储覆盖items,导致接口数据或本地存储数据被意外覆盖,逻辑优先级颠倒,应该优先读取本地存储,本地无数据时再请求接口初始化。
- created中合并逻辑完全无效:
items.concat(items)既没有指向实例的this.items,同时concat是返回新数组的非变更方法,不会修改原数组,且逻辑上是要合并接口返回数据与已有数据,而非数组自身合并。 - localStorage保存失败:
saveItems方法中拼写错误,this.item应为this.items,导致存入的是undefined,读取时自然无效。 - 计算属性存在副作用风险:
activeItems中未调用this.saveItems()(缺括号),且计算属性不适合执行存储类副作用操作,容易触发无限更新。 - 数组变更方法误用:
filteredItems中直接调用this.items.reverse(),reverse会修改原数组,导致items顺序被意外篡改,应先拷贝数组再执行反转。 - 接口数据无合并逻辑:接口请求成功后直接赋值
this.items = response.data,完全覆盖已有本地用户数据,没有执行合并操作。
修复后代码
var app = new Vue({ el: '#app', data () { return { items: [], title: '', show: 'all', } }, // 统一逻辑放到created处理,避免生命周期顺序冲突 created: async function () { // 优先读取本地存储 if(localStorage.getItem('items')) { try { this.items = JSON.parse(localStorage.getItem('items')); } catch(e) { localStorage.removeItem('items'); this.items = []; } } // 本地无数据时才请求接口初始化,避免覆盖用户已新增的内容 if(this.items.length === 0) { try { const response = await axios.get("https://jsonplaceholder.typicode.com/todos") // 只取前10条示例数据,避免接口返回太多内容 this.items = response.data.slice(0, 10) this.saveItems() } catch (e) { console.error('接口请求失败', e) } } }, computed: { activeItems() { return this.items.filter(item => !item.completed); }, filteredItems() { if (this.show === 'active') return this.items.filter(item => !item.completed); if (this.show === 'completed') return this.items.filter(item => item.completed); // 拷贝数组后再反转,避免修改原数组 return [...this.items].reverse(); }, }, methods: { addItem() { if(!this.title.trim()) return this.items.push({ title: this.title, completed: false }); this.title = ''; this.saveItems(); }, deleteItem(item) { var index = this.items.indexOf(item); if (index > -1) this.items.splice(index, 1); this.saveItems(); }, saveItems() { // 修正拼写错误 this.item -> this.items const parsed = JSON.stringify(this.items); localStorage.setItem('items', parsed); }, showActive() { this.show = 'active'; }, showAll() { this.show = 'all'; }, showCompleted() { this.show = 'completed'; }, deleteCompleted() { this.items = this.items.filter(item => !item.completed); this.saveItems(); }, } });
内容的提问来源于stack exchange,提问作者Kale
相关产品推荐
相关产品推荐

