Vue第二部分

品牌列表案例

运用的知识:

v-model进行双向绑定

@click.prevent="del(id)" 函数传参

v-for循环

String.prototype.includes('要包含的字符串')

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>cysky</title>
    <link rel="stylesheet" href="../lib/bootstrap-3.3.7.css">
    <script src="../lib/vue-2.4.0.js"></script>
</head>
<body>
<div id="app">
    <div class="panel panel-primary">
        <div class="panel-heading">
            <h3>添加品牌</h3>
        </div>
        <div class="panel-body form-inline">
            <label for="">
                ID:
                <input type="text" class="form-control" v-model="id">
            </label>
            <label for="">
                Name:
                <input type="text" class="form-control" v-model="name">
            </label>
            <label for="">
                <input type="button" value="添加" class="btn btn-primary" @click="add">
            </label>
            <label for="">
                搜索名称关键字:
                <input type="text" class="form-control" v-model="keywords">
            </label>
        </div>
    </div>

    <table class="table table-bordered table-striped table-hover">
        <thead>
        <tr>
            <th>ID</th>
            <th>Name</th>
            <th>Ctime</th>
            <th>Del</th>
        </tr>
        </thead>
        <tbody>
        <tr v-for="item in search(keywords)">
            <td>{{ item.id }}</td>
            <td>{{ item.name }}</td>
            <td>{{ item.ctime }}</td>
            <td><a href="" @click.prevent="del(id)">删除</a></td>
        </tr>
        </tbody>
    </table>
</div>

<script>
    var vm = new Vue({
        el: '#app',
        data: {
            id: '',
            name: '',
            keywords: '',
            list: [
                {id: 1, name: '奔驰', ctime: new Date()},
                {id: 2, name: '宝马', ctime: new Date()},
            ]

        },
        methods: {
            add() {
                var car = {id: this.id, name: this.name, ctime: new Date()};
                this.list.push(car);
                this.id = '';
                this.name = ''
            },
            del(id) {
                var index = this.list.indexOf(function (item) {
                    if (item.id === id) {
                        return true
                    }
                });
                this.list.splice(index, 1)
            },
            search(keywords) {
                return this.list.filter(function (item) {
                    if (item.name.includes(keywords)) {
                        return item
                    }
                })
            }
        }
    })
</script>
</body>
</html>

<tr v-for="item in search(keywords)">

之前,v-for 中的数据,都是直接从 data 上的 list 中直接渲染过来的,现在,这里定义了一个 search 方法 在 search 方法内部,通过执行 for 循环,把所有符合搜索的关键字的数据,保存到一个新数组中返回。

全局过滤器

定义私有过滤器 过滤器有两个 条件 【过滤器名称 和 处理函数】

所谓的全局过滤器,就是所有的VM实例都共享的

Vue.filter('dataFormat',function(dataStr,pattern = ''){
        var dt = new Date(dataStr);
        var y = dt.getFullYear();
        var m = dt.getMonth()+1;
        var d = dt.getDate().toString().padStart(2,'0');
        var h = dt.getHours().toString().padStart(2,'0');
        var mm = dt.getMinutes().toString().padStart(2,'0');
        var s = dt.getSeconds().toString().padStart(2,'0');
        return `${y}-${m}-${d} ${h}:${mm}:${s}`
    });

使用: <td>{{ item.ctime | dateFormat() }}</td>

私有过滤器

过滤器调用的时候,采用就近原则,如果私有过滤器和全局过滤器名称一致,这时候优先调用私有过滤器

filters:{
            timeFormat: function (dateStr, pattern='') {
                var dt = new Date(dateStr);
                var y = dt.getFullYear();
                var m = dt.getMonth() + 1;
                var d = dt.getDate();
                var h = dt.getHours().toString().padStart(2,'0');
                var mm = dt.getMinutes().toString().padStart(2,'0');
                var s = dt.getSeconds().toString().padStart(2,'0');
                return `${y}-${m}-${d} ${h}:${mm}:${s}`
            }
        }

自定义全局按键修饰符

全部的按键别名:

  • .enter
  • .tab
  • .delete (捕获“删除”和“退格”键)
  • .esc
  • .space
  • .up
  • .down
  • .left
  • .right

以上可以直接使用:@click.enter = 'add'

Vue.config.keyCodes.f2 = 113

使用:@click.f2='add'

使用Vue.directive()定义全局的指令

 Vue.directive('focus',{
        inserted:function(el){
            el.focus()
        }
    });

使用:<input type="text" class="form-control" v-model="keywords" id="search" v-focus v-color="'green'">

inserted 表示元素 插入到DOM中的时候,会执行 inserted 函数【触发1次】

和样式相关的操作,一般都可以在 bind 执行

    Vue.directive('color',{
        bind:function(el,binding){
            el.style.color = 'red';
            console.log(binding.value)
        }
    });

使用:<input type="text" class="form-control" v-model="keywords" id="search" v-focus v-color="'green'">

每当指令绑定到元素上的时候,会立即执行这个 bind 函数,只执行一次

函数中的第一个参数永远是 el ,表示被绑定了指令的那个元素, 这个 el 参数, 是一个原生的 JS 对象

和 JS 行为有关的操作,最好在 inserted 中去执行

参数1:指令的名称,注意,在定义的时候,指令名称前不需要加 v- 前缀,但是,在调用的时候,必须在指令名称前加上 v- 前缀来进行调用

参数2:是一个对象,这个对象身上,有一些指令相关的函数,这些函数可以在特定阶段,执行相关的操作

自定义私有指令

 directives: {
            'fontweight': {
                bind: function (el, binding) {
                    el.style.fontWeight = binding.value
                }
            },
            'fontsize': {
                bind: function (el, binding) {
                    el.style.fontSize = binding.value
                }
            }
        }

品牌列表完整案例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>cysky</title>
    <link rel="stylesheet" href="../lib/bootstrap-3.3.7.css">
    <script src="../lib/vue-2.4.0.js"></script>
</head>
<body>
<div id="app">
    <div class="panel panel-primary">
        <div class="panel-heading">
            <h3>添加品牌</h3>
        </div>
        <div class="panel-body form-inline">
            <label for="">
                ID:
                <input type="text" class="form-control" v-model="id">
            </label>
            <label for="">
                Name:
                <input type="text" class="form-control" v-model="name">
            </label>
            <label for="">
                <input type="button" value="添加" class="btn btn-primary" @click="add">
            </label>
            <label for="">
                搜索名称关键字:
                <input type="text" class="form-control" v-model="keywords" v-focus>
            </label>
        </div>
    </div>

    <table class="table table-bordered table-striped table-hover">
        <thead>
        <tr>
            <th>ID</th>
            <th>Name</th>
            <th>Ctime</th>
            <th>Del</th>
        </tr>
        </thead>
        <tbody>
        <tr v-for="item in search(keywords)">
            <td>{{ item.id }}</td>
            <td>{{ item.name }}</td>
            <td>{{ item.ctime | timeFormat() }}</td>
            <td><a href="" @click.prevent="del(id)">删除</a></td>
        </tr>
        </tbody>
    </table>

    <p v-fontsize="50" v-color="'blue'">这是一个P标签,用于测试私有directives</p>
</div>

<script>
    var vm = new Vue({
        el: '#app',
        data: {
            id: '',
            name: '',
            keywords: '',
            list: [
                {id: 1, name: '奔驰', ctime: new Date()},
                {id: 2, name: '宝马', ctime: new Date()},
            ]

        },
        methods: {
            add() {
                var car = {id: this.id, name: this.name, ctime: new Date()};
                this.list.push(car);
                this.id = '';
                this.name = ''
            },
            del(id) {
                var index = this.list.indexOf(function (item) {
                    if (item.id === id) {
                        return true
                    }
                });
                this.list.splice(index, 1)
            },
            search(keywords) {
                return this.list.filter(function (item) {
                    if (item.name.includes(keywords)) {
                        return item
                    }
                })
            }

        },
        filters: {//私有过滤器
            timeFormat: function (dateStr, pattern = '') {
                var dt = new Date(dateStr);
                var y = dt.getFullYear();
                var m = dt.getMonth() + 1;
                var d = dt.getDate();
                var h = dt.getHours().toString().padStart(2, '0');
                var mm = dt.getMinutes().toString().padStart(2, '0');
                var s = dt.getSeconds().toString().padStart(2, '0');
                return `${y}-${m}-${d} ${h}:${mm}:${s}`
            }
        },
        directives: {//自定义私有指令
            'fontweight': {
                bind: function (el, binding) {
                    el.style.fontWeight = binding.value
                }
            },
            'fontsize': {
                bind: function (el, binding) {
                    el.style.fontSize = parseInt(binding.value) + 'px'
                }
            },
            'color': {
                bind: function (el, binding) {
                    el.style.color = binding.value
                }
            },
            'focus': {
                inserted: function (el) {
                    el.focus()
                }
            }
        }
    })
</script>
</body>
</html>

生命周期

lifecycle.png

beforeCreate(){}:这是我们遇到的第一个生命周期函数,表示实例完全被创建出来之前,会执行它

注意:beforeCreate(){} 执行的时候,data 和 methods 中的数据都还没有初始化

created(){} 这是遇到的第二个生命周期函数,在 created 中,data 和 methods 都已经被初始化好了

注意:如果要调用 methods 中的方法,或者操作 data 中的数据,最早,只能在 created 中操作

beforeMount(){} 这是遇到的第三个生命周期函数,表示模版已经在内存中编辑完成了,但是尚未把模版渲染到页面中

注意:在 beforeMount 执行的时候,页面中的元素,还没有被真正替换过来,只是之前写的模版字符串

mounted(){} 这是遇到的第四个盛名周期函数,表示,内存中的模版,已经真实的挂载到了页面中,用户已经可以看到渲染好的页面了

注意:mounted 是实例创建期间最后的一个生命周期函数,当执行完 mounted 就表示,实例已经被完全创建好了,此时,如果没有其他操作,这个实例就在内存中,等候

接下来的是运行中的两个事件

beforeUpdate() {} 这时候表示我们的界面还没有被更新(数据已经更新了)

结论: 当执行 beforeUpdate 的时候,页面中的显示的数据,还是旧的,此时 data 数据是最新的,页面尚未和 最新的数据保持同步

updated(){} 事件执行的时候,页面和 data 数据已经保持同步了,都是最新的

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,383评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,522评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,852评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,621评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,741评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,929评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,076评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,803评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,265评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,582评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,716评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,395评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,039评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,027评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,488评论 2 361
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,612评论 2 350

推荐阅读更多精彩内容

  • vue概述 在官方文档中,有一句话对Vue的定位说的很明确:Vue.js 的核心是一个允许采用简洁的模板语法来声明...
    li4065阅读 7,193评论 0 25
  • ## 框架和库的区别?> 框架(framework):一套完整的软件设计架构和**解决方案**。> > 库(lib...
    Rui_bdad阅读 2,895评论 1 4
  • 想起了《记承天寺夜游》,元丰六年十月十二日夜,解衣欲睡,月色入户,欣然起行。念无与为乐者,遂至承天寺,寻张怀民,...
    逃离者阅读 342评论 0 1
  • Peter同学乃滨海小外四年级小学生一枚,时有妙语引家人一乐,故记录之。 论好食堂的重要性 四年级开学在即,当老师...
    胡喜平阅读 747评论 0 3
  • 人有三次成长,我经历了两次,有些事情不是努力可以得到的…… 我今年18,摩羯座,马上大二,在这个暑假,我第一次觉得...
    我就是很普通阅读 381评论 0 1