以下笔记皆基于 Vue 2
指令是本身是给框架识别的一种标记,可以指示框架快速对元素进行处理,减少 DOM 操作,而 Vue.js 指令的本质就是以 v- 开头的 HTML 自定义属性。
内容处理
v-once 指令
使元素内部的插值表达式值生效一次。
<body>
<div id="app">
<p>此内容会随数据变化而自动变化:{{ content }}</p>
<p v-once>此内容不会随数据变化而自动变化: {{ content }}</p>
</div>
<script src="lib/vue.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
content: '内容文本'
}
})
</script>
</body>
v-text 指令
元素内容整体替换为指定纯文本数据。与插值表达式不同的是,v-text 指令会覆盖整个元素的原始内容,其底层调用的是 textContent 属性。
属性。
<body>
<div id="app">
<p v-text="content">这是 p 标签的原始内容</p>
</div>
<script src="lib/vue.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
content: '内容文本',
}
});
</script>
</body>
v-html 指令
元素内容整体替换为指定的 HTML 文本。和 v-text 类似,该指令会覆盖整个元素的原始内容。
<body>
<div id="app">
<p v-html="content">这是默认的文本内容</p>
</div>
<script src="lib/vue.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
content: '<span>span的内容</span>'
}
});
</script>
</body>
属性绑定
v-bind 指令
v-bind 指令用于动态绑定 HTML 属性,同时 Vue.js 还为 v-bind 指令提供了简写方式。也与插值表达式类似,v-bind 中也允许使用表达式。
<body>
<div id="app">
<p v-bind:title="myTitle">p标签的内容</p>
<!-- 简化写法 -->
<p :title="myTitle">p标签的内容</p>
<!-- 使用表达式 -->
<p :class="'num' + 1 + 2 + 3">p标签的内容</p>
<p :class="prefix + num"></p>
</div>
<script src="lib/vue.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
myTitle: '这是title的内容',
prefix: 'demo',
num: 10
}
});
</script>
</body>
如果需要一次绑定多个属性,还可以绑定对象。
<body>
<div id="app">
<p v-bind="attrObj">这是 p 标签的内容</p>
</div>
<script src="lib/vue.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
attrObj: {
id: 'box',
title: '示例内容', // 固有属性
class: 'clearFix', // 固有属性
'data-title': '这是 data-title 的内容' // 自定义属性
}
}
});
</script>
</body>
class 绑定
class 是 HTML 属性,可以通过 v-bind 进行绑定,并且可以与 class 属性共存。
<body>
<div id="app">
<p v-bind:class="cls">标签内容</p>
<p class="a" :class="cls">标签内容</p>
</div>
<script src="lib/vue.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
cls: 'x',
}
});
</script>
</body>
对于 class 绑定, Vue.js 中还提供了特殊处理方式:
- 对象结构,对象结构中,键作为类名(带
-
类名可以用''
包裹),值使用布尔值判断类名是否生效,对象中可以同时书写多个类名:<body> <div id="app"> <p :class="{ b: isB, c: isC, 'class-d': true }"></p> </div> <script src="lib/vue.js"></script> <script> var vm = new Vue({ el: '#app', data: { isB: true, isC: false } }); </script> </body>
- 数组结构,该方式同样可以设置多个类名,并且可以在数组内设置固定的类名,以及需要条件判断的类名:
<body> <div id="app"> <p :class="[ 'a', {b: isB}, 'c' ]"></p> </div> <script src="lib/vue.js"></script> <script> var vm = new Vue({ el: '#app', data: { isB: true, } }); </script> </body>
style 绑定
style 是 HTML 属性,可以通过 v-bind 进行绑定,并且可以与 style 属性共存,需要传入对象形式的值。键表示样式属性名,可以使用传统命名法或者驼峰命名法;值表示样式属性值,样式单位不能省略。
<body>
<div id="app">
<p :style="styleObj">标签内容</p>
<!-- 以绑定的 width 值为准,即最后宽度为 200px -->
<p style="width: 100px" :style="styleObj">标签内容</p>
</div>
<script src="lib/vue.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
styleObj: {
width: '200px',
height: '200px',
border: '1px solid #ccc',
backgroundColor: 'red',
'font-size': '30px'
}
}
});
</script>
</body>
当我们希望给元素绑定多个样式对象时,可以设置为数组。
<body>
<div id="app">
<p :style="[baseStyle, styleObj1]">第一个 p 标签</p>
<p :style="[baseStyle, styleObj2]">第二个 p 标签</p>
</div>
<script src="lib/vue.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
// 公共样式
baseStyle: {
width: '100px',
height: '100px'
},
styleObj1: {
backgroundColor: 'red'
},
styleObj2: {
backgroundColor: 'blue'
}
}
});
</script>
</body>
渲染指令
v-for指令
用于遍历数据渲染结构,常用的数组与对象均可遍历,还可以进行值的处理,通过()
内声明多个标识符以获得索引或者键。
<body>
<div id="app">
<ul>
<li v-for="item in arr">元素内容为:{{ item }}</li>
<li v-for="(item, index) in arr">
元素内容为:{{ item }}, 索引为:{{ index }}
</li>
<li v-for="value in obj">元素内容为:{{ value }}</li>
<li v-for="(value, key, index) in obj">
元素内容为: {{ value }}, 键为: {{ key }}, 索引值为: {{ index }}
</li>
</ul>
<ul>
<!-- 从 1 开始遍历到 5 -->
<li v-for="(item, index) in 5">
这是第{{ item }}个元素,索引值为:{{ index }}
</li>
</ul>
</div>
<script src="lib/vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
arr: ['内容1', '内容2', '内容3']
obj: {
content1: '内容1',
content2: '内容2',
content3: '内容3'
}
}
});
</script>
</body>
v-for 的默认行为会尝试原地修改元素而不是移动它们,所以想要强制其重新排序元素,应始终指定唯一的 key 属性,可以提高渲染性能并避免问题。
<body>
<div id="app">
<ul>
<li v-for="(item, index) in itemList" :key="item.id">
输入框{{ item.value }}: <input type="text">
</li>
</ul>
</div>
<script src="lib/vue.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
arr: [1, 2, 3],
itemList: [
{ id: 1, value: 2 },
{ id: 2, value: 3 },
{ id: 3, value: 3 }
]
}
})
</script>
</body>
通过 <template> 标签设置模板占位符,可以将部分元素或内容作为整体进行操作,<template> 不是一个真实的元素标签,它只是一个占位符,在 DOM 上是不存在的。
<body>
<div id="app">
<template v-for="item in obj">
<span>{{ item }}</span>
<br>
</template>
</div>
<script src="lib/vue.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
obj: {
content1: '内容1',
content2: '内容2',
content3: '内容3'
}
}
})
</script>
</body>
v-show 指令
v-show 用于控制元素显示与隐藏,适用于显示隐藏频繁切换时使用。
注意:因为v-show 的本质是给元素添加 display:none 样式属性,因此<template> 无法使用 v-show 指令。
<body>
<div id="app">
<!-- 布尔值表示显示隐藏 -->
<p v-show="false">标签内容</p>
<!-- 布尔值表达式 -->
<p v-show="22 > 11">标签内容</p>
<!-- 绑定值 -->
<p v-show="bool">标签内容</p>
<!-- v-show 没有效果 -->
<template v-show='false'>这是内容</template>
</div>
<script src="lib/vue.js"></script>
<script>
var vm = new Vue({
el: "#app",
data: {
bool: true
}
});
</script>
</body>
v-if 指令
v-if 用于根据条件控制元素的创建与移除。
<div>
<p v-if="false">这个元素不会创建</p>
<p v-else-if="true">这个元素会创建</p>
<p v-else>这个元素不会创建</p>
</div>
如果使用 v-if 的元素是同类型元素,则需要绑定不同的 key,原因和 v-for 类似。
<body>
<div id="app">
<!-- 绑定 key 确保输入框也创建和移除 -->
<div v-if="type==='username'" :key="'username'">
用户名输入框:<input type="text">
</div>
<div v-else :key="'email'">
邮箱输入框:<input type="text">
</div>
</div>
<script src="lib/vue.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
bool: true,
type: 'username'
}
});
</script>
</body>
出于性能考虑,应避免将 v-if 与 v-for 应 用于同一标签,因为 v-for 的渲染优先级要高于 v-if,因此在会先遍历生成元素,再执行判断创建或移除,影响渲染效率。可以将 v-if 放在父级,v-for 放在子级,以提高渲染效率。
<body>
<div id="app">
<ul v-if="false">
<li v-for="item in items">{{item}}</li>
</ul>
</div>
<script src="lib/vue.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
items: {
content1: '内容1',
content2: '内容2',
content3: '内容3'
}
}
});
</script>
</body>