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 相关文章推荐
跨浏览器开发经验总结(三)   警惕“IE依赖综合症”
May 13 Javascript
jquery mobile的触控点击事件会多次触发问题的解决方法
May 08 Javascript
JS设置cookie、读取cookie、删除cookie
Apr 17 Javascript
javascript图片切换综合实例(循环切换、顺序切换)
Jan 13 Javascript
window.open不被拦截的简单实现代码(推荐)
Aug 04 Javascript
浅谈jquery采用attr修改form表单enctype不起作用的问题
Nov 25 Javascript
yii form 表单提交之前JS在提交按钮的验证方法
Mar 15 Javascript
vue-cli中使用高德地图的方法示例
Mar 28 Javascript
webpack4 optimization使用总结
Nov 10 Javascript
非常漂亮的js烟花效果
Mar 10 Javascript
手机浏览器唤起微信分享(JS)
Oct 11 Javascript
详细聊聊浏览器是如何看闭包的
Nov 11 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模板,主要想体现一下思路
2006/12/25 PHP
php中函数的形参与实参的问题说明
2010/09/01 PHP
四个PHP非常实用的功能
2015/09/29 PHP
jquery中常用的SET和GET
2009/01/13 Javascript
javascript基础知识大全 便于大家学习,也便于我自己查看
2012/08/17 Javascript
JS短路原理的应用示例 精简代码的途径
2013/12/13 Javascript
javascript实现获取浏览器版本、操作系统类型
2015/01/29 Javascript
JavaScript实现在标题栏上显示当前日期的方法
2015/03/19 Javascript
Bootstrap三种表单布局的使用方法
2016/06/21 Javascript
JavaScript 控制字体大小设置的方法
2016/11/23 Javascript
Node.js和Express简单入门介绍
2017/03/24 Javascript
基于rollup的组件库打包体积优化小结
2018/06/18 Javascript
javascript中的event loop事件循环详解
2018/12/14 Javascript
element-ui带输入建议的input框踩坑(输入建议空白以及会闪出上一次的输入建议问题)
2019/01/15 Javascript
原生js实现each方法实例代码详解
2019/05/27 Javascript
vue.js购物车添加商品组件的方法
2019/09/17 Javascript
vue.js中ref及$refs的使用方法解析
2019/10/08 Javascript
js+cavans实现图片滑块验证
2020/09/29 Javascript
详解vue中使用transition和animation的实例代码
2020/12/12 Vue.js
[13:40]TI3青蛙君全程回顾 DOTA2我们为梦想再战
2013/09/13 DOTA
[01:38]女王驾到——至宝魔廷新尊技能&特效展示
2020/06/16 DOTA
Python基础之getpass模块详细介绍
2017/08/10 Python
详解python里使用正则表达式的全匹配功能
2017/10/19 Python
K-means聚类算法介绍与利用python实现的代码示例
2017/11/13 Python
使用tensorflow实现线性回归
2018/09/08 Python
Django利用cookie保存用户登录信息的简单实现方法
2019/05/27 Python
python 中值滤波,椒盐去噪,图片增强实例
2019/12/18 Python
Python递归求出列表(包括列表中的子列表)的最大值实例
2020/02/27 Python
scrapy头部修改的方法详解
2020/12/06 Python
英国殿堂级有机护肤品牌:Rodial
2017/04/17 全球购物
英国最大的在线运动补充剂商店:Discount Supplements
2017/06/03 全球购物
shell的种类有哪些
2015/04/15 面试题
远程教育心得体会
2014/01/03 职场文书
终止劳动合同协议书
2014/04/14 职场文书
幼师自荐信范文(2016推荐篇)
2016/01/28 职场文书
Python初学者必备的文件读写指南
2021/06/23 Python