1. 指令概述
(1)Vue框架中的所有指令的名字都以”v-“开始。指令的职责是,当表达式的值改变时,将其产生的连带影响,响应的作用于DOM
(2)Vue框架中的指令都是以HTML标签的属性形式存在的,指令对于浏览器是无法看懂的,需要先让Vue框架进行编译,编译之后浏览器才可以看懂。
<span 指令写在这里></span>
(3)指令的语法规则
<HTML标签 v-指令名:参数="表达式"></HTML标签>
①表达式:在插值语法在{{}}可以写的,在指令表达式都可以写(指令中不用加{{}})
②不是所有的指令都有参数和表达式,有的指令不需要参数也不需要表达式:如v-once。
v-once:只渲染元素一次,随后的重新渲染,元素及其所有的子元素将被视为静态内容并跳过,可以用于优化性能。
(4)什么时候使用插值语法,什么时候使用指令?
①凡是标签体当中的内容想要动态,需要使用插值语法
②想让HTML标签的属性动态,需要使用指令语法
2.常用指令的分类
指令(Directives)是 vue 为开发者提供的模板语法,用于辅助开发者渲染页面的基本结构。vue 中的指令按照不同的用途可以分为如下 6 大类:
2.1 内容渲染指令
内容渲染指令用来辅助开发者渲染 DOM 元素的文本内容。常用的内容渲染指令有如下 3 个:
2.1.1 v-text
<!-- 1.导入vue的库文件,在window全局就有了Vue这个构造函数 --> <script src="./lib/vue-2.6.12.js"></script> <!-- 2.创建Vue的实例对象 --> <script> // 创建Vue的实例对象 const vm = new Vue({ // el属性是固定的写法,表示当前vm实例要控制页面上的哪个区域,接收的值是一个选择器 el: '#app', // data对象就是要渲染到页面上的数据 data: { username: 'zhangsan' gender: 'nan' } }) </script>
2.1.2 插值语法{{ }}
2.1.2.1 插值语法{{}}可以写什么
(1)在data中声明的
(2)常量
(3)合法的JavaScript表达式
(4)模板表达式都被放在沙盒中,只能访问全局变量的一个白名单,如 Math 和 Date
<body> <div id="app"> <!-- data中声明的 --> <div>{{msg}}</div> <div>{{age}}</div> <!-- 常量 --> <div>{{1313}}</div> <!-- 合法的JavaScript表达式 --> <div>{{1+1}}</div> <!-- 模板表达式都被放在沙盒中,只能访问全局变量的一个白名单,如 Math 和 Date --> <h1>{{Date.now()}}</h1> </div> <script> // 创建vue实例 const myVue = new Vue({ data: { age: 28, msg: 'agvc' }, el: '#app' }) // myVue.$mount('#app') </script> </body>
2.1.2.2 插值语法可以解决什么
vue 提供的 {{ }} 语法,专门用来解决 v-text 会覆盖默认文本内容的问题。这种 {{ }} 语法的专业名称是插值表达
式
2.1.3 v-html
v-text 指令和插值表达式只能渲染纯文本内容。如果要把包含 HTML 标签的字符串渲染为页面的 HTML 元素,
则需要用到 v-html 这个指令:
<p v-html="info"></p> const vm = new Vue({ // el属性是固定的写法,表示当前vm实例要控制页面上的哪个区域,接收的值是一个选择器 el: '#app', // data对象就是要渲染到页面上的数据 data: { info: '<h1 style="color: red">欢迎学习vue</h1>' } })
2.2 属性绑定指令(v-bind)
(1)v-bind指令是干嘛的?
它可以让HTML标签的某个属性的值产生动态的效果
(2)v-bind指令的语法格式:
<HTML标签 v-bind:参数="表达式"></HTML标签>
(3)v-bind指令的编译原理
①编译前:<HTML标签 v-bind:参数="表达式"></HTML标签>
②编译后:<HTML标签 参数="表达式"></HTML标签>
③注意两项:
a.在编译的时候v-bind后面的”参数名“会被编译为HTML标签的”属性名“
b.表达式会关联data,当data发生改变之后,表达式的执行结果就会发生变化。连带的就会产生动态效果
(3)由于 v-bind 指令在开发中使用频率非常高,因此,vue 官方为其提供了简写形式(简写为英文的 : )
2.3 事件绑定指令(v-on)
(1)vue 提供了 v-on 事件绑定指令,用来辅助程序员为 DOM 元素绑定事件监听。语法格式如下:
<div id="app"> <p>count的值是:{{ count }}</p> <button v-on:click="add">+1按钮</button> <div> const vm = new Vue({ el: '#app', data: { count: 0 }, methods: { add() { this.count += 1
注意:原生 DOM 对象有 onclick、oninput、onkeyup 等原生事件,替换为 vue 的事件绑定形式后,
分别为:v-on:click、v-on:input、v-on:keyup
(2)由于 v-on 指令在开发中使用频率非常高,因此,vue 官方为其提供了简写形式(简写为英文的 @ )
(3)事件参数对象
在原生的 DOM 事件绑定中,可以在事件处理函数的形参处,接收事件参数对象 event。同理,在 v-on 指令
(简写为 @ )所绑定的事件处理函数中,同样可以接收到事件参数对象 event,示例代码如下:
(4)绑定事件并传参
在使用 v-on 指令绑定事件时,可以使用 ( ) 进行传参,示例代码如下:
(5)$event
$event
是 vue 提供的特殊变量,用来表示原生的事件参数对象 event。$event
可以解决事件参数对象 event
被覆盖的问题。示例用法如下:
(6)事件修饰符
vue 提供了事件修饰符的概念,来辅助程序员更方便的对事件的触发进行控制。常用的 5 个事件修饰符如下:
①.stop:停止事件冒泡,等同于event.stopProagation()
<body> <div id="app"> <!-- 停止事件冒泡 --> <div @click="san"> <div @click="er"> // 如果不加会出现1 2 3,加了就只显示1 <button @click.stop="yi">事件冒泡</button> </div> </div> </div> <script> const vm = new Vue({ el: '#app', data: { msg:'事件修饰符' }, methods: { yi(){ alert(1) }, er(){ alert(2) }, san(){ alert(3) } } }) </script> </body>
②.prevent:等同于event.preventDefault() 阻止事件的默认行为
<body> <div id="app"> <h1>{{msg}}</h1> // 使用 .prevent 后就不会跳转到百度页面了 <a href="https://www.baidu.com" @click.prevent="yi">百度</a> </div> <script> const vm = new Vue({ el: '#app', data: { msg:'事件修饰符' }, methods: { yi(){ alert('去百度') } } }) </script> </body>
③.capture:添加事件监听器时使用事件捕获模式
添加事件监听器包括两种不同的方式:
a.从内到外添加(事件冒泡模式):下面例子打印 1、2、3
b.从外到内添加(事件捕获模式):下面例子打印 3、2、1
<body> <div id="app"> <!-- 添加事件监听器时使用事件捕获模式 --> <div @click.capture="san"> <div @click.capture="er"> <button @click.capture="yi">添加事件监听器时使用事件捕获模式</button> </div> </div> </div> <script> const vm = new Vue({ el: '#app', methods: { yi(){ alert(1) }, er(){ alert(2) }, san(){ alert(3) } } }) </script> </body>
(4).self:这个事件如果是“我自己身上的元素”发生的事件,不是别人传递过来的,则执行相应的程序
<body> <div id="app"> <div @click="san"> // 此时2就不会显示出来 <div @click.self="er"> <button @click="yi">使用.self</button> </div> </div> </div> <script> const vm = new Vue({ el: '#app', methods: { yi(){ alert(1) }, er(){ alert(2) }, san(){ alert(3) } } }) </script> </body>
(5).once:事件只发生一次
2.4 双向绑定指令(v-model)
(1)vue 提供了 v-model 双向数据绑定指令,用来辅助开发者在不操作 DOM 的前提下,快速获取表单的数据。
(2)注意:表单和Vue中data的数据,任一发生改变都会同步发生变化
2.4.1 v-bind和v-model的区别和联系
(1)v-bind和v-model这两个指令都可以完成数据绑定
(2)v-bind是单向数据绑定:data ==>视图
;v-model是双向数据绑定:data <==> 视图
(3)v-bind可以使用在任何HTML标签当中;v-model只能使用在表单元素上,例如:input标签、select标签。v-model有这个限制是因为只有表单类的元素才能给用户提供交互输入的界面
(4)v-bind和v-model都有简写方式:
①v-bind:参数="表达式"
简写为 :参数="表达式"
②v-model:value="表达式"
简写为 v-model="表达式"
2.5 条件渲染指令
2.5.1 v-if
(1)v-if指令的值:true/false
①true:表示该元素会被渲染到页面上
②false:表示该元素不会被渲染到页面上
<body> <div id="app"> <div v-if="false">{{msg}}</div> </div> <script> const vm = new Vue({ el: '#app', data: { msg: 'Class绑定之字符串形式', } }) </script> </body>
2.5.2 v-else
为了提高效率,可以配合 v-if使用v-else
2.5.3 v-else-if
(1)充当 v-if 的“else-if 块”,可以连续使用
(2)v-if和v-show如何选择
①如果一个元素在页面被频繁的隐藏和显示,建议使用v-show,因为v-if的开销比较大
②v-if的优点:页面加载速度快,提高了页面的渲染效率
2.5.4 v-show
跟v-if用法一样
2.6 列表渲染指令(v-for)
(1)v-for要写在循环项上
(2)v-for的语法规则:
v-for=“变量名 in/of 数组”(变量名代表了数组中的每一个元素)
(3)v-for 还支持一个可选的第二个参数,即当前项的索引。
(item, index) in items
(4)一般会遍历对象
<body> <ul id="app"> <li v-for="item in vips"> 会员名:{{item.name}},年龄:{{item.age}} </li> </ul> <script> const vm = new Vue({ el: '#app', data: { vips: [ { name: 'jack', age: 20 }, { name: 'lucy', age: 22 }, { name: 'tom', age: 18 } ] } }) </script> </body>
2.6.1 v-for指令的 :key属性
(1)在v-for指令所在的标签中,还有一个非常重要的属性 :key
(2)如果没有指定 :key属性,会自动拿index作为key,这个key是这个dom元素的唯一标识
(3)如果采用index作为key会存在什么问题
①效率低
②产生错乱,尤其是对数组当中非末尾元素进行操作(例如列表中已经选中了一些,又新增了列表元素)
3.其他指令
3.1 v-cloak
v-cloak 配置 css 样式来解决胡子的闪现问题。
v-cloak 指令使用在标签当中,当Vue实例接管之后会删除这个指令。
这是一段CSS样式:当前页面中所有带有v-cloak属性的标签都隐藏起来。
<style> [v-cloak] { display : none; } </style>
3.2 v-once
初次接触指令的时候已经学过了。只渲染一次。之后将被视为静态内容。
3.3 v-pre
使用该指令可以提高编译速度。带有该指令的标签将不会被编译。可以在没有Vue语法规则的标签中使用
可以提高效率。不要将它用在带有指令语法以及插值语法的标签中。
4.自定义指令
(1)函数式方式
<body> <div id="app"> <h1 v-text-danger="msg">test</h1> </div> <script> const vm = new Vue({ el: '#app', data: { msg:'自定义指令', }, directives:{ // 指令1 // 指令2 // ... // 关于指令的名字: // (1)v- 不需要写 // (2)Vue官方建议指令的名字要全部小写,如果是多个单词的话,使用 - 进行衔接 // 这个回调函数的执行时机包括两个:1.标签和指令第一次绑定的时候 2.模板被重新解析的时候 // 这个回调函数有两个参数:第一个参数:真实的dom元素 第二个元素:标签与指令之间绑定关系的对象 'text-danger':function(element,binding){ element.innerText = binding.value element.style.color = 'red' } } }) </script> </body>
(2)对象式方式
directives: { // 对象式 'bind-blue': { // 这个对象中的三个方法的名字不能随便写,这个三个函数将来都会自动被调用 // 元素与指令初次绑定的时候,会自动调用bind // 注意:在特定的时间节点调用特定的函数,这种被调用的函数称为钩子函数 bind(element, binding) { element.value = binding.value }, // 元素被插入到页面之后,这个函数自动被调用 inserted(element, binding) { element.parentNode.style.backgroundColor = 'blue' }, // 当模板重新解析的时候,这个函数会被自动调用 update(element, binding) { element.value = binding.value } }
5.template
template标签/元素只是起到占位的作用,不会真正的出现在页面上,也不会影响页面的结构