05-Vue 自定义指令

111 阅读3分钟

Vue 内置指令

  • v-html:内容按普通 HTML 插入,可防止 XSS 攻击
  • v-show:根据表达式的真假值,切换元素的 display CSS 属性来显示隐藏元素
  • v-if:根据表达式的真假值来渲染元素
  • v-else:前面必须有 v-ifv-else-if
  • v-else-if:前面必须有 v-ifv-else-if
  • v-for:遍历的数组或对象
  • v-on:绑定事件监听器
  • v-bind:用于绑定元素属性
  • v-model:在表单控件或者组件上创建双向绑定
  • v-once:一次性插值,当后面数据更新后视图数据不会更新
  • v-pre:可以用来显示原始插入值标签 {{}},并跳过这个元素和它的子元素的编译过程,加快编译。如:{{message}},页面上将显示:{{message}}
  • v-text:等价于 {{}},用于显示内容,区别是:{{}} 会造成闪烁,v-text 不会
  • v-cloak:如果想用 {{}},但又不想有闪烁的问题,则可以使用该指令来处理。具体步骤如下:在被 Vue 管理的模板入口节点上作用 v-cloak 指令添加一个属性选择器:[v-cloak]{display:none;}。 原理:默认一开始的时候被 Vue 管理的模板是隐藏的,当 Vue 解析处理完 DOM 模板之后,会自动把这个样式去除,然后显示出来。

自定义指令

  除了内置指令外,Vue 也允许注册自定义指令。如有时候需要对普通 DOM 元素进行底层操作,这时候使用自定义指令就更为方便。使用自定义指令的步骤如下:

  1. 首先需要注册自定义指令

  自定义指令的注册方式有两种:

  • 注册全局指令
// 指令名称不要带-v
Vue.directive ('指令名', {
  // el 代表使用了此指令的那个 DOM 元素
  // binding 可以获取使用了此指令的绑定值(value)、表达式(expression)、指令名(name)等
  inserted: function (el, binding) {
    // 逻辑代码
  }
})
  • 注册局部指令
directives {
	'指令名': {
  	inserted (el, binding) {
    	// 逻辑代码
    }
  }
}
  1. 使用指令

  引用指令的时候,需要在指令名前面加上 v-,直接在元素上使用即可:v-指令名='表达式'

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script src="./node_modules/vue/dist/vue.min.js"></script>
</head>
<body>
    <div id="app">
        <p v-upper-text="message"></p>
        <input type="text" v-focus>
    </div>
    </div>
    <script>
        // 注册全局指令
        Vue.directive('upper-text', {
            // 一般对样式操作放在 bind 中,该函数只调用一次
            bind: function(el) {
                el.style.color = 'red';
            },
            // 一般对 js 的操作放在 inserted 中,该函数也只调用一次
            inserted: function(el, binding) {
                el.innerHTML = binding.value.toUpperCase();
            }
        });

        let app = new Vue({
            data() {
                return {
                    message: 'Hello World'
                }
            },
            // 注册局部指令
            directives: {
                'focus': {
                    inserted: function(el) {
                        el.focus();
                    }
                }
            }
        }).$mount('#app');
    </script>
</body>
</html>

关于几个函数说明

bind:只调用一次,指令第一次绑定到元素的时候调用,在这里可以进行一次性的初始化设置

inserted:被绑定元素插入父节点时调用(仅保证父节点存在,但不一定已被插入文档中)

update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新(详细的钩子函数参数见下)

componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用

unbind:只调用一次,指令与元素解绑时调用

关于 nextTick

在下次 DOM 更新循环结束之后执行延迟回调,在修改数据之后立即使用这个方法,获取更新后的 DOM:

// 修改数据
vm.msg = "Hello";
// DOM 还没有更新
Vue.nextTick( function () {
  // DOM 更新了
})

  还提供了简写的方法:

<body>
    <div id="box">
      <div v-hello=" 'yellow' ">11111111</div>
      <div v-hello=" 'red' ">22222222</div>
      <div v-hello="whichColor">33333333</div>
    </div>	


    <script type="text/javascript">
      Vue.directive("hello",(el,binding)=>{
          // 创建或者更新都会执行
          el.style.background=binding.value
      })
      var vm = new Vue({
        el:"#box",
        data:{
          whichColor:"blue"
        }
      })
    </script>
</body>