优化Vue版本的todoList-加localStorage

之前有说要添加的功能。这次写出来了。
在线demo https://xzchen.github.io/project/vue/todolist/。
先说同第一版本的差别。

  1. 加入了localStorage将数据存储在客户端。
  2. 把比较复杂模板提出来,单独写入js部分。不然模板过重。
  3. 增添了几个新的指令。

鉴于之前已经大体说过逻辑部分,也就不再次讲了。
localStorage => HTML5中新添数据,没有时间限制的数据存储
此demo中用到的方法
localStorage.setItem(‘item’, ‘value’) => 设置一个条目item的值为value;
localStorage.getItem(‘item’) => 或者条目为item的值
localStorage.hasOwnProperty(‘item’) => 判断localStorage中是否存在item这个条目。
鉴于localStorage只支持string类型的存储,
优化Vue版本的todoList-加localStorage_第1张图片


通过JSON.parse()从localStorage.getItem(‘todoList’)里解析出对象赋值给todoList,然后在vue里代理todoList。
虽然也可以使用“.”和“[]”去读写localStorage的数组,但是推荐使用推荐使用getItem和setItem去读写数据。(此处大多从stackoverflow得到答案)
一:有语义,增强可读性。
二:避免冲突,可能覆盖掉(重写)改对象上的已经存在成员(譬如通过localStorage.getItem = ‘test’ 那么它原有的getItem方法就会被覆盖掉。)推荐看下面这个链接的问题。
http://stackoverflow.com/questions/12632463/is-localstorage-getitemitem-better-than-localstorage-item-or-localstoragei
另外,不同Array.length; localStorage.length是只读的。所以也有↓↓↓()
优化Vue版本的todoList-加localStorage_第2张图片


其余基本没太改变。放代码了。看注释吧。
HTML部分

<header>
    <h2>
    ToDoList
    <input type="text" placeholder="增加要完成的todo,回车键入" v-model.trim="newTodoText" @keyup.enter="createNewTodo"> 
    
    h2>
header>
<div>
    <p v-if="!doingLength">没有正在进行的任务p>
    
    <p v-else>正在进行 <span>{{doingLength}}span>p> 
    <ul>
        <li v-for="todo,index in todoList" v-if="!todo.flag">
            <input type="checkbox" @click="todo.flag = !todo.flag">
            <p @click="showEdit(todo)">
                {{todo.text}}
                <input 
                    type="text" 
                    v-show="todo === edit" 
                    v-model:value="todo.text"
                    v-focus="todo === edit"
                    @blur="changeValue(todo)"
                    @keyup.enter="changeValue(todo)"
                    @keyup.esc="todo.text =oldText;edit = ''">
            p>
            <span @click="todoList.splice(index,1)">span>
        li>
    ul>
div>

JS部分

//全局注册了focus指令。 el:指令所绑定的元素,可以用来操作DOM
//binding一个对象,其中value属性就指令绑定的值 expression运算后的值
Vue.directive('focus', {
    update(el, binding) {
        if (binding.value) {
            el.focus()
        }
    }
})
//如果用户的localStorage里面不存在todoList项。我们就预设一个。
if (!localStorage.hasOwnProperty('todoList')) {
    localStorage.setItem('todoList', '[{"text":"这里写你未完成的任务","flag":false},{"text":"支持修改,删除操作","flag":true}]')
}

var todoList = JSON.parse(localStorage.getItem('todoList'))  //从字符串中解析出JSON对象
new Vue({
    el: '#app',
    data: {
        newTodoText: '', 
        todoList: todoList,
        edit: '',
        oldText: '',
    },
    methods: {
        createNewTodo() {
            if (this.newTodoText) {
                this.todoList.push({text: this.newTodoText, flag: false})
                this.newTodoText = '';
            }
            else {
                alert('不能输入空项目');
                return;
            }
        },
        showEdit(todo) {
            this.edit = todo;   //edit引用todo,这样todo改变edit也会改变
            this.oldText = todo.text; //showEidt里记录下原有的值,当用户不想修改的时候按住esc可以直接返回oldText的值
        },
        changeValue(todo) {
            if (!todo.text) {
                alert("项目不能为空")
                todo.text = this.oldText;  //changeValue的时候只修改值而不改变flag状态,所以就直接改text就好(v-model指令是双向绑定。这是为空的情况)。
            }
            this.edit = '';   //对象的引用,一个对象置空后不影响另一对象。
        }
    },
    watch: {
        todoList: {
            handler() {
                localStorage.setItem('todoList', JSON.stringify(this.todoList))
            },
            deep: true  //保证监听数组内部值的变化
        }
    },
    computed: {
        doingLength() {
            return this.todoList.filter(item => item.flag === false).length; //计算属性。根据todo.flag过滤
        },
        doneLength() {
            return this.todoList.filter(item => item.flag === true).length;
        }
    }
})

是不是要放源码。。。
https://github.com/xzchen/project/tree/gh-pages/vue/todolist

你可能感兴趣的:(Vue.js,vue-js,数据存储)