02vue指令-1
vue内部指令
指令 | 说明 | 简写 |
---|---|---|
mustache | 大括号语法 | { |
v-if | 条件判断,根据ture/false渲染元素 | |
v-else | 同上 | |
v-else-if | 同上 | |
v-show | 样式显示 | |
v-for | 遍历 | |
v-text | 插入覆盖文字内容 | |
v-html | 转义超链接 | |
v-on | 事件监听 | @ |
v-model | 双向绑定;复杂 | |
v-bind | 动态绑定;复杂 | : |
v-pre | 显示原始字符串,不转义 | |
v-once | 执行一次 | |
v-cloak | 披风,用于遮盖 |
1、Mustache语法
<div id="app">
<h2>{{message}}</h2>
<h2>{{message}},啧啧啧</h2>
<!-- Mustache的语法不仅可以直接写变量,还可以写简单表达式 -->
<h2>{{firstName + lastName}}</h2>
<h2>{{firstName + " " + lastName}}</h2>
<h2>{{firstName}}{{lastName}}</h2>
<h2>{{count * 2}}</h2>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
<script>
const app = new Vue({
el:"#app",
data:{
message:"你好啊",
firstName:"skt t1",
lastName:"faker",
count:100
}
})
</script>
2、v-once
v-once表示该dom元素只渲染一次,之后数据改变,不会再次渲染。
<div id="app">
<h2>{{message}}</h2>
<!-- 只会渲染一次,数据改变不会再次渲染 -->
<h2 v-once>{{message}}</h2>
</div>
3. v-html
在某些时候我们不希望直接输出[百度一下](http://www.baidu.com)
这样的字符串,而输出被html自己转化的超链接。此时可以使用v-html。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="app">
<h2>不使用v-html</h2>
<h2>{{ url }}</h2>
<h2>使用v-html,直接插入html</h2>
<h2 v-html="url"></h2>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const app = new Vue({
el:"#app",
data:{
url:"<a href='http://www.baidu.com'>百度一下</a>"
}
})
</script>
</body>
</html>
页面如下
4. v-text
v-text会覆盖dom元素中的数据,相当于js的innerHTML方法。
<body>
<div id="app">
<h2>不使用v-text</h2>
<h2>{{message}},啧啧啧</h2>
<h2>使用v-text,以文本形式显示,会覆盖</h2>
<h2 v-text="message">,啧啧啧</h2>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
<script>
const app = new Vue({
el:"#app",
data:{
message:"你好啊"
}
})
</script>
</body>
结果
5. v-pre
有时候我们期望直接输出{{message}}
这样的字符串,而不是被{{}}
语法转化的message的变量值,此时我们可以使用v-pre
标签。
<body>
<div id="app">
<h2>不使用v-pre</h2>
<h2>{{message}}</h2>
<h2>使用v-pre,不会解析</h2>
<h2 v-pre>{{message}}</h2>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
<script>
const app = new Vue({
el:"#app",
data:{
message:"你好啊"
}
})
</script>
</body>
结果如图,使用v-pre修饰的dom会直接输出字符串。
6、v-cloak 披风
有时候因为加载延时问题,例如卡掉了,数据没有及时刷新,就造成了页面显示从{{message}}
到message变量“你好啊”的变化,这样闪动的变化,会造成用户体验不好。此时需要使用到v-cloak
的这个标签。在vue解析之前,div属性中有v-cloak
这个标签,在vue解析完成之后,v-cloak标签被移除。简单,类似div开始有一个css属性display:none;
,加载完成之后,css属性变成display:block
,元素显示出来。
<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<title>v-cloak指令的使用</title>
<style>
[v-cloak]{
display: none;
}
</style>
</head>
<body>
<div id="app" v-cloak>
<h2>{{message}}</h2>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
<script>
//在vue解析前,div中有一个属性cloak
//在vue解析之后,div中没有一个属性v-cloak
setTimeout(() => {
const app = new Vue({
el: "#app",
data: {
message: "你好啊"
}
})
}, 1000);
</script>
</body>
</html>
这里通过延时1秒模拟加载卡住的状态,结果一开始不显示message的值,div元素中有v-cloak的属性,1秒后显示message变量的值,div中的v-cloak元素被移除。
7、v-for
对于一个数组或者字典元素可以用v-for遍历元素
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="app">
<h3>直接显示值</h3>
<ul>
<li v-for="item in items">
{{item}}
</li>
</ul>
<h3>显示index和值</h3>
<ul>
<li v-for="(index,item) in items">
{{item}} => {{index}}
</li>
</ul>
<h3>显示index、键、值</h3>
<ul>
<li v-for="(value, key, index) in object">
{{ index }} => {{ key }} => {{ value }}
</li>
</ul>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
<script>
const app = new Vue({
el: "#app",
data: {
items: ['葫', '芦', '娃', '救', '爷爷'],
object: {
firstName: '葫芦娃',
lastName: '爷爷',
}
}
})
</script>
</script>
</body>
</html>
结果:
8、v-if、 v-else-if、v-else、v-show
v-if用于条件判断,判断Dom元素是否显示。
<div v-if="isLogin">你好</div>
<div v-else>请登录后操作</div>
<div v-show="isLogin">你好</div>
<div v-if="type === 'A'">A</div>
<div v-else-if="type === 'B'">B</div>
<div v-else-if="type === 'C'">C</div>
<div v-else>Not A/B/C</div>
v-if与v-show的区别
v-show = false 相对于 display : none
- v-if: 在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建,开销较高,在运行时条件很少改变时使用。
- v-show:调整css dispaly属性,开销较小,在常频繁地切换时使用。
8.1、v-if的demo
在登录网站是经常可以选择使用账户名或者邮箱登录的切换按钮。要求点击按钮切换登录方式。
实现输入框的复用
<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id="app">
<span v-if="isUser">
<label for="username">用户账号</label>
<input type="text" id="username" placeholder="请输入用户名" >
</span>
<span v-else="isUser">
<label for="email">用户邮箱</label>
<input type="text" id="email" placeholder="请输入用户邮箱" >
</span>
<button @click="isUser=!isUser">切换类型</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
<script>
const app = new Vue({
el:"#app",
data:{
isUser:true
}
})
</script>
</body>
</html>
这里需要了解一下vue底层操作,此时input输入框值被复用了。
-
vue在进行DOM渲染是,处于性能考虑,会复用已经存在的元素,而不是每次都创建新的DOM元素。
-
在上面demo中,Vue内部发现原来的input元素不再使用,所以直接将其映射对应虚拟DOM,用来复用。
-
如果不希望出现类似复用问题,可以给对应的dom元素加上
key
值,并保证key
不同。<input type="text" id="username" placeholder="请输入用户名" key="username"> <input type="text" id="email" placeholder="请输入用户邮箱" key="email">
v-if 在首次渲染的时候,如果条件为假,什么也不操作,页面当作没有这些元素。当条件为真的时候,开始局部编译,动态的向DOM元素里面添加元素。当条件从真变为假的时候,开始局部编译,卸载这些元素,也就是删除。
v-show 不管条件是真还是假,第一次渲染的时候都会编译出来,也就是标签都会添加到DOM中。之后切换的时候,通过display: none;样式来显示隐藏元素。可以说只是改变css的样式,几乎不会影响什么性能。
9、v-bind (:)简写(语法糖)【动态绑定属性】https://cn.vuejs.org/v2/api/#v-bind
用于处理html标签的动态属性,即动态赋值。
常规写法
// html
<img v-bind:src="imgSrc" width="200px">
// js
data: {
imgSrc:'http://liangxinghua.com/uploads/image/20180709/1531106987.png'
}
说明
某些时候我们并不想将变量放在标签内容中,像这样<h2>{{message}}</h2>是将变量h2标签括起来,类似js的innerHTML。但是我们期望将变量imgURL写在如下位置,想这样<img src="imgURL" alt="">导入图片是希望动态获取图片的链接,此时的imgURL并非变量而是字符串imgURL,如果要将其生效为变量,需要使用到一个标签v-bind:,像这样<img v-bind:src="imgURL" alt="">,而且这里也不能使用Mustache语法,类似<img v-bind:src="{{imgURL}}" alt="">,这也是错误的。
<!-- 正确的做法使用v-bind指令 -->
<img v-bind:src="imgURL" alt="">
<a v-bind:href="aHerf"></a>
<!-- 语法糖写法 -->
<img :src="imgURL" alt="">
<a :href="aHerf"></a>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
<script>
const app = new Vue({
el:"#app",
data:{
imgURL:"https://cn.bing.com/th?id=OIP.NaSKiHPRcquisK2EehUI3gHaE8&pid=Api&rs=1",
aHerf:"http://www.baidu.com"
}
})
</script>
此时vue对象中定义的imgURL
变量和aHerf
变量可以动态的绑定到img标签的src属性和a标签的href属性。v-bind:
由于用的很多,vue对他有一个语法糖的优化写法也就是:
9.1 v-bind动态绑定class(对象语法)
有时候我们期望对Dom元素的节点的class进行动态绑定,选择此Dom是否有指定class属性。例如,给h2标签加上class="active",当Dom元素有此class时候,变红<style>.active{color:red;}</style>,在写一个按钮绑定事件,点击变黑色,再次点击变红色。
<body>
<div id="app">
<!-- <h2 class="active">{{message}}</h2>
<h2 :class="active">{{message}}</h2> -->
<!-- 动态绑定class对象用法 -->
<!-- <h2 :class="{key1:value1,key2:value2}">{{message}}</h2>
<h2 :class="{类名1:true,类名2:boolean}">{{message}}</h2> -->
<h2 class="title" :class="{active:isActive}">{{message}}</h2>
<h2 class="title" :class="getClasses()">{{message}}</h2>
<button @click="change">点击变色</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
<script>
const app = new Vue({
el:"#app",
data:{
message:"你好啊",
active:"active",
isActive:true
},
methods: {
change(){
this.isActive = !this.isActive
},
getClasses(){
return {active:this.isActive}
}
},
})
</script>
</body>
定义两个变量active
和isActive
,在Dom元素中使用:class={active:isActive}
,此时绑定的class='active'
,isActive为true,active显示,定义方法change()绑定在按钮上,点击按钮this.isActive = !this.isActive
,控制Dom元素是否有class='active'
的属性。
9.2 v-bind动态绑定class(数组语法)
<body>
<div id="app">
<!-- 加上单引号当成字符串 -->
<h2 class="title" :class="['active','line']">{{message}}</h2>
<!-- 不加会被当成变量 -->
<h2 class="title" :class="[active,line]">{{message}}</h2>
<h2 class="title" :class="getClasses()">{{message}}</h2>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
<script>
const app = new Vue({
el:"#app",
data:{
message:"你好啊",
active:"aaaa",
line:'bbbb'
},
methods: {
getClasses(){
return [this.active,this.line]
}
},
})
</script>
</body>
- 加上单引号的表示字符串
- 不加的会当成变量
- 可以直接使用方法返回数组对象
例子
<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<title>作业(v-for和v-bind的结合)</title>
<style>
.active{
color:red;
}
</style>
</head>
<body>
<div id="app">
<ul>
<li v-for="(item, index) in movies" :key="index" :class="{active:index===currentIndex}" @click="changeColor(index)" >{{index+"---"+item}}</li>
</ul>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
<script>
const app = new Vue({
el:"#app",
data:{
currentIndex:0,
movies:["海王","海贼王","火影忍者","复仇者联盟"]
},
methods: {
changeColor(index){
this.currentIndex = index
}
},
})
</script>
</body>
</html>
v-for时候的index索引,给每行绑定事件点击事件,点击当行是获取此行索引index并赋值给currentIndex
,使用v-bind:
绑定class,当index===currentIndex
Dom元素有active的class,颜色变红。
9.4 v-bind动态绑定style(对象语法)
<!-- <h2 :style="{key(属性名):value(属性值)}">{{message}}</h2> -->
<!-- 加单引号,当成字符串解析 -->
<h2 :style="{fontSize:'50px'}">{{message}}</h2>
<!-- 不加单引号,变量解析 -->
<h2 :style="{fontSize:fontSize}">{{message}}</h2>
<h2 :style="getStyle()">{{message}}</h2>
9.5 v-bind动态绑定style(数组语法)
<div id="app">
<h2 :style="[baseStyle]">{{message}}</h2>
<h2 :style="getStyle()">{{message}}</h2>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
<script>
const app = new Vue({
el:"#app",
data:{
message:"你好啊",
baseStyle:{backgroundColor:'red'}
},
methods: {
getStyle(){
return [this.baseStyle]
}
},
})
</script>
类似绑定class,绑定style也是一样的。
10、v-on 简写@
详情:https://cn.vuejs.org/v2/api/#v-on
绑定事件监听器。事件类型由参数指定。表达式可以是一个方法的名字或一个内联语句,如果没有修饰符也可以省略。
用在普通元素上时,只能监听原生 DOM 事件。用在自定义元素组件上时,也可以监听子组件触发的自定义事件。
在监听原生 DOM 事件时,方法以事件为唯一的参数。如果使用内联语句,语句可以访问一个 $event
property:v-on:click="handle('ok', $event)"
。
从 2.4.0
开始,v-on
同样支持不带参数绑定一个事件/监听器键值对的对象。注意当使用对象语法时,是不支持任何修饰器的。
10.1、修饰符
.stop
- 调用event.stopPropagation()
。.prevent
- 调用event.preventDefault()
。.capture
- 添加事件侦听器时使用 capture 模式。.self
- 只当事件是从侦听器绑定的元素本身触发时才触发回调。.{keyCode | keyAlias}
- 只当事件是从特定键触发时才触发回调。.native
- 监听组件根元素的原生事件。.once
- 只触发一次回调。.left
- (2.2.0) 只当点击鼠标左键时触发。.right
- (2.2.0) 只当点击鼠标右键时触发。.middle
- (2.2.0) 只当点击鼠标中键时触发。.passive
- (2.3.0) 以{ passive: true }
模式添加侦听器
<body>
<div id="app">
<!--1. .stop的使用,btn的click事件不会传播,不会冒泡到上层,调用event.stopPropagation() -->
<div @click="divClick">
<button @click.stop="btnClick">按钮1</button>
</div>
<!-- 2. .prevent 调用event.preeventDefault阻止默认行为 -->
<form action="www.baidu.com">
<button type="submit" @click.prevent="submitClick">提交</button>
</form>
<!--3. 监听键盘的事件 -->
<input type="text" @click.enter="keyup">
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
<script>
const app = new Vue({
el:"#app",
methods:{
btnClick(){
console.log("点击button");
},
divClick(){
console.log("点击div");
},
submitClcik(){
console.log("提交被阻止了")
},
keyup(){
console.log("keyup点击")
}
}
})
</script>
</body>
说明:
1 .stop的使用,btn的click事件不会传播,不会冒泡到上层,调用event.stopPropagation()。
2 .prevent 调用event.preeventDefault阻止默认行为。
3 .enter监听键盘事件
10.2 实例
一个简单的鼠标点击事件
<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
<title>Document</title>
</head>
<body>
<div id="app">
<h2>{{count}}</h2>
<!-- <button v-on:click="count++">加</button>
<button v-on:click="count--">减</button> -->
<button @click="increment">加</button>
<button @click="decrement()">减</button>
</div>
<script>
const app = new Vue({
el:"#app",
data:{
count:0
},
methods: {
increment(){
this.count++
},
decrement(){
this.count--
}
}
})
</script>
</body>
</html>
使用v-on:click
给button绑定监听事件以及回调函数,@是v-on:
的语法糖,也就是简写也可以使用@click
。方法一般是需要写方法名加上(),在@click
中可以省掉,如上面的<button @click="increment">加</button>
。
10.2、 v-on的参数传递
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<!-- 事件没传参 -->
<button @click="btnClick">按钮1</button>
<button @click="btnClick()">按钮2</button>
<!-- 事件调用方法传参,写函数时候省略小括号,但是函数本身需要传递一个参数 -->
<button @click="btnClick2(123)">按钮3</button>
<button @click="btnClick2()">按钮4</button>
<button @click="btnClick2">按钮5</button>
<!-- 事件调用时候需要传入event还需要传入其他参数 -->
<button @click="btnClick3($event,123)">按钮6</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
<script>
const app = new Vue({
el:"#app",
methods:{
btnClick(){
console.log("点击XXX");
},
btnClick2(value){
console.log(value+"----------");
},
btnClick3(event,value){
console.log(event+"----------"+value);
}
}
})
</script>
</body>
</html>
说明
- 事件没传参,可以省略()
- 事件调用方法传参了,写函数时候省略了小括号,但是函数本身是需要传递一个参数的,这个参数就是原生事件event参数传递进去
- 如果同时需要传入某个参数,同时需要event是,可以通过
$event
传入事件。
按钮4调用btnClick2(value){}
,此时undefined
。按钮5调用时省略了(),会自动传入原生event事件,如果我们需要event对象还需要传入其他参数,可以使用$event
对象。