vue实现todolist

/*============================   css  ============================*/
#app .input-type{margin:10px 0;width:600px}
#app button,#app input{padding:0;outline:0;border:1px solid #ccc;box-shadow:none;font-size:14px;line-height:35px}
#app input{width:480px;text-indent:1em}
#app input:focus{border:1px solid #4791ff}
#app button{width:115px;border:1px solid #ccc;background-color:#fff;cursor:pointer;transition:all .2s}
#app button:hover{border:1px solid #4791ff;background-color:#4791ff;color:#fff}
#app button:disabled{background-color: #666;color: #ccc;border:none;}
#app table{width:600px;text-align:center;line-height:30px;margin-top: 20px;}
#app table,#app table tr td{border:1px solid #ccc}
#app table tr span{cursor:pointer}
#app table thead th{font-weight:400;font-size:16px}
[v-cloak]{display: none;}


/*============================   html ============================*/
<div id="app">
    <!-- 添加输入框 -->
    <div class="input-type">
        <input type="text" v-focus v-model="inputValue"  placeholder="请输入内容" @keyup.enter="addcont">
        <button @click="addcont" :disabled="inputValue.length===0">提交</button>
    </div>
    <!-- 搜索输入框 -->
    <div>
        <input type="text" placeholder="请输入商品名称查询!" v-model="searchVal">
    </div>
    <!-- 内容列表 -->
    <table border="1" cellspacing="0" cellpadding="0">
        <thead>
            <tr>
                <th width="10%">序号</th>
                <th width="40%">内容</th>
                <th width="40%">时间</th>
                <th width="10%">操作</th>
            </tr>
        </thead>
        <tbody>
            <tr v-for="(item,index) in newList" :key="index">
                <td>{{ index + 1 }}</td>
                <td>{{ item.cont }}</td>
                <td>{{ item.date | Datefil}}</td>
                <td @click="deleteBtn(index)"><span>删除</span></td>
            </tr>
            <tr v-if="newList.length == 0">
                <td colspan="4">Sorry,暂时没有清单</td>
            </tr>
        </tbody>
    </table>
</div>

/*============================ javascript ============================*/
<script>
    var myList = [
        {
            cont : 'HELLO WORLD',
            date : new Date()
        },
        {
            cont : 'HELLO CSS',
            date : new Date()
        },
        {
            cont : 'HELLO HTML',
            date : new Date()
        },
        {
            cont : 'HELLO JAVASCRIPT',
            date : new Date()
        },
    ]

    new Vue({
        el : '#app',
        data : {
            inputValue : '',
            lists : myList,
            searchVal : ""
        },
        // 自定义局部指令
        directives: {
            focus: {
                inserted: function (el) {
                    el.focus();
                }
            }
        },
        // 定义局部过滤器
        filters : {
            // 原生实现,Vue推荐采用moment.js中的format('时间格式')
            'Datefil' : (val)=>{
                var value = new Date(val);
                var year = value.getFullYear();
                var month = value.getMonth()+1;
                var day = value.getDate();
                var hour = value.getHours();
                var minutes = value.getMinutes();
                var seconds = value.getSeconds();
                return year + '年-' + month + '月-' + day + '日 ' + hour + ':' + minutes + ':' + seconds;
            }
        },
        // 页面加载前获取本地缓存数据
        created() {
            // 遍历本地数据是否存在
            var localStr = JSON.parse(localStorage.getItem('key')); 
            if ( localStr == null || localStr == '' ) {
                return;
            } else {
                this.lists = localStr;
            }
        },
        // 计算复杂的逻辑
        computed: { 
            newList : function () {
                // 判断this.lists中的cont是否包含searchVal
                var arr = this.lists.filter((v)=>{
                    return v.cont.includes(this.searchVal);
                })
                return arr;
            }
        },
        methods: {
            // 添加数据按钮
            addcont : function (){
                this.lists.unshift({
                    date : new Date(),
                    cont : this.inputValue
                });
                this.inputValue = '';
                localStorage.setItem("key",JSON.stringify(this.lists));
            },
            // 删除数据按钮
            deleteBtn : function (i){ 
                // 确认是否删除·
                if(confirm('删除不可恢复,是否继续删除数据?')){
                    this.lists.splice(i,1);
                    localStorage.setItem('key',JSON.stringify(this.lists));
                }
            }
        }
    })
</script>

 

===================== 2018年03月15日 更新(本地数据测试 db.json) =======================
准备工作:
1.) axios.js (npm 或者 cdn)
2.) moment.js (npm 或者 cdn)
3.) 更新页面渲染结构,lists

<tbody>
    <tr v-for="(item,index) in lists" :key="index">
        <td>{{ item.id }}</td>
        <td>{{ item.cont }}</td>
        <td>{{ item.date | Datefil }}</td>
        <td @click="deleteBtn(item.id)"><span>删除</span></td>
    </tr>
    <tr v-if="lists.length == 0">
        <td colspan="4">Sorry,暂时没有清单</td>
    </tr>
</tbody>

4.) 采用(Json-Server)数据测试,将Dom操作通过Ajax/Axios获取

<script>
    new Vue({
        el : '#app',
        data : {
            inputValue : '',
            lists : [],
            searchVal : ""
        },
        //页面加载完获取数据
        mounted() {
            this.getData();
        },
        //自定义局部指令
        directives: {
            focus: {
                inserted: function (el) {
                    el.focus();
                }
            }
        },
        filters : {
            Datefil : function (v){
                return moment(v).format('YYYY-MM-SS HH:mm:ss');
            }
        },
        methods: {
            //获取数据接口
            getData : function (){
                axios.get('http://localhost:3000/brands')
                .then( res =>{
                    var {status,data} = res;
                    if (status === 200) {
                        this.lists = data;
                    }
                })
            },
            //添加数据按钮
            addcont : function (){
                axios.post('http://localhost:3000/brands',{
                    cont : this.inputValue,
                    date : new Date()
                }).then( res => {
                    var {status,data} = res;
                    if (status === 201) {
                        this.getData();
                    }
                })
            },
            //删除数据按钮
            deleteBtn : function (i){
                if(confirm('删除不可恢复,是否继续删除数据?')){
                    axios.delete('http://localhost:3000/brands/'+i).then(res => {
                        var {status, data } = res;
                        if (status === 200) {
                            this.getData();
                        }
                    })
                }
            }
        },
        //监听搜索结果返回lists
        watch: {
            searchVal : function (newVal, oldVal){
                axios.get('http://localhost:3000/brands?cont_like=' + newVal)
                .then((res)=>{
                    var {status,data} = res;
                    if (status === 200) {
                        this.lists = data;
                    }
                })
            }
        }
    })
</script>