todo 小案例

1. todo 小案例完成
需求分析
使用 vuejs 完成一个todo小项目,todo应用主要是用于记录用户要做的事情。
参考原型
http://todomvc.com/examples/vue/

实现的功能
1. todo 展示
2. todo 删除
3. 筛选

代码实操源码:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <!--1. 引入 bootstrap-->
    <link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.css" rel="stylesheet">
    <script src="https://cdn.bootcss.com/jquery/2.0.1/jquery.js"></script>
    <script src="https://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.js"></script>
    <style type="text/css">
        /*<!--代表已经完成的项目-->*/
        .del {
            text-decoration: line-through;
            color: #ccc;
        }
    </style>

</head>
<body>
<!--2. 导航-->
<nav class="navbar navbar-inverse">
    <div class="container-fluid">
        <div class="navbar-header">
            <a class="navbar-brand" href="#">
                Vuejs_TODO
            </a>
        </div>
    </div>
</nav>

<!--pannel-->
<div class="container" id="app">
    <div class="row">
        <div class="col-md-8 col-md-offset-2">
            <div class="panel panel-success">

                <div class="panel-heading">
                    <h3 class="text-danger">-_-, 还有 {{ unDoDataTotal }} 件事未完成</h3>
                    <!--确保用户按下回车的时候,进行存储 监控回车按键-->
                    <!--按键修饰符: 13这个是回车键的键码,代表用户按下了回车键-->
                    <!--收集数据时候也可以使用修饰符-->
                    <input type="text" v-model.trim="title" @change.13="changeHandler" class="form-control">
                </div>

                <div class="panel-body">

                    <ul class="list-group">

                        <!--注意:在写模型变量的时候,单词的大小写,还有顺序不要写错-->
                        <!--能复制不要手写-->
                        <!--todos  toods  tods-->
                        <!--展示筛选后的数据-->
                        <li class="list-group-item" :class="{del: todo.isCompleted}" v-for="todo in newTodos">
                            <input type="checkbox" v-model="todo.isCompleted"> {{ todo.title }}
                            <button type="button" class="btn btn-danger btn-xs pull-right"
                                    @click="removeItemHandler(todo)">&times;
                            </button>
                        </li>

                    </ul>

                </div>
                <div class="panel-footer">
                    <!--要实现筛选功能:前台是要监控得到用户点击的是哪个筛选条件:可以使用到 window.onhashchange 这个事件, 当页面的锚点发生变化的时候,触发-->
                    <ul class="nav nav-pills">
                        <li :class="{active: hash =='#/all'}"><a href="#/all">全部</a></li>
                        <li :class="{active: hash =='#/finish'}"><a href="#/finish">已完成</a></li>
                        <li :class="{active: hash =='#/unfinish'}"><a href="#/unfinish">未完成</a></li>
                </div>
            </div>
        </div>
    </div>
</div>
</body>
<script src="./js/uuid.js"></script>

<script src="https://cdn.bootcss.com/vue/2.6.10/vue.js"></script>
<script type="text/javascript">
    var vm = new Vue({
        el: '#app',
        data: {
            hash: '#/all', // 默认全部选中
            title: '',
            todoskey: 'keys',

            todos: [
                {
                    id: 1,
                    title: '睡觉',
                    isCompleted: false,
                },
                {
                    id: 2,
                    title: '吃饭',
                    isCompleted: true,
                },
                {
                    id: 3,
                    title: '打豆豆',
                    isCompleted: false,
                },
            ],
            //  在 使用 watch 的时候,存在一个监视的层级问题:默认是浅检测,只会监视模型变量的第一层的变化 开启深度检测
            newTodos: [],

        },
        // 页面一加载,函数自动触发
        created: function () {

            var key = 'todosKey';

            this.todos = localStorage.getItem(key) ? JSON.parse( localStorage.getItem(key) ): [];

            window.addEventListener('hashchange', () => {
                console.log(location.hash);
                this.hash = location.hash;
            }, false);

        },
        methods: {
            generaterId: function () {
                var uuid = uuidv1();
                return uuid.replace(/-/g, '');

            },
            changeHandler: function () {

                if (this.title.length <= 0) {
                    alert('请填写待做事情!');
                    return;
                }

                this.todos.push({
                    id: this.generaterId(),
                    title: this.title,
                    isCompleted: false,
                });

                this.title = '';// 清空
            },
            removeItemHandler: function (todo) {
                this.todos = this.todos.filter((item) => {
                    return item !== todo;
                    // 当前如果不等于传过来的待删除的条目,则保留
                });

            }
        },
        // 展示待做项
        computed: {
            unDoDataTotal: function () {
                // 返回还没有完成的事情 isCompleted: false
                return this.newTodos.filter((item) => {
                    return !item.isCompleted;
                }).length;
            },


        },
        watch: {
            hash: function (newVal, oldVal) {
                if (newVal === '#/finish') {
                    this.newTodos = this.todos.filter((item) => {
                        return item.isCompleted;
                    })

                } else if (newVal === '#/unfinish') {

                    this.newTodos = this.todos.filter((item) => {
                        return !item.isCompleted;
                    })
                } else {
                    // 代表默认的操作,全部的数据
                    this.newTodos = this.todos;
                }

            },
            todos: {
                handler: function () {
                    var key = 'todosKey';
                    console.log('this', this);
                    // 自己定义的模型变量不能使用下划线(vuejs默认会认为是私有属性)
                    // vuejs 里面特性 set get
                    console.log('this.todoskey', this.todoskey);
                    localStorage.setItem(key, JSON.stringify(  this.todos  ));
                    this.newTodos = this.todos;
                },
                deep: true,
            },
        }
    })
</script>
</html>

js代码如下:

!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).uuidv1=e()}}(function(){return function(){return function e(n,r,o){function t(u,f){if(!r[u]){if(!n[u]){var c="function"==typeof require&&require;if(!f&&c)return c(u,!0);if(i)return i(u,!0);var s=new Error("Cannot find module '"+u+"'");throw s.code="MODULE_NOT_FOUND",s}var a=r[u]={exports:{}};n[u][0].call(a.exports,function(e){return t(n[u][1][e]||e)},a,a.exports,e,n,r,o)}return r[u].exports}for(var i="function"==typeof require&&require,u=0;u<o.length;u++)t(o[u]);return t}}()({1:[function(e,n,r){for(var o=[],t=0;t<256;++t)o[t]=(t+256).toString(16).substr(1);n.exports=function(e,n){var r=n||0,t=o;return[t[e[r++]],t[e[r++]],t[e[r++]],t[e[r++]],"-",t[e[r++]],t[e[r++]],"-",t[e[r++]],t[e[r++]],"-",t[e[r++]],t[e[r++]],"-",t[e[r++]],t[e[r++]],t[e[r++]],t[e[r++]],t[e[r++]],t[e[r++]]].join("")}},{}],2:[function(e,n,r){var o="undefined"!=typeof crypto&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto)||"undefined"!=typeof msCrypto&&"function"==typeof window.msCrypto.getRandomValues&&msCrypto.getRandomValues.bind(msCrypto);if(o){var t=new Uint8Array(16);n.exports=function(){return o(t),t}}else{var i=new Array(16);n.exports=function(){for(var e,n=0;n<16;n++)0==(3&n)&&(e=4294967296*Math.random()),i[n]=e>>>((3&n)<<3)&255;return i}}},{}],3:[function(e,n,r){var o,t,i=e("./lib/rng"),u=e("./lib/bytesToUuid"),f=0,c=0;n.exports=function(e,n,r){var s=n&&r||0,a=n||[],d=(e=e||{}).node||o,l=void 0!==e.clockseq?e.clockseq:t;if(null==d||null==l){var p=i();null==d&&(d=o=[1|p[0],p[1],p[2],p[3],p[4],p[5]]),null==l&&(l=t=16383&(p[6]<<8|p[7]))}var v=void 0!==e.msecs?e.msecs:(new Date).getTime(),y=void 0!==e.nsecs?e.nsecs:c+1,m=v-f+(y-c)/1e4;if(m<0&&void 0===e.clockseq&&(l=l+1&16383),(m<0||v>f)&&void 0===e.nsecs&&(y=0),y>=1e4)throw new Error("uuid.v1(): Can't create more than 10M uuids/sec");f=v,c=y,t=l;var w=(1e4*(268435455&(v+=122192928e5))+y)%4294967296;a[s++]=w>>>24&255,a[s++]=w>>>16&255,a[s++]=w>>>8&255,a[s++]=255&w;var b=v/4294967296*1e4&268435455;a[s++]=b>>>8&255,a[s++]=255&b,a[s++]=b>>>24&15|16,a[s++]=b>>>16&255,a[s++]=l>>>8|128,a[s++]=255&l;for(var x=0;x<6;++x)a[s+x]=d[x];return n||u(a)}},{"./lib/bytesToUuid":1,"./lib/rng":2}]},{},[3])(3)});

注意:文件的路径哦,各位小可爱

效果截图如下:

   相关博客:https://blog.csdn.net/Solitarily/article/details/85333159

 
原文地址:https://www.cnblogs.com/fang-1207/p/lifangfang-todo.html