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 相关文章推荐
简单实用jquery版三级联动select示例
Jul 04 Javascript
SeaJS入门教程系列之使用SeaJS(二)
Mar 03 Javascript
javascript常用功能汇总
Jul 05 Javascript
AngularJS整合Springmvc、Spring、Mybatis搭建开发环境
Feb 25 Javascript
原生js的ajax和解决跨域的jsonp(实例讲解)
Oct 16 Javascript
Vue+Jwt+SpringBoot+Ldap完成登录认证的示例代码
May 21 Javascript
详解mpvue中使用vant时需要注意的onChange事件的坑
May 16 Javascript
JS实现给数组对象排序的方法分析
Jun 24 Javascript
微信小程序 select 下拉框组件功能
Sep 09 Javascript
vue父组件给子组件的组件传值provide inject的方法
Oct 23 Javascript
Openlayers实现点闪烁扩散效果
Sep 24 Javascript
vue使用exif获取图片旋转,压缩的示例代码
Dec 11 Vue.js
微信公众号开发 自定义菜单跳转页面并获取用户信息实例详解
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
索尼SONY ICF-SW7600GR电路分析与改良
2021/03/02 无线电
PHP输出控制功能在简繁体转换中的应用
2006/10/09 PHP
一个漂亮的php验证码类(分享)
2013/08/06 PHP
ThinkPHP 3.2 数据分页代码分享
2014/10/14 PHP
yii实现使用CUploadedFile上传文件的方法
2015/12/28 PHP
php微信开发之关注事件
2018/06/14 PHP
使用基于jquery的gamequery插件做JS乒乓球游戏
2011/07/31 Javascript
基于jQuery实现的图片切换焦点图整理
2014/12/07 Javascript
JavaScript数据结构和算法之二叉树详解
2015/02/11 Javascript
jQuery基于图层模仿五星星评价功能的方法
2015/05/07 Javascript
jquery中表单 多选框的一种巧妙写法
2015/09/06 Javascript
解决jquery插件:TypeError:$.browser is undefined报错的方法
2015/11/21 Javascript
javaScript给元素添加多个class的简单实现
2016/07/20 Javascript
ES6记录异步函数的执行时间详解
2016/08/31 Javascript
浅谈EasyUI常用控件的禁用方法
2016/11/09 Javascript
微信小程序 高德地图SDK详解及简单实例(源码下载)
2017/01/11 Javascript
jQuery Validate 数组 全部验证问题
2017/01/12 Javascript
Node.js+jade+mongodb+mongoose实现爬虫分离入库与生成静态文件的方法
2017/09/20 Javascript
Koa2微信公众号开发之本地开发调试环境搭建
2018/05/16 Javascript
javascript function(函数类型)使用与注意事项小结
2019/06/10 Javascript
在Linux下使用Python的matplotlib绘制数据图的教程
2015/06/11 Python
Python发送邮件功能示例【使用QQ邮箱】
2018/12/04 Python
Python中dict和set的用法讲解
2019/03/28 Python
python 使用matplotlib 实现从文件中读取x,y坐标的可视化方法
2019/07/04 Python
Python namedtuple命名元组实现过程解析
2020/01/08 Python
new_zeros() pytorch版本的转换方式
2020/02/18 Python
全网首秀之Pycharm十大实用技巧(推荐)
2020/04/27 Python
python实现经纬度采样的示例代码
2020/12/10 Python
HTML5中form如何关闭自动完成功能的方法
2018/07/02 HTML / CSS
爱尔兰电子产品购物网站:Komplett.ie
2018/04/04 全球购物
来自Ocado的宠物商店:Fetch
2018/07/10 全球购物
澳大利亚在线奢侈品时尚零售平台:Azura Runway
2021/01/13 全球购物
报关专员求职信范文
2014/02/22 职场文书
大学学生会竞选演讲稿
2014/04/25 职场文书
校园绿化美化方案
2014/06/08 职场文书
工伤事故赔偿协议书(标准)
2014/09/29 职场文书