Vue的内置指令和自定义指令学习笔记

152 阅读4分钟

内置指令

v-text指令

  1. 作用:向其所在的节点中渲染文本内容。
  2. 与插值语法的区别:v-text会替换掉节点中的内容,{{xx}}不会。

1.png

2.png

 <div id="vtext">
        <div>你好,{{name}}</div>
        <div v-text="name">你好,</div>
        <div v-text="name"></div>
    </div>
    <script>
        new Vue({
            el: '#vtext',
            data: {
                name: 'nepu',
                str: '<h3>你好哈哈哈哈</h3>'
            }
        })
    </script>

v-html指令

  1. 作用:向指定节点中渲染包含html结构的内容
  2. 与插值语法的区别:
    1. v-html会替换掉节点中所有的内容,{{xx}}不会。
    2. v-html可以识别html结构。
  3. ⭐严重注意:v-html有安全性问题
    1. 再网站上动态渲染任意html是非常危险的,容易导致XXS攻击。
    2. 一定要在可信的内容上使用v-html,永不要在用户提交的内容上!!!

v-cloak指令

vue.js脚本引入在vue模板和vue实例之间时,当网络较慢,网页还在加载 Vue.js ,而导致 Vue 来不及渲染,这时页面就会显示出 Vue 源代码。我们可以使用 v-cloak 指令来解决这一问题。

    <div id="cloak">
        <h2 v-cloak>{{name}}</h2>
    </div>

    <style>
        [v-cloak] {
            display: none;
        }
    </style>

    <script src="http://localhost:8080/resource/5s/vue.js"></script>

    <script>
        console.log(1)

        new Vue({
            el: '#cloak',
            data: {
                name: 'hhhhhhhh'
            }
        })
    </script>

加入v-cloak之后的运行结果,打开浏览器运行,缓冲5s后显示内容,缓冲过程页面无内容。

小结v-cloak

v-cloak指令(没有值):

  1. 本质是一个特殊属性,Vue实例创建完毕并接管容器后,会删掉v-cloak属性。
  2. 使用css配合v-cloak可以解决网速慢时页面展示出{{xxx}}的问题。

v-once

  1. v-once所在节点在初次动态渲染后,被视为静态内容了。
  2. 以后数据的改变不会引起v-once所在结构的更新,可以用于优化性能。
    <div id="vonce">
        <h2 v-once>初始n值:{{n}}</h2>
        <h2>当前n值:{{n}}</h2>
        <button @click="n++">点我n+1</button>
    </div>
    <script>
        new Vue({
            el: '#vonce',
            data: {
                n: 1
            }
        })
    </script>

v-pre

v-pre指令:

  1. 跳过其所在节点的编译过程
  2. 可利用它跳过:没有使用指令语法、没使用插值语法的节点,会加快编译。
    <div id="vpre">
        <h2 v-pre>hello大家好</h2>
        <h2 v-pre>当前值为:{{n}}</h2>
        <button v-pre @click="n++">n+1</button>
    </div>
    <script>
        new Vue({
            el: '#vpre',
            data: {
                n: 1
            }
        })
    </script>

运行结果截图

3.png

自定义指令

需求1:定义一个v-big指令,和v-text功能类似,但会把绑定的数值放大10倍。 代码:

    <div id="vbig">
        <h2>当前n值:<span v-text="n"></span></h2>
        <h2>放大10倍之后的n值为:<span v-big="n"></span></h2>
        <button @click="n++">n+1</button>
    </div>
    <script>
        new Vue({
            el: '#vbig',
            data: {
                n: 1
            },
            directives: {
                big(element, binding) {
                    element.innerText = binding.value * 10
                }
            }
        })
    </script>

难点:

  1. directives对象的形式可以处理一些细节,函数不可以。
  2. big函数被调用的两种情况: (1) 指令与元素成功绑定时(一上来) (2) 指令所在的模板被重新解析
  3. big函数不能通过返回值返回结果。 big函数接收的两个参数是啥,可以运行如下代码查看
   big(a, b) {
       console.log(a, b)
   }

运行截图 4.png span是真实DOM元素,console.dir(a)可以证明

5.png console.log(a instanceof HTMLElement)运行结果为true也可以证明span是真实DOM元素 所以参数a是真实DOM元素span,b是包含很多属性的对象。

6.png

需求2:定义一个v-fbind指令,和v-bind功能类似,但可以让其绑定的input元素默认获取焦点。

<input type="text" v-fbind:value="n" autofocus>
 fbind(element, binding) {
     element.value = binding.value
     element.focus()
 }

以chrome浏览器为例,autofocus会使得输入框内光标聚焦,去掉autofocus就不会聚焦了,但是一些浏览器中autofocus并不好使。就不会聚焦了。第二个input输入框交给vue,指令与元素绑定成功,关系建立页面没有input,点击按钮n发生变化,模板重新解析,重新调用fbind,element已经存在,所以会成功聚焦。vue将元素放入页面不能被fbind捕捉,所以考虑使用对象式自定义指令。 代码中获取焦点的功能没有实现,原因可以通过如下代码解释

    <button id="btn">点我创建一个输入框</button>

    <script>
        const btn = document.getElementById('btn')
        btn.onclick = () => {
            const input = document.createElement('input')
            document.body.appendChild(input)
            input.focus()
        }
    </script>

运行截图

7demo.png 成功添加了输入框并且获取焦点。input.focus()必须放在最后.

对象式自定义指令代码

 fbind: {
     // 指令与元素成功绑定时(一上来)
     bind(element, binding) {
         element.value = binding.value
     },
    // 指令所在元素被插入页面时
     inserted(element, binding) {
         element.focus()
     },
     // 指令所在的模板被重新解析时
     update(element, binding) {
         element.value = binding.value
     }
 }

bind和update对应函数bind被调用的两个时刻。

自定义指令总结

定义语法

  1. 局部指令: new Vue({ directives:{指令名:配置对象} }) 或者 new Vue({ directives(){} })
  2. 全局指令: Vue.directive(指令名,配置对象) 或者 Vue.directive(指令名,回调函数)
Vue.directive('big',function(element,binding){
    console.log('big',this)//this是window
})

配置对象中常用的三个回调

  1. bind:指令与元素成功绑定时调用
  2. inserted:指令所在元素被插入页面时调用。
  3. update:指令所在模板结构被重新解析时调用。

备注

  1. 指令定义时不加v-,但使用的时候要加v-;
  2. 指令名如果是多个单词,要使用kebab-case命名方式,不要用camelCase命名。