Vue 通过自定义指令回顾v-内置指令(小结)


Posted in Javascript onSeptember 03, 2018

Vue.js 的各种指令(Directives)更加方便我们去数据驱动 DOM,例如 v-bind、v-on、v-model、v-if、v-for、v-once 等内置指令,这些指令的职责就是当表达式改变时将某些行为应用到 DOM 上,尽量不去操作增删改 DOM。通过了解如何去自定义指令,可以想象内置指令是如何完成的。

内置指令

指令名称 描述 使用
v-model 绑定数据
v-text 输出文本,不能解析标签
v-html 输出文本,可解析标签 /p>
v-once 只绑定一次数据 {{message}}
v-bind 绑定属性
v-if 控制是否显示容器 值转为布尔为false时 注释该容器,反之显示
v-show 控制是否显容器,改变的时display:none/block
v-for 循环遍历数组、对象 {{val}}
v-cloak 在还没有执行到vue代码的时候隐藏元素,可解决‘闪烁'问题 {{message}}

自定义指令

在需要特殊功能时,使用自定义指令对 DOM 进行底层操作

注册

自定义指令的注册分为全局注册和局部注册,类似组件的注册,只是方法名为 directive,写法如下:

// 全局注册 自定义指令
Vue.directive(‘mydir',{
  // 指令选项
});
// 全局注册 自定义指令函数
Vue.directive('mydir', function () {
 // 这里将会被 `bind` 和 `update` 调用
})
// 局部注册(只针对组件内元素)
export default {
  directives: {
    mydir: {
      // 指令选项
    }
  }
}

需要注意的是:Vue.directive( ) 注册指令要在实例初始化 new Vue( ) 之前才能全局注册指令。定义指令时驼峰式写法会报错,所以一般小写。

指令选项

自定义指令的选项是由几个钩子函数(可选)组成,可以根据需求选择不同的钩子,例如使用全局注册一个指令时:

Vue.directive('mydir', {
 bind: function () {
  // 只调用一次,指令第一次绑定到元素时调用,用于在绑定元素时执行一次的初始化动作。
  },
 update: function () {
  // 第一次是紧跟在 bind 之后调用,获得的参数是绑定的初始值,
  // 之后被绑定元素所在的模板更新时调用,而不论绑定值是否变化,可以忽略不必要的模板更新。  
  }, 
 inserted: function () {
  // 被绑定元素插入父节点时调用(父节点存在即可调用,不必存在于 document 中)。
  },
 componentUpdated: function () {
  // 被绑定元素所在模板完成一次更新周期时调用。
  },
 unbind: function () {
  // 只调用一次, 指令与元素解绑时调用。
  }
})

以上每个钩子函数都有几个参数可用:

  1. el:指令所绑定的元素,可以用来直接操作 DOM;
  2. binding:包含指令信息的一个对象;
  3. vnode:Vue 编译的生成虚拟节点;
  4. oldVnode:上一次的虚拟节点,仅在update和componentUpdated钩子函数中可用。

示例

// 一个带自定义指令的元素
<div v-mytest:foo.m1.m2="1+1">MyDirective</div>

// 部分 JS 代码
export default {
  directives:{
   mytest: {
    bind: function (el, binding, vnode) {
     console.log(el)
     console.log(binding)
     console.log(vnode)
    }
   }
  }
}

控制台输出截图:

Vue 通过自定义指令回顾v-内置指令(小结)

其中对于 binding 对象输出的属性有:

  1. rawName: "v-mytest:foo.m1.m2" // 自定义指令
  2. name: "mytest" // 指令名称
  3. arg: "foo" // 指令的参数
  4. modifiers: {m1: true, m2: true} // 指令的修饰符
  5. expression: "1+1" // 指令绑定值的字符串形式
  6. value: 2 // 指令的绑定值

v-bind || : 绑定属性

Vue 内置指令 v-bind 用于动态更新 HTML 元素属性,使用 v-bind:someAttr = "someData"或者语法糖 :someAttr = "someData"就可以在 someData 改变时更新绑定的 someAttr 属性。

基本用法

绑定单一的属性值

<a :href="url" rel="external nofollow" rel="external nofollow" :id="linkID">链接</a>

测试 data 如下:

// js
data : {
  url: 'https://www.baidu.com/',
  linkID : 'myid'
}

元素渲染输出:

<a href="https://www.baidu.com/" rel="external nofollow" rel="external nofollow" id="myid">链接</a>

对象语法

v-bind 最常用的是绑定 class 或 style 属性来动态改变样式。例如可以给 :class 设置一个对象来动态切换 class 的值:

<!-- class 绑定 -->
<div :class="{colorRed: isRed}"></div>

当 isRed:true 时渲染输出:

<div class="colorRed"></div>

对象中可以传入多个属性值来动态切换 class:

<!-- class 绑定,传入多个属性 -->
<div :class="{ classA: isA, classB: isB }">

当 isA、isB 变化时 classA、classB 会动态更新,当都为 true 时显然渲染结果为:

<div class="classA classB"></div>

同理对于 style 可以传入对象属性,并且可以使用字符串拼接:

<!-- style 绑定 -->
<div :style="{ fontSize: size + 'px' }"></div>

对于元素中的各个对象可以统一用 v-bind 绑定:

<!-- 绑定一个有属性的对象 -->
<div v-bind="{ id: someProp, 'other-attr': otherProp }"></div>

数组语法

class 可以传入多值,给 :class 绑定一个数组就可以使用 class 列表

<div :class="[activeA, activeB]"></div>

例如当 {activeA: 'class1', activeB: 'class2'} 时渲染结果为:

<div class="class1 class2"></div>

还可以在数组语法中使用三元表达式切换 class,例如:

<div :class="[isA ? activeA : '', activeB]">

在 class 有多个条件时使用三元表达式比较繁琐,可以在数组语法中使用对象语法:

<div :class="[{activeA: isA}, activeB]">

修饰符

v-bind 的修饰符很少,API 中只提供.prop、.camel和.sync,并且多用于组件,使用方式示例:

<!-- 通过 prop 修饰符绑定 DOM 属性 (property) -->
<div v-bind:text-content.prop="text"></div>

<!-- .camel 修饰符(2.1.0+)将 v-bind 属性名称 kebab-case 驼峰化为 camelCase -->
<svg :view-box.camel="viewBox"></svg>

<!-- .sync 修饰符(2.3.0+) 语法糖,会扩展成一个更新父组件绑定值的 v-on 侦听器-->
<text-document v-bind:title.sync="doc.title"></text-document>
<!-- 批量绑定,将 doc 对象中的每一个属性 (如 title) 都作独立的 prop ,各自添加 v-on 监听器-->
<text-document v-bind.sync="doc"></text-document>

v-on || @ 监听事件

v-on 用于动态绑定事件监听器,使用 v-on:someEvent = "someFunction"或者语法糖 @someEvent = "someFunction"就可以监听 someEvent 进行交互。

基本用法

@someEvent 调用的方法名后面可以不跟(),例如:

<a :href="url" rel="external nofollow" rel="external nofollow" :id="linkID">链接</a>
<!-- 监听一个事件 -->
<button @click="changeFun">change button</button>

可以在 methods 中添加函数:

// 部分 JS 代码
methods :{
 changeFun : function () {
  this.linkID = 'changeID' // 指向当前组件本身
 }
}

点击 button 按钮后 a 元素的 id 改变:

<a href="https://www.baidu.com/" rel="external nofollow" rel="external nofollow" id="changeID">链接</a>

当然 v-on 还可以使用对象语法监听多个事件:

<!-- v2.4.0+ -->
<button v-on="{ mousedown: doThis, mouseup: doThat }"></button>

对于在 HTML 元素上监听的事件,当 ViewModel 销毁时,所有的事件处理器会自动删除,无需自己清理。

修饰符

Vue 可以将原生事件对象参数 event 传入事件方法中,并提供了特殊变量$event用来访问元素 DOM 事件。此外可以通过一些事件修饰符来实现特定的事件,如 .stop、.prevent、.capture、.once 等,常用的使用示例:

<!-- 停止单击事件冒泡,调用 event.stopPropagation()-->
<button @click.stop="doThis"></button>

<!-- 阻止默认行为,调用 event.preventDefault() -->
<button @submit.prevent="doThis"></button>

<!-- 添加事件侦听器时使用 capture 事件捕获模式 -->
<button @click.capture="doThis"></button>

<!-- 点击回调只会触发一次 -->
<button @click.once="doThis"></button>

<!-- 只当点击鼠标左键时触发(2.2.0) -->
<button @click.left="doThis"></button>

<!-- 串联修饰符 -->
<button @click.stop.prevent="doThis"></button>

此外,v-on 还提供按键修饰符来监听键盘事件,键值为 .keyCode,常用有.entry、.delete、.tab、.esc、.space、.down等,如下:

<!-- 只有在 `keyCode` 是 5 时调用 `vm.submit()` -->
<input v-on:keyup.5="submit">

<!-- 为重要的 keyCode 如 enter 提供别名-->
<input v-on:keyup.enter="submit">

<!-- 缩写语法 -->
<input @keyup.enter="submit">

此外还有系统修饰符监听键盘事件,不同的系统其键盘/系统修饰符不一样。这些按键修饰符可以任意组合使用。

v-if、v-show 条件渲染

条件渲染 v-if 根据表达式的值的真假条件渲染元素,在表达式为真时渲染,为假时移除。

<p v-if="status === 1">当 status 为 1 时显示此行</p>

<p v-else-if="status === 1">当 status 为 2 时显示此行</p>

<p v-else>其它情况默认显示此行</p>

v-show 也是条件渲染,但只切换元素的 CSS 属性 display,无论条件真假都会被编译,相比于 v-if 更适用于频繁切换场景。

<p v-show="status === 1">当 status 为 1 时显示此行</p>

当 data: {status: 2} 时隐藏,但依旧会被编译,渲染结果为:

<p style="display: none;">当 status 为 1 时显示此行</p>

显然在 Vue.js 内置的 <template> 元素上可以使用 v-if,但不能使用 v-show,可以思考下为什么。

v-for 列表渲染

列表渲染指令 v-for 常用于数组遍历或枚举一个对象的循环显示,必须结合 in 使用特定语法 alias in expression 为当前遍历的元素提供别名:

<!-- 遍历一个数组 -->
<div v-for="item in items">{{ item.text }}</div>

<!-- 提供第二个的参数为数组的索引 -->
<div v-for="(item, index) in items">{{ index }} - {{ item.text }}</div>

<!-- 遍历对象属性 -->
<div v-for="value in object">{{ value }}</div>

<!-- 提供第二个可选的参数:对象的键名 -->
<div v-for="(value, key) in object">{{ key }}: {{ value }}</div>

<!-- 提供第三个的可选参数:对象的索引 -->
<div v-for="(value, key, index) in object">{{ index }}. {{ key }}: {{ value }}</div>

可以用 of 替代 in 作为分隔符

当 v-for 和 v-if 在同一节点一起使用时,v-for 的优先级比 v-if 更高。

v-model 表单控件双向绑定

v-model 其实也是一个特殊的语法糖,其实实现的数据双向绑定也可用v-bind和v-on实现,但v-model在不同表单上会有更加智能的处理。

文本框

经典的使用案例是对<input>、<textarea>文本框的双向数据绑定:

<!-- 输入框 -->
<input type="text" v-model="message" placeholder="edit me">
<!-- 文本域 -->
<textarea v-model="message" placeholder="edit me"></textarea>
<!-- 实时更新 -->
<p>Message is: {{ message }}</p>

动态选择

对于单选按钮,复选框及选择框的选项,v-model配合 Vue 实例的数据作为value属性值实现不同效果,即会忽略所有表单元素的 value、checked、selected 特性的值。

<!--单选按钮的互斥效果-->
<div id="example-radio">
 <input type="radio" id="one" value="One" v-model="picked">
 <label for="one">One</label>
 
 <input type="radio" id="two" value="Two" v-model="picked">
 <label for="two">Two</label>
 
 <!-- picked 显示的是 value 的值 -->
 <p>Picked: {{ picked }}</p>
</div>

<!--多选按钮-->
<div id='example-checkbox'>
 <input type="checkbox" id="one" value="One" v-model="checkedNames">
 <label for="jack">Jack</label>
 <input type="checkbox" id="two" value="Two" v-model="checkedNames">
 <label for="john">John</label>

  <!-- Checked 显示的是 value 组成的数组 -->
 <p>Checked: {{ checkedNames }}</p>
</div>

修饰符

v-model的修饰符的使用限制在<input>、<select>、<textarea> 和组件。

  1. .lazy - 取代 input 监听 change 事件
  2. .number - 输入字符串转为数字
  3. .trim - 输入首尾空格过滤

v-pre、v-cloak、v-once

这三个指令的共同点是无需表达式,用法如下:

<!-- 不显示未编译的标签直到实例初始化完 -->
<div v-cloak>{{ message }}</div>
<!-- 需要配合 CSS 隐藏样式 [v-cloak]{ display: none;}-->

<!-- 只渲染一次,随后的渲染将被视为静态内容并跳过 -->
<div v-once>{{ message }}</div>

<!-- 不会被编译,直接显示显示原始{{ }}标签 -->
<div v-pre>{{ message }}</div>

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

Javascript 相关文章推荐
js调用flash的效果代码
Apr 26 Javascript
仿微博字符限制效果实现代码
Apr 20 Javascript
自己做的模拟模态对话框实现代码
May 23 Javascript
js关闭模态窗口刷新父页面或跳转页面
Dec 13 Javascript
JS保存、读取、换行、转Json报错处理方法
Jun 14 Javascript
jQuery EasyUI实现右键菜单变灰不可用效果
Sep 24 Javascript
js HTML5 Ajax实现文件上传进度条功能
Feb 13 Javascript
JavaScript 经典实例日常收集整理(常用经典)
Mar 30 Javascript
Element-UI踩坑之Pagination组件的使用
Oct 29 Javascript
Vue路由前后端设计总结
Aug 06 Javascript
Node.js HTTP服务器中的文件、图片上传的方法
Sep 23 Javascript
layui: layer.open加载窗体时出现遮罩层的解决方法
Sep 26 Javascript
JavaScript日期工具类DateUtils定义与用法示例
Sep 03 #Javascript
Angular5中状态管理的实现
Sep 03 #Javascript
JavaScript创建对象方法实例小结
Sep 03 #Javascript
vue自定义底部导航栏Tabbar的实现代码
Sep 03 #Javascript
解决vue单页路由跳转后scrollTop的问题
Sep 03 #Javascript
webpack4 SCSS提取和懒加载的示例
Sep 03 #Javascript
vue自定v-model实现表单数据双向绑定问题
Sep 03 #Javascript
You might like
PHP 数据库树的遍历方法
2009/02/06 PHP
Yii实现单用户博客系统文章详情页插入评论表单的方法
2015/12/28 PHP
Linux php 中文乱码的快速解决方法
2016/05/13 PHP
自适应高度框架 ----属个人收藏内容
2007/01/22 Javascript
基于jQuery的倒计时实现代码
2012/05/30 Javascript
删除select中所有option选项jquery代码
2013/08/12 Javascript
常用的Javascript数据验证插件
2015/08/04 Javascript
使用jquery提交form表单并自定义action的方法
2016/05/25 Javascript
基于JS实现无缝滚动思路及代码分享
2016/06/07 Javascript
js通过keyCode值判断单击键盘上某个键,然后触发指定的事件方法
2017/02/19 Javascript
浅谈angularjs依赖服务注入写法的注意点
2017/04/24 Javascript
详解关于Vue2.0路由开启keep-alive时需要注意的地方
2018/09/18 Javascript
AngularJS实现的鼠标拖动画矩形框示例【可兼容IE8】
2019/05/17 Javascript
Vue实现穿梭框效果
2020/09/30 Javascript
Python中你应该知道的一些内置函数
2017/03/31 Python
python 计算两个日期相差多少个月实例代码
2017/05/24 Python
Python基础教程之浅拷贝和深拷贝实例详解
2017/07/15 Python
详解Python里使用正则表达式的ASCII模式
2017/11/02 Python
Python OpenCV 直方图的计算与显示的方法示例
2018/02/08 Python
python实现nao机器人身体躯干和腿部动作操作
2019/04/29 Python
python如何通过twisted搭建socket服务
2020/02/03 Python
Python实现新型冠状病毒传播模型及预测代码实例
2020/02/05 Python
python接口自动化之ConfigParser配置文件的使用详解
2020/08/03 Python
Html5写一个简单的俄罗斯方块小游戏
2019/12/03 HTML / CSS
英国Flybe航空官网:欧洲最大的独立支线廉价航空公司
2019/07/15 全球购物
新西兰第一的行李箱网站:luggage.co.nz
2019/07/22 全球购物
资深财务管理人员自我评价
2013/09/22 职场文书
服装采购员岗位职责
2014/03/15 职场文书
新农村建设典型材料
2014/05/31 职场文书
2014超市收银员工作总结
2014/11/13 职场文书
毕业酒会致辞
2015/07/29 职场文书
2016大学生毕业实习心得体会
2016/01/23 职场文书
Vue3.0写自定义指令的简单步骤记录
2021/06/27 Vue.js
Go Plugins插件的实现方式
2021/08/07 Golang
德劲DE1102数字调谐收音机机评
2022/04/07 无线电
win11自动弹出虚拟键盘怎么关闭? Win11关闭虚拟键盘的技巧
2023/01/09 数码科技