• 【Vue.js 2.0】指令


    一、内置指令

    1. v-bind 主要用于动态绑定DOM元素属性(attribute),即元素属性实际的值是由vm实例中的data属性提供的。例如:

    <img v-bind:src='imgPath' />
    <script>
        var app = new Vue({
            data:{
                imgPath: 'http://...'
            }
        })
    </script>

    2. v-model 主要对表单元素进行双向数据绑定,在修改表单元素值的同时,实例vm中对应的属性值也同时更新,反之亦然。输入框示例:

    <div id="app">
        <h1>输入内容为:{{message}}</h1>
        <input type="text" v-model="message" />
    </div>
    
    <script>
        var app = new Vue({
            el: '#app',
            data: {
                message: 'this is v-model example'
            }
        })
    </script>

    Vue.js 2.0中取消了lazy和number作为参数,用修饰符(modifier)来代替:

    <input type="text" v-model.lazy="message" />  <%-- 加lazy后会更改为在change事件中同步 --%>
    <input type="text" v-model.trim="message" /> <%-- 去掉输入值的首尾空格 --%>
    <input type="number" v-model.number="message" /> <%-- 自动将用户的输入值转为数值类型。即使input输入框的type=number类型,获取到的值也是string类型,如果加上.number获取到的值则为number类型 --%>

    3. v-if  v-else  v-show 主要用于根据条件展示对应的模板内容。需要注意的是,v-else必须紧跟v-if,不然该指令不起作用,例如:

    <div id="app">
        <div v-if="yes">yes</div>
        <p>the v-else div shows</p>
        <div v-else>no</div>
    </div>
    
    <script>
        var app = new Vue({
            el: '#app',
            data: {
                yes: false
            }
        })
    //显示:the v-else div shows
    </script>

    除了 v-if,v-show 也是可以根据条件展示元素的一种指令。与v-if 不同的是,v-show 元素的使用会渲染并保持在 DOM 中。v-show 只是切换元素的 css 属性 display。v-if 的切换消耗要比 v-show 高,但初始条件为 false 的情况下,v-if 的初始渲染要稍快。

    4. v-for 主要用于列表渲染,将根据接收到的数组重复渲染v-for绑定到的DOM元素及内部的子元素,并且可以通过设置别名的方式,获取数组内的数据并渲染到节点中。例如:

    <div id="app">
        <p>--------------------列表渲染--------------------</p>
        <ul>
            <%-- items为data中的属性名,item为别名,可以通过item来获取当前数组遍历的每个元素--%>
            <li v-for="item in items">
                <h3>{{item.title}}</h3>
                <p>{{item.description}}</p>
            </li>
        </ul>
        <p>--------------------列表渲染 + 索引--------------------</p>
        <ul>
            <%-- 也可以用 of 替代 in 作为分隔符,因为它更接近 JavaScript 迭代器的语法;index为当前数组元素的索引--%>
            <li v-for="(item, index) of items">
                <h3>{{index}}:{{item.title}}</h3>
                <p>{{item.description}}</p>
            </li>
        </ul>
        <p>--------------------列表渲染 + (key, value)形式--------------------</p>
        <ul>
            <li v-for="(value, key) of objectDemo">
                <h3>{{key}}</h3>
                <p>{{key}}:{{value}}</p>
            </li>
        </ul>
        <p>--------------------列表渲染 + template--------------------</p>
        <ul>
            <template v-for="item in items">
            <li>{{ item.title }}</li>
            <li>{{item.description}}</li>
          </template>
        </ul>
        <p>--------------------迭代1-10--------------------</p>
        <ul>
            <%--Vue.js 2.0之后n 由原来的 09 迭代变成 110 迭代--%>
            <li v-for="n in 10">{{ n }}
            </li>
        </ul>
        <p>--------------------v-bind:key--------------------</p>
       <%-- key的作用就是为了防止更新了数据的时候重新渲染整个列表,有key相当于做了一个缓存,只会去重新渲染更新了的数据--%>
        <div v-for="item in items" v-bind:key="item.id">
             <h3>{{item.title}}</h3>
        </div>
    </div>
    
    <script>
        var app = new Vue({
            el: '#app',
            data: {
                yes: true,
                items: [
                    { title: 'title-1', description: 'description-1' },
                { title: 'title-2', description: 'description-2' },
                { title: 'title-3', description: 'description-3' },
                { title: 'title-4', description: 'description-4' }
                ],
                objectDemo: {
                    a: 'a-value',
                    b: 'b-value',
                    c: 'c-value'
                }
            }
        })
    </script>
    View Code

    5. v-on 主要用于事件绑定

    <div id="app">
        <%-- 按钮1、按钮2等价,响应结果:弹框输出 Hello Vue.js --%>
        <button v-on:click="say">按钮1</button>
        <button @click="say">按钮2</button>
    
    
        <%-- v-on 也支持内联 JavaScript 语句,但仅限一个语句,响应结果:弹框输出 Hello Vue.js from param --%>
        <button v-on:click="sayFrom ('from param')">按钮3</button>
    
        <%-- 同一元素上也可以通过 v-on 绑定多个相同事件函数,执行顺序为顺序执行,响应结果:依次弹框输出 Hello Vue.js:one;Hello Vue.js:two --%>
        <button v-on:click="sayFrom (':one'), sayFrom (':two')">按钮4</button> 
    </div>
    
    <script>
        var app = new Vue({
            el: '#app',
            data: {
                msg: 'Hello Vue.js'
            },
            methods: {
                say: function () {
                    alert(this.msg);
                },
                sayFrom: function (from) {
                    alert(this.msg + '' + from);
                }
            }
        })
    </script>  
    View Code
    5.1 .prevent 调用 event.preventDefault();.self只当事件是从侦听器绑定的元素本身触发时才触发回调;v-on:click.self.prevent 和 v-on:click.prevent.self的区别:
    <%-- 节点关系:div标签>a标签>P标签 --%>
    <div style="border: 1px solid #000; padding: 10px; margin: 10px">
        <div v-on:click="alert('爷爷')">
            <a href="https://www.baidu.com" v-on:click="alert('爸爸')">爸爸
              <p v-on:click="alert('儿子')">儿子</p>
            </a>
        </div>
        <%--结果说明:点击'爷爷'会弹出'爷爷'不跳转;点击'爸爸'会依次弹出'爸爸'、'爷爷'并跳转;点击'儿子'会依次弹出'儿子'、'爸爸'、'爷爷'并跳转。这发生了事件冒泡--%>
    
        <%--v-on:click.self.prevent 阻止对元素自身的点击,.prevent修饰符在后,修饰的是元素的v-on事件在被.self修饰后的事件,所以它只能阻止对元素自身的点击,无法阻止事件冒泡--%>
        <div v-on:click="alert('爷爷')">
            <a href="https://www.baidu.com" v-on:click.self.prevent="alert('爸爸')">爸爸
              <p v-on:click="alert('儿子')">儿子</p>
            </a>
        </div>
        <%--结果说明:点击'爷爷'会弹出'爷爷'不跳转;点击'爸爸'会依次弹出'爸爸'、'爷爷'不跳转;点击'儿子'会依次弹出'儿子'、'爷爷'并跳转。分析:点击自身,.prevent修饰符阻止了<a>标签的默认事件,但是事件冒泡没有阻止;.self修饰符阻止了事件冒泡时触发元素本身绑定的事件 --%>
    
        <%--v-on:click.prevent.self 阻止所有的点击,.prevent修饰符在前,修饰的是元素的v-on事件,所以它会阻止所有的点击,自身点击和事件冒泡--%>
        <div v-on:click="alert('爷爷')">
            <a href="https://www.baidu.com" v-on:click.prevent.self="alert('爸爸')">爸爸
              <p v-on:click="alert('儿子')">儿子</p>
            </a>
        </div>
        <%--结果说明:点击'爷爷'会弹出'爷爷'不跳转;点击'爸爸'会依次弹出'爸爸'、'爷爷'不跳转;点击'儿子'会依次弹出'儿子'、'爷爷'不跳转。分析:不管是点击自身还是由于事件冒泡,.prevent修饰符都阻止了<a>标签的默认事件;.self修饰符阻止了事件冒泡时触发元素本身绑定的事件 --%>
    </div>
    View Code
    5.2 v-on:click.stop 调用 event.stopPropagation()
    <div id="app">
        <div v-on:click="dodo">
            <%-- 先弹出'noclick',再弹出'dodo' --%>
            <button v-on:click="doThis">单击事件</button>
            <%--只弹出'noclick'--%>
            <button v-on:click.stop="doThis">阻止单击事件继续传播</button>
        </div>
    </div>
    
    <script>
        var app = new Vue({
            el: '#app',
            data: {
                msg: 'Hello Vue.js'
            },
            methods: {
                doThis: function () {
                    alert("noclick");
                },
                dodo: function () {
                    alert("dodo");
                }
            }
        })
    </script>
    View Code

    6. v-text和v-html

    <div id="app"> 
        <p v-html="html"></p> 
        <p v-text="text"></p> 
    </div>
    
    <script>
        var app = new Vue({
            el: '#app',
            data: { 
                html: "<h1>html标签在渲染的时候被解析</h1>",
                text: "<h1>html标签在渲染的时候被源码输出</h1>",
            },
            beforeDestroy: function () {
                debugger
            }
        })
    </script>

    8. v-once 用于标明元素或组件只渲染一次,即使随 后发生绑定数据的变化或更新,该元素或组件及包含的子元素都不会再次被编译和渲染

    <div id="app">
        <p>{{message}}</p> 
        <p v-once>{{msg}}</p>  
    </div>
    
    <script>
        var app = new Vue({
            el: '#app',
            data: {
                message: 'aaa',
                msg: 'bbb',
            }, 
        })
    </script>

    二、自定义指令

    1. 注册指令

    Vue.directive(id, definition)

    2. 指令的定义对象

     1 <body>
     2     <div id="app">
     3         <div v-lang="color">{{num}}</div>
     4         <p>
     5             <button v-on:click="add">add</button>
     6         </p>
     7     </div>
     8     <p>
     9         <button onclick='unbind()'>解绑</button>
    10     </p>
    11 
    12     <script type="text/javascript">
    13         function unbind() {
    14             console.log('6 - unbind');//另外起一个方法解绑
    15         }
    16 
    17         Vue.directive('lang', { //五个注册指令的钩子函数
    18             bind: function () { //被绑定
    19                 console.log('1 - bind');
    20             },
    21             inserted: function () { //绑定到节点
    22                 console.log('2 - inserted');
    23             },
    24             update: function () { //组件更新
    25                 console.log('3 - update');
    26             },
    27             componentUpdated: function () { //组件更新完成
    28                 console.log('4 - componentUpdated');
    29             },
    30             unbind: function () { //解绑
    31                 console.log('5 - unbind');
    32             }
    33         })
    34         var vm = new Vue({
    35             el: "#app",
    36             data: {
    37                 num: 10,
    38                 color: 'red'
    39             },
    40             methods: {
    41                 add: function () {
    42                     this.num++;
    43                 }
    44             }
    45         })
    46     </script>
    47 </body>
    View Code

    指令的钩子函数(都是可选函数)

    1. bind: 只被调用一次,在指令第一次绑定到元素上时调用
    2. inserted:被绑定元素插入父节点时调用(仅保证父节点存在,但不一定已被插入文档中)
    3. update :指令绑定 bind 函数执行后不直接调用 update 函数, 只要组件发生重绘,无论指令接受的值是否发生变化,均会调用 update 函数,update 接收到的参数为 newValue 和 oldValue。如果需要过滤不必要的更新,则可以使用 binding.value == binding.oldValue 来判断
    4. componentUpdate:当整个组件都完成了 update 状态后即所有 DOM 都更新后调用该钩子函数,无论指令接受的参数是否发生变化
    5. unbind :指令从元素上解绑时调用,只调用一次

    3. 对象字面量

    如果指令需要多个值,可以传入一个JavaScript对象字面量,指令函数能够接受所有合法的JavaScript表达式

     1 <body>
     2     <div id="app">
     3         <div v-demo="{color:'white',text:'hello!'}"></div>
     4     </div>
     5 
     6     <script type="text/javascript">
     7         Vue.directive('demo', function (el, binding) {
     8             console.log(binding.value.color);    // 输出'white'
     9             console.log(binding.value.text);    // 输出'hello!'
    10         });
    11         new Vue({
    12             el: '#app',
    13         });
    14     </script>
    15 </body>

    4. 指令实例属性

     1 <body>
     2     <div id="app">
     3         <div v-demo="message"></div>
     4     </div>
     5 
     6     <script type="text/javascript">
     7         Vue.directive('demo', {
     8             bind: function (el, binding, vnode) {
     9                 let s = JSON.stringify;
    10                 el.innerHTML =
    11                 'name:' + s(binding.name) + '<br>' +
    12                 'value:' + s(binding.value) + '<br>' +
    13                 'expression:' + s(binding.expression) + '<br>' +
    14                 'argument:' + s(binding.arg) + '<br>' +
    15                 'modifiers:' + s(binding.modifiers) + '<br>' +
    16                 'vnode keys:' + Object.keys(vnode).join(',')
    17             }
    18         });
    19         new Vue({
    20             el: '#app',
    21             data: {
    22                 message: 'hello'
    23             }
    24         });
    25     </script>
    26 </body>
    View Code

    1. el:指定所绑定的元素,可以直接操作DOM
    2. binding:一个对象,包含若干属性
    3. vnode:Vue编译生成的虚拟节点
    4. oldVnode:上一个虚拟节点,尽在update和componentUpdated钩子函数中可用

    binding对象包含的属性:

    • name:指令名,不包含v-前缀
    • value:指令的绑定值,例如:v-mode='1+1'中,绑定值为2
    • oldValue:指定绑定的前一个值,仅在update和componentUpdate钩子中可用,无论是否改变都可用
    • expression:字符串形式的指令表达式,例如:v-mode='1+1'中,表达式为'1+1'
    • arg:传给指令的参数、可选。例如v-demo:foo中,参数为'foo'
    • modifiers:一个包含修饰符的对象。例如:v-demo.foo.bar中,修饰符对象为{foo:true,bar:true}
  • 相关阅读:
    Jenkins pipeline 流水线部署 并自定义 buildName 和 buildDescription 显示信息
    Jenkins中插件 pipeline 中声明式流水线的语法
    Linux 发送https POST请求sample ===Slack 频道中发送消息通知
    Jenkins pipline
    jenkins pipeline中获取shell命令的输出
    Chrome浏览器对标签进行整理和分组
    MacBook 对rar后缀的文件进行加压
    Macbook中Docker一栏的应用程序图标不见了,怎么找出来?
    [Pytest]运行指定的case
    软考 高项 重点知识点
  • 原文地址:https://www.cnblogs.com/zhaoyl9/p/14846343.html
Copyright © 2020-2023  润新知