一、常用指令
1. 内容渲染指令
{{ }}
v-text
v-html
<template>
<div>
<!-- 1. 插值表达式 -->
<h1> {{ message1 }}</h1>
<!-- 2. 渲染字符串,不可以渲染 html 标签 -->
<h1 v-text="message2"></h1>
<!-- 3. 渲染字符串,可以渲染 html 标签 -->
<h1 v-html="message3"></h1>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
data() {
return {
message1: 'Hello Vue!【1】',
message2: '<h1>Hello Vue!【】</h1>',
message3: '<h1>Hello Vue!【3】</h1>',
}
}
}
</script>
2. 属性绑定指令
v-bind:XXX
:XXX
<template>
<div>
<!-- 1. 使用 "v-bind:" 为属性进行动态绑定 -->
<h3><a v-bind:href="href"> {{ text }} </a></h3>
<hr/>
<hr/>
<!-- 2. 可以使用简写 ":" 为属性进行动态绑定 -->
<h3><a :href="href"> {{ text }} </a></h3>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
data() {
return {
text: '我是 text 文本',
href: 'https://www.jd.com'
}
}
}
</script>
3. 条件渲染指令
v-if
v-else-if
v-else
v-show
<template>
<div>
<div id="if">
<h1 v-if="num > 10">num 大于 10</h1>
<h1 v-else-if="num > 5">num 大于 5,小于等于 10</h1>
<h1 v-else>num 小于等于 5</h1>
</div>
<hr/>
<div id="show">
<h1 v-show="isShow">Hello,World【1】</h1>
<h1 v-show="!isShow">Hello,World【2】</h1>
</div>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
data() {
return {
num: 5,
isShow: true,
}
}
}
</script>
4. 列表渲染指令
v-for
:key
<template>
<ul>
<!--
- 避免出现错误,强烈建议使用子元素的唯一标识(通常是 id 值)来充当每个 DOM 元素的唯一 key
- 遍历列表的两种语法:"(item, index) in list" 或者 "item in list"
- 使用 index 作为每个 DOM 元素的唯一 key 是不明智的,因为随着元素顺序的改变,index 的意义也会发生变化,可能会出错
-->
<li v-for="(fruit, index) in fruits" :key="fruit.id">
{{ index + ' : ' + fruit.name }}
</li>
</ul>
</template>
<script>
export default {
name: 'HelloWorld',
data() {
return {
fruits: [
{id: 1, name: 'apple'},
{id: 2, name: 'watermelon'},
{id: 3, name: 'banana'},
{id: 4, name: 'strawberry'},
]
}
}
}
</script>
5. 事件绑定指令
v-on:
@
(1)绑定事件
<template>
<div>
<h1>{{'总数为:' + count }}</h1>
<!-- 1. 使用 "v-on:" 指令绑定点击事件,这里的回调函数没有传递参数,默认会传递事件对象作为参数 -->
<button v-on:click="add">点击总数增加</button>
<!-- 2. 使用 "@" 简写绑定点击事件,传递了一个指定参数,也可以通过 "$event" 传递事件对象 -->
<button @click="sub(9, $event)">点击总数减少</button>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
data() {
return {
count: 0,
}
},
methods: {
// 3. 回调函数没有传递参数的话,默认情况下事件对象作为参数传递
add(event) {
this.count += 5;
console.log('事件对象参数:', event)
},
// 4. 回调函数有了参数,也可以通过 $event 来传递事件对象作为参数
sub(num, event) {
this.count -= num;
console.log('事件对象参数:', event)
},
}
}
</script>
(2)事件的修饰符
<template>
<div>
<!-- 1. 给 keyup 事件添加修饰符,只有按下 esc 键时才触发改事件 -->
按下 esc 键时触发:<input type="text" @keypress.esc="clearAll">
<hr/>
<!-- 2. 给 keyup 事件添加修饰符,只有按下 enter 键时才触发改事件 -->
按下 enter 键时触发:<input type="text" @keyup.enter="submitAll">
<hr/>
<!-- 3. 给 click 事件添加修饰符,取消默认行为 -->
取消默认行为:<a href="https://www.taobao.com" @click.prevent="toTaobao">点击跳转到淘宝</a>
<hr/>
<!-- 4. 给 click 事件添加修饰符,阻止冒泡、默认行为【可以连续书写修饰符】 -->
阻止冒泡、默认行为:<button @click.stop.prevent="stopPop">阻止冒泡行为、默认行为</button>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
methods: {
clearAll() {
alert('按下了 esc 键,清空所有的输入')
},
submitAll() {
alert('按下了 enter(回车) 键,提交所有的输入')
},
toTaobao() {
alert('阻止了跳转到淘宝页面的行为');
},
stopPop() {
alert('阻止冒泡行为、默认行为');
},
}
}
</script>
6. 数据双向绑定指令
v-model:value
v-model
收集表单元素的 value 值
(1)基本用法
<template>
<div>
<!-- 1. 普通的数据双向绑定(未简写格式) -->
<p>{{ msgString1 }}</p>
<input type="text" v-model="msgString1">
<!-- 2. 普通的数据双向绑定(简写格式) -->
<p>{{ msgString2 }}</p>
<input type="text" v-model="msgString2">
<!-- 3. 使用 number 修饰符将输入的字符串数据转化为 number 数据 -->
<p>{{ num + ' + 6 = ' + (num + 6) }}</p>
<input type="text" v-model.number="num">
<!-- 4. 使用 trim 修饰符去除数据两边的空格 -->
<p>{{ '数据的长度为: ' + trimString.length }}</p>
<input type="text" v-model.trim="trimString">
<!-- 5. 使用 lazy 修饰符使得在 change 状态时更新数据,而不是 input 状态更新数据 -->
<p>{{ lazyString }}</p>
<input type="text" v-model.lazy="lazyString">
</div>
</template>
<script>
export default {
name: 'HelloWorld',
data() {
return {
msgString1: 'msgString1',
msgString2: 'msgString2',
num: 0,
trimString: 'trimString',
lazyString: 'lazyString',
}
}
}
</script>
(2)文本、多行文本
<template>
<div>
<p>{{ msgString1 }}</p>
<input type="text" v-model="msgString1">
<hr>
<p>{{ msgString2 }}</p>
<textarea v-model="msgString2"></textarea>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
data() {
return {
msgString1: 'msgString1',
msgString2: 'msgString2'
}
}
}
</script>
(3)单个复选框
<template>
<div>
<input type="checkbox" id="checkbox1" v-model="checked1">
<label for="checkbox1">{{ '当前的 checked1 值为:' + checked1 }}</label>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
data() {
return {
checked1: true
}
}
}
</script>
(4)多个复选框
<template>
<div>
<input type="checkbox" id="checkbox1" value="001" v-model="myArr">
<label for="checkbox1">选项1</label> <br>
<input type="checkbox" id="checkbox2" value="002" v-model="myArr">
<label for="checkbox2">选项2</label> <br>
<input type="checkbox" id="checkbox3" value="003" v-model="myArr">
<label for="checkbox3">选项3</label> <br>
<hr>
<span>已经选择的选项为:{{ myArr }}</span>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
data() {
return {
myArr: [],
}
}
}
</script>
(5)单个、多个单选按钮
<template>
<div>
<input type="radio" id="one" value="001aaa" v-model="picked">
<label for="one">One</label>
<br>
<input type="radio" id="two" value="002aaa" v-model="picked">
<label for="two">Two</label>
<br>
<span> 选择的是 : {{ picked }}</span>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
data() {
return {
picked: '',
}
}
}
</script>
(6)单选下拉选择框
如果
v-model
表达式的初始值未能匹配任何选项,<select>
元素将被渲染为“未选中”状态。在 iOS 中,这会使用户无法选择第一个选项。因为这样的情况下,iOS 不会触发 change 事件。因此推荐像下面这样提供一个值为空的禁用选项。
<template>
<div>
<select v-model="selected">
<option disabled value="">请选择</option>
<option value="001">A</option>
<option value="002">B</option>
<option value="003">C</option>
</select>
<br>
<span>选择的是: {{ selected }}</span>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
data() {
return {
selected: '',
}
}
}
</script>
(7)多选下拉选择框
<template>
<div>
<select v-model="selected" multiple>
<option disabled value="">请选择</option>
<option value="001">A</option>
<option value="002">B</option>
<option value="003">C</option>
</select>
<br>
<span>选择的是: {{ selected }}</span>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
data() {
return {
selected: [],
}
}
}
</script>
7. class 属性绑定的指令
:class
(1)字符串格式
<template>
<div>
<!-- 可以与普通的 class 共存 -->
<p class="basic" :class="myClassVar">Hello</p>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
data() {
return {
myClassVar: 'a b',
}
}
}
</script>
<style scoped>
.basic {
font-size: 26px;
}
.a {
color: red;
}
.b {
background-color: pink;
}
</style>
(2)数组格式
<template>
<div>
<!-- 可以与普通的 class 共存 -->
<p class="basic" :class="myClassVar">Hello</p>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
data() {
return {
myClassVar: ['a', 'b'],
}
}
}
</script>
<style scoped>
.basic {
font-size: 26px;
}
.a {
color: red;
}
.b {
background-color: pink;
}
</style>
(3)对象格式
<template>
<div>
<!-- 可以与普通的 class 共存 -->
<p class="basic" :class="myClassVar">Hello</p>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
data() {
return {
myClassVar: {
a: true, // 使用该类名
b: false, // 不使用该类名
},
}
}
}
</script>
<style scoped>
.basic {
font-size: 26px;
}
.a {
color: red;
}
.b {
background-color: pink;
}
</style>
8. style 属性绑定的指令
:style
(1)对象格式
<template>
<div>
<p class="basic" :style="{fontSize: '36px', color: 'green',}">Hello</p>
<p class="basic" :style="styleObj">Hello</p>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
data() {
return {
styleObj: {
color: 'pink',
fontSize: '39px',
},
}
}
}
</script>
(2)数组格式
<template>
<div>
<p class="basic" :style="[styleObj1, styleObj2]">Hello</p>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
data() {
return {
styleObj1: {
color: 'pink',
backgroundColor: 'skyblue',
},
styleObj2: {
fontSize: '39px',
},
}
}
}
</script>
9. v-once 指令
v-once
v-once
所在节点在初次动态渲染之后,就被当作静态内容了,以后的变化不会引起结构的更新,保证当前的响应式数据不会被动态的修改
<template>
<div>
<input v-model="username">
<p v-once>{{ username }}</p>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
data() {
return {
username: 'bugu',
}
}
}
</script>
10. v-pre 指令
v-pre
跳过没有使 vue 相关语法指令的节点,加快编译过程
<template>
<div>
<p>{{ username }}</p>
<p v-pre>哈哈哈</p>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
data() {
return {
username: 'bugu',
}
}
}
</script>
二、自定义指令
当 Vue 的指令满足不了需求时,可以自己写指令
在自定义指令的函数里面的 this 是 window,不是 vue 实例,所以如果使用了匿名函数,则建议采用箭头函数
1. 对象格式
<template>
<div>
<h1>原来的值:<span>{{ n }}</span></h1>
<h1>经过自定义指令 add8 解析后的值为:<span v-add8="n"></span></h1>
<h1>经过自定义指令 fbind 解析后的值为:<input type="text" v-fbind="n"></h1>
<button @click="n++">点我n+1</button>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
data() {
return {
n: 1,
}
},
directives: {
// 自定义指令"add10"的作用是:将数字增加 8
// - 第一个参数element:绑定自定义指令的对象
// - 第二个参数binding:自定义指令对象本身
// - 两个参数顺序不变,可以省略
add8(element, binding) {
console.log('绑定自定义指令的对象', element)
console.log('自定义指令对象本身', binding)
element.innerText = binding.value + 8;
},
fbind: {
// 指令与元素成功绑定时调用【第一次绑定调用,只会被调用一次】
bind(element, binding) {
console.log(111);
element.value = binding.value + '!';
},
// 指令所在元素被插入页面时
inserted(element) {
console.log(222);
element.focus();
},
// 指令所在模板被重新解析时【模板重新渲染时调用,但是第一次渲染时不会调用】
update(element, binding) {
console.log(333);
element.value = binding.value + '?';
}
}
}
}
</script>
2. 函数格式
对象格式过于复杂,可以化简为函数格式
<template>
<div>
<h1>原来的值:<span>{{ n }}</span></h1>
<h1>经过自定义指令 add8 解析后的值为:<span v-add8="n"></span></h1>
<button @click="n++">点我n+1</button>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
data() {
return {
n: 1,
}
},
directives: {
// 调用时机【仅针对函数格式】
// - 指令与元素成功绑定时
// - 指令所在的模板被重新解析时调用
// 第一个参数:指令所绑定的元素
// 第二个参数:自定义指令对象本身
add8(element, binding) {
element.innerText = binding.value + 8;
}
}
}
</script>
3. 全局的自定义指令
(1)注册自定义指令
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
// 函数格式
Vue.directive('add8', (element, binding) => {
element.innerText = binding.value + 8;
})
// 对象格式
Vue.directive('fbind', {
bind(element, binding) {
console.log(111);
element.value = binding.value + '!';
},
inserted(element) {
console.log(222);
element.focus();
},
update(element, binding) {
console.log(333);
element.value = binding.value + '?';
}
})
new Vue({
render: h => h(App),
}).$mount('#app')
(2)使用自定义指令
<template>
<div>
<h1>原来的值:<span>{{ n }}</span></h1>
<h1>经过自定义指令 add8 解析后的值为:<span v-add8="n"></span></h1>
<h1>经过自定义指令 fbind 解析后的值为:<input type="text" v-fbind="n"></h1>
<button @click="n++">点我n+1</button>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
data() {
return {
n: 1,
}
}
}
</script>