Vue.JS入门教程之自定义指令


Posted in Javascript onDecember 08, 2016

基础

Vue.js 允许你注册自定义指令,实质上是让你教 Vue 一些新技巧:怎样将数据的变化映射到 DOM 的行为。你可以使用Vue.directive(id, definition)的方法传入指令id和定义对象来注册一个全局自定义指令。定义对象需要提供一些钩子函数(全部可选):

  • bind: 仅调用一次,当指令第一次绑定元素的时候。
  • update: 第一次是紧跟在 bind 之后调用,获得的参数是绑定的初始值;以后每当绑定的值发生变化就会被调用,获得新值与旧值两个参数。
  • unbind:仅调用一次,当指令解绑元素的时候。

例子:

Vue.directive('my-directive', {
 bind: function () {
 // 做绑定的准备工作
 // 比如添加事件监听器,或是其他只需要执行一次的复杂操作
 },
 update: function (newValue, oldValue) {
 // 根据获得的新值执行对应的更新
 // 对于初始值也会被调用一次
 },
 unbind: function () {
 // 做清理工作
 // 比如移除在 bind() 中添加的事件监听器
 }
})

一旦注册好自定义指令,你就可以在 Vue.js 模板中像这样来使用它(需要添加 Vue.js 的指令前缀,默认为 v-):

<div v-my-directive="someValue"></div>

如果你只需要 update 函数,你可以只传入一个函数,而不用传定义对象:

Vue.directive('my-directive', function (value) {
 // 这个函数会被作为 update() 函数使用
})

所有的钩子函数会被复制到实际的指令对象中,而这个指令对象将会是所有钩子函数的this
上下文环境。指令对象上暴露了一些有用的公开属性:

el: 指令绑定的元素
vm: 拥有该指令的上下文 ViewModel
expression: 指令的表达式,不包括参数和过滤器
arg: 指令的参数
raw: 未被解析的原始表达式
name: 不带前缀的指令名

这些属性是只读的,不要修改它们。你也可以给指令对象附加自定义的属性,但是注意不要覆盖已有的内部属性。

使用指令对象属性的示例:

 

<!DOCTYPE html>
<html>
<head lang="en">
 <meta charset="UTF-8">
 <title></title>
 <script src="http://cdnjs.cloudflare.com/ajax/libs/vue/0.12.16/vue.min.js"></script>
</head>
<body>
<div id="demo" v-demo-directive="LightSlateGray : msg"></div>

<script>
 Vue.directive('demoDirective', {
  bind: function () {
   this.el.style.color = '#fff'
   this.el.style.backgroundColor = this.arg
  },
  update: function (value) {
   this.el.innerHTML =
     'name - '  + this.name + '<br>' +
     'raw - '  + this.raw + '<br>' +
     'expression - ' + this.expression + '<br>' +
     'argument - ' + this.arg + '<br>' +
     'value - '  + value
  }
 });
 var demo = new Vue({
  el: '#demo',
  data: {
   msg: 'hello!'
  }
 })

</script>
</body>
</html>

多重从句

同一个特性内部,逗号分隔的多个从句将被绑定为多个指令实例。在下面的例子中,指令会被创建和调用两次:

<div v-demo="color: 'white', text: 'hello!'"></div>

如果想要用单个指令实例处理多个参数,可以利用字面量对象作为表达式:

<div v-demo="{color: 'white', text: 'hello!'}"></div>

Vue.directive('demo', function (value) {
 console.log(value) // Object {color: 'white', text: 'hello!'}
})

字面指令

如果在创建自定义指令的时候传入 isLiteral: true ,那么特性值就会被看成直接字符串,并被赋值给该指令的 expression。字面指令不会试图建立数据监视。
例子:

<div v-literal-dir="foo"></div>

Vue.directive('literal-dir', {
 isLiteral: true,
 bind: function () {
 console.log(this.expression) // 'foo'
 }
})

动态字面指令

然而,在字面指令含有 Mustache 标签的情形下,指令的行为如下:

指令实例会有一个属性,this._isDynamicLiteral被设为true;

如果没有提供update函数,Mustache 表达式只会被求值一次,并将该值赋给this.expression。不会对表达式进行数据监视。

如果提供了update函数,指令将会为表达式建立一个数据监视,并且在计算结果变化的时候调用update。

双向指令

如果你的指令想向 Vue 实例写回数据,你需要传入 twoWay: true 。该选项允许在指令中使用 this.set(value)。

Vue.directive('example', {
 twoWay: true,
 bind: function () {
 this.handler = function () {
  // 把数据写回 vm
  // 如果指令这样绑定 v-example="a.b.c",
  // 这里将会给 `vm.a.b.c` 赋值
  this.set(this.el.value)
 }.bind(this)
 this.el.addEventListener('input', this.handler)
 },
 unbind: function () {
 this.el.removeEventListener('input', this.handler)
 }
})

内联语句

传入 acceptStatement: true 可以让自定义指令像 v-on 一样接受内联语句:

<div v-my-directive="a++"></div>

Vue.directive('my-directive', {
 acceptStatement: true,
 update: function (fn) {
 // the passed in value is a function which when called,
 // will execute the "a++" statement in the owner vm's
 // scope.
 }
})

但是请明智地使用此功能,因为通常我们希望避免在模板中产生副作用。

深度数据观察

如果你希望在一个对象上使用自定义指令,并且当对象内部嵌套的属性发生变化时也能够触发指令的 update 函数,那么你就要在指令的定义中传入 deep: true。

<div v-my-directive="obj"></div>

Vue.directive('my-directive', {
 deep: true,
 update: function (obj) {
 // 当 obj 内部嵌套的属性变化时也会调用此函数
 }
})

指令优先级

你可以选择给指令提供一个优先级数(默认是0)。同一个元素上优先级越高的指令会比其他的指令处理得早一些。优先级一样的指令会按照其在元素特性列表中出现的顺序依次处理,但是不能保证这个顺序在不同的浏览器中是一致的。

通常来说作为用户,你并不需要关心内置指令的优先级,如果你感兴趣的话,可以参阅源码。逻辑控制指令 v-repeat, v-if 被视为 “终结性指令”,它们在编译过程中始终拥有最高的优先级。

元素指令

有时候,我们可能想要我们的指令可以以自定义元素的形式被使用,而不是作为一个特性。这与 Angular 的 E 类指令的概念非常相似。元素指令可以看做是一个轻量的自定义组件(后面会讲到)。你可以像下面这样注册一个自定义的元素指令:

Vue.elementDirective('my-directive', {
 // 和普通指令的 API 一致
 bind: function () {
 // 对 this.el 进行操作...
 }
})

使用时我们不再用这样的写法:

<div v-my-directive></div>

而是写成:

<my-directive></my-directive>
元素指令不能接受参数或表达式,但是它可以读取元素的特性,来决定它的行为。与通常的指令有个很大的不同,元素指令是终结性的,这意味着,一旦 Vue 遇到一个元素指令,它将跳过对该元素和其子元素的编译 - 即只有该元素指令本身可以操作该元素及其子元素。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
图片img的src不变让浏览器重新加载实现方法
Mar 29 Javascript
纯Javascript实现ping功能的方法
Mar 20 Javascript
javascript封装 Cookie 应用接口
Aug 07 Javascript
移动端翻页插件dropload.js(支持Zepto和jQuery)
Jul 27 Javascript
JavaScript字符串对象(string)基本用法示例
Jan 18 Javascript
js 两个日期比较相差多少天的实例
Oct 19 Javascript
详解如何使用PM2将Node.js的集群变得更加容易
Nov 15 Javascript
在vue中封装可复用的组件方法
Mar 01 Javascript
如何在Angular应用中创建包含组件方法示例
Mar 23 Javascript
微信小程序自定义弹窗滚动与页面滚动冲突的解决方法
Jul 16 Javascript
浅谈Vue中render中的h箭头函数
Nov 07 Javascript
在 Vue 中编写 SVG 图标组件的方法
Feb 24 Javascript
微信公众号开发 自定义菜单跳转页面并获取用户信息实例详解
Dec 08 #Javascript
node.js学习之交互式解释器REPL详解
Dec 08 #Javascript
JavaScript正则表达式小结(test|match|search|replace|split|exec)
Dec 08 #Javascript
JS中用childNodes获取子元素换行会产生一个子元素
Dec 08 #Javascript
微信公众号 摇一摇周边功能开发
Dec 08 #Javascript
Vue概念及常见命令介绍(1)
Dec 08 #Javascript
Jquery给当前页或者跳转后页面的导航栏添加选中后样式的实例
Dec 08 #Javascript
You might like
深入理解PHP之OpCode原理详解
2016/06/01 PHP
CI框架(ajax分页,全选,反选,不选,批量删除)完整代码详解
2016/11/01 PHP
关于jQuery object and DOM element
2013/04/15 Javascript
浏览器页面区域大小的js获取方法
2013/09/21 Javascript
JavaScript中的逻辑判断符&amp;&amp;、||与!介绍
2014/12/31 Javascript
js简单设置与使用cookie的方法
2016/01/22 Javascript
Bootstrap组件系列之福利篇几款好用的组件(推荐二)
2016/07/12 Javascript
jQuery实现的右下角广告窗体跟随效果示例
2016/09/16 Javascript
浅谈js中的引用和复制(传值和传址)
2016/09/18 Javascript
JS常见创建类的方法小结【工厂方式,构造器方式,原型方式,联合方式等】
2017/04/01 Javascript
nodejs基础之buffer缓冲区用法分析
2018/12/26 NodeJs
详解element-ui日期时间选择器的日期格式化问题
2019/04/08 Javascript
Vue+ElementUI项目使用webpack输出MPA的方法
2019/08/27 Javascript
基于layui框架响应式布局的一些使用详解
2019/09/16 Javascript
python应用程序在windows下不出现cmd窗口的办法
2014/05/29 Python
深入理解python中的浅拷贝和深拷贝
2016/05/30 Python
详细解读tornado协程(coroutine)原理
2018/01/15 Python
对python pandas 画移动平均线的方法详解
2018/11/28 Python
在python 中split()使用多符号分割的例子
2019/07/15 Python
Python通过4种方式实现进程数据通信
2020/03/12 Python
设置jupyter中DataFrame的显示限制方式
2020/04/12 Python
Python3 pywin32模块安装的详细步骤
2020/05/26 Python
CSS3 实现穿梭星空动画
2020/11/13 HTML / CSS
html5 css3实例教程 一款html5和css3实现的小机器人走路动画
2014/10/20 HTML / CSS
欧舒丹澳洲版:L’OCCITANE
2017/07/17 全球购物
成教毕业生自我鉴定
2013/10/23 职场文书
管理专员自荐信
2014/01/26 职场文书
人力资源部门的主要职能
2014/02/22 职场文书
教师竞聘上岗演讲稿
2014/09/03 职场文书
大学生创业事迹材料
2014/12/30 职场文书
贷款担保书
2015/01/20 职场文书
eclipse创建项目没有dynamic web的解决方法
2021/06/24 Java/Android
一定要知道的 25 个 Vue 技巧
2021/11/02 Vue.js
PHP 时间处理类Carbon
2022/05/20 PHP
使用CSS实现黑白格背景效果
2022/06/01 HTML / CSS
不想升级Win11?教你彻底锁定老版Windows系统的方法(附下载地址)
2022/09/23 数码科技