在学习vue时,插值表达式和vue指令可谓是基础中的基础,这篇文章,就让你彻底了解怎么使用插值表达式和vue中所有指令的用法。
一、插值表达式:{{ }}
- 可以将vue中的数据填写在插值表达式中
<div id="app">{{ title }}</div>
<script>
const vm = new Vue({
el:"#app",
data:{
title:"the first vue"
}
})
</script>
- 也可以直接填写数值、数组、对象等。
<div id="app">{{ 123 }}</div>
- 可以填写表达式,但是不能写流程语句。
<div id="app">
{{ 100*2 }}
{{ 1 + 1 === 2 ? "是的" : "不是" }}
</div>
- 注意:尽量中间加上空格,否则遇到一个对象的时候,会报错。也不能使用未声明的变量。
<div id="app">{{{a:1}}}</div>
//Error compiling template
二、vue中的指令
1、v-pre
v-pre
:不使用vue语法进行渲染,跳过元素和他的子元素的编译过成。
<div v-pre>{{ title }}</div>
// {{ title }}
2、v-cloak
v-cloak
:当元素在编译时存在,当元素编译完成后,该指令消失。通常解决首屏闪烁。
[v-cloak] {
display: none;
}
<div v-cloak>{{ title }}</div>
3、v-once
v-once
:只渲染一次,之后的重新渲染,元素及其所有的子节点将被视为静态内容并跳过。因为它使用缓存中的值,不再使用vm中的值,数据也就不再变化。
<div v-once>{{ title }}</div>
4、v-html
-
v-html
:相当于innerHTML
。内容按普通 HTML 插入,不会作为 Vue 模板进行编译 。注意:小心XXS攻击,在可信内容上使用v-html,拒绝用户交互下使用该指令
<div v-html="title"></div> // the first vue {{ name }}
<script>
const vm = new Vue({
el:"#app",
data:{
title:"the first vue {{ name }}",
name:"lkx"
}
})
</script>
5、v-text
v-text
:相当于textContent
。
注意:v-text
会替换元素中所有的文本,插值表达式只替换自己,不会清空元素。优先级比插值表达式高。
<div v-text="title"></div>
<!-- 和下面的效果一样 -->
<div>{{ title }}</div>
补充: dom.innerText
和dom.textContent
- 设置文本替换时,两者都会把指定节点下的所有子节点也一并替换掉。
- innerText 受 CSS 样式的影响,并且不会返回隐藏元素的文本,而textContent会。
- 由于 innerText 受 CSS 样式的影响,它会触发重排(reflow),但textContent 不会。
- textContent 会获取所有元素的内容,包括
<script>
和<style>
元素,但innerText不会
6、v-if
7、v-else-if
8、v-else
-
v-if
:控制元素的显示和隐藏,通过对元素的添加和删除。可以作用在template上。 -
v-else-if
:控制元素显示和隐藏。前一个兄弟元素必须有v-if
-
v-else
:前一个兄弟元素必须有v-if
或v-else-if
<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>
9、v-show
v-show
:控制标签的显示和隐藏,通过操作display:none|block
属性控制显示和隐藏,v-show对template标签不起作用,显而易见是因为template标签,没有任何意义,也不会渲染到页面中,只是为了方便填写指令出现的。
<div v-show="isShow">{{ title }}</div>
注意:v-if
是惰性的,如果在初始渲染时条件为假,则什么也不做,直到条件第一次变为真时,才会开始渲染条件块。v-show
则不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS
进行切换。v-if
有更高的切换开销,v-show
有更高的初始渲染开销,如果需要频繁切换,v-show
比较好,如果改变少,则v-if
更好。
10、v-bind
v-bind
:动态绑定一个或多个特性值,或用:
缩写。:
后面的时参数,例如:v-bind:src="imgSrc"
,src
就是参数
<!-- 绑定一个属性 -->
<img v-bind:src="imgSrc">
<!-- 动态特性名 (2.6.0+) -->
<button v-bind:[key]="value"></button>
<!-- 缩写 -->
<img :src="imgSrc">
<!-- 动态特性名缩写 (2.6.0+) -->
<button :[key]="value"></button>
<!-- 内联字符串拼接 -->
<img :src="'/img/' + fileName">
<!-- 没有参数,绑定一个对象,键值会变为特性名和值 -->
<img v-bind="{src:'a.jpg'}>
使用v-bind
绑定class
和style
绑定class
:绑定class并非覆盖原来的class,只是在原来的基础上添加
- 对象语法:是否使用
red
类名,取决于isRed
变量的真假
<div v-bind:class="{ red: isRed }"></div>
- 数组语法:我们可以把一个数组传给 v-bind:class,以应用一个 class 列表
<div v-bind:class="[classA, classB]"></div>
注意:
- 在数组语法中可以使用三元表达式来切换class
<div v-bind:class="[isActive ? activeClass : '', errorClass]"></div>
- 在数组语法中可以使用对象语法
<div v-bind:class="[classA, { classB: isB, classC: isC }]">
<div v-bind:class="classA" class="red">
- v-bind:class 可以与普通 class 共存
<div v-bind:class="classA" class="red">
绑定style
:
- 对象语法:看着比较像CSS,但其实是一个JavaScript对象
<div v-bind:style="{ fontSize: size + 'px' }"></div>
<script>
const vm = new Vue({
el:"#app",
data:{
size: 30
}
})
</script>
<!-- 等同于下面写法 -->
<div v-bind:style="styleObject"></div>
<script>
const vm = new Vue({
el:"#app",
data:{
styleObject: {
fontSize: '13px'
}
}
})
</script>
- 数组语法:可以将多个样式对象应用到同一个元素
<div v-bind:style="[styleObjectA, styleObjectB]"></div>
注意:
-
自动添加前缀。在绑定style时,使用需要添加浏览器引擎前缀的CSS属性时,Vue.js会自动侦测并添加相应的前缀。
-
CSS属性名可以用驼峰式或者短横线分隔来命名。但是使用短横线分隔时,要用引号括起来
<div :style="{color:'red',width:'100px','background-color':'#ccc'}"></div>
<!-- background-color 必须加上引号,或者写成backgroundColor 驼峰命名法 -->
v-bind的指令修饰符:
.camel
:特性会将大写字符转换成小写字母,camel解决这种问题,用-
链接符会变为驼峰命名法
<svg :view-box.camel="viewBox"></svg>
<!-- 被渲染为 -->
<svg viewBox="xxxx"></svg>
.prop
:直接使用dom中的属性,给属性赋值
<div v-bind:text-content.prop="title"></div>
<!-- 相当于 -->
document.getElementsByTagName("div")[0].textContent = title
11、v-on
v-on
:事件监听,并触发绑定的JavaScript代码,可以用@
简写
<div id="app">
<button v-on:click="add(1,$event)">点击</button>
<p>按钮被点击了 {{ counter }} 次</p>
</div>
<script>
new Vue({
el: '#app',
data: {
counter: 0
},
methods: {
add: function (num,e) {
console.log(e)
this.counter += 5;
}
}
})
</script>
注意:填写多个参数时,可以用$event获取事件对象
v-on指令的修饰符:
.stop
阻止冒泡行为。点击按钮只会输出button
<div id="app">
<div @click="console('div')">
<button @click.stop="console('button')">点击</button>
</div>
</div>
<script>
new Vue({
el: "#app",
methods: {
console(str){console.log(str)}
},
})
</script>
.prevent
阻止默认事件。会调用event.preventDefault()
,组织默认事件。例如:下面点击提交按钮后,页面不会重载
<div id="app">
<form v-on:submit.prevent="onSubmit">
<input type="submit">
</form>
</div>
<script>
new Vue({
el: "#app",
methods: {
onSubmit(){console.log("提交操作...")}
},
})
</script>
.capture
开启事件捕获模式。即事件从上向下依次执行,例如:点击按钮后,先输出div再输出button
<div id="app">
<div @click.capture="console('div')">
<button @click="console('button')">点击</button>
</div>
</div>
<script>
new Vue({
el: "#app",
methods: {
console(str){console.log(str)}
},
})
</script>
.self
只当事件是从侦听器绑定的元素本身触发时才触发回调。就是点击自己的时候才执行,不会因为冒泡或其他捕获时执行。
<div id="app">
<div @click.self="console('div')">
<button @click="console('button')">点击</button>
</div>
</div>
<script>
new Vue({
el: "#app",
methods: {
console(str){console.log(str)}
},
})
</script>
-
.once
只执行一次,多次点击无效,太简单了,不举例了。 -
.passive
不阻止默认事件 。并要注意不要把.passive
和.prevent
一起使用,因为.prevent
将会被忽略,同时浏览器可能会向你展示一个警告。
<div v-on:scroll.passive="onScroll">...</div>
解释:passive是滚动行为的默认事件,只要滚动给就会立即执行,不会等到onScroll
完成。在触发触摸事件时,执行了一个空的函数,也会让页面卡顿。因为浏览器不知道监听器到底会不会阻止默认事件,所以浏览器要等到执行完整个函数后,才能决定是否要滚动页面。passive事件监听器,允许开发者告诉浏览器,监听器不会阻止默认行为,从而浏览器可以放心大胆的滚动页面,这样可以大幅度提升移动端页面的性能,因为据统计只有20%的触摸事件会阻止默认事件。
我们还需要注意,修饰符的顺序也非常重要。相应的代码会以同样的顺序产生。例如:
v-on:click.prevent.self
:会阻止所有的点击的默认事件,而v-on:click.self.prevent
:只会阻止对元素自身点击的默认事件
v-on中的按键修饰符:
- 按键码修饰符
下面的代码,只有当我们按下回车键时才会触发submit函数执行
<input v-on:keyup.enter="submit">
常用的按键码别名:.enter
(回车键)、.tab
(tab键)、.delete
(捕获“删除”和“退格”键)、.esc
、
.space
、.up
、.down
、.left
、.right
也可以在全局自定义按键修饰符的别名,使用Vue.config.keyCodes
对象
Vue.config.keyCodes = {
'f1-key':112 //但需要使用-链接
}
v-on中鼠标按钮修饰符:
下面的代码,只有当我们按下鼠标右键时才会触发change函数执行
<button v-on:click.right="change"></button>
鼠标按钮修饰符只有三个.left
、.right
、.middle
12、v-for
v-for
:基于一个数据来渲染一个列表。
在数组中:v-for="(item, index) in items"
,其中item
是被迭代的数据的别名,index
是当前的索引(可选值),items
是数据源。
在对象中:v-for="(value, key, index) in items"
,其中value
是被迭代的数据的别名,key
是键值(可选值),index
是当前的索引(可选值),items
是数据源。
在使用v-for
时,还需要指定一个唯一的key
值,vue
会根据key
值找到对应的dom
,会进行比对,如果发生变化,可以准确的进行更新,便于重排和重绘
<div v-for="(item,index) in items" :key="item.id">
{{ item }}
</div>
注意:不能把key值给template,必须要给真实的元素
<template v-for="(item,index) in items">
<div :key="`${key}_1`">{{ item }}</div>
<span :key="`${key}_2`">{{ item }}</span>
</template>
注意:vue会为了尽可能的节省性能,当vue的发现两个dom相同时,就不会替换,会复用元素。如下,当切换时,input框不会替换,我们通常为input添加key值解决。
<div v-if="flag">
<label for="name">name</label>
<input type="text">
</div>
<div v-else>
<label for="name">age</label>
<input type="text">
</div>
我们尽量不要将v-for
和v-if
放在同一个元素上使用,因为v-for
的优先级比v-if
高,每一个dom元素都会进行相同的v-if
判断,十分影响性能。
13、v-model
v-model
:表单元素的双向数据绑定。数据更新元素会更新、元素更新数据也会更新。本质上v-model
是value和input事件的语法糖
<div id="app">
<input type="text" v-model="data"> {{ data }}
</div>
<script>
const vm = new Vue({
el:"#app",
data:{
data:""
}
})
</script>
其实底层就是通过控制value和input事件来实现的。如下:
<div id="app">
<input type="text" :value="data" @input="inputHandle"> {{ data }}
</div>
<script>
const vm = new Vue({
el:"#app",
data:{
data:""
},
methods:{
inputHandle(e){
this.data = e.target.value
}
}
})
</script>
v-model在不同的表单元素上使用
- 在
input
和textarea
是value
的值 - 在单选框中,为选中的
value
值 - 在复选框中,是一个数组,每一项是选中的
value
- 在下拉框中,单选下拉框是选中的
option
中的值,多选是一个数组,每一项是选中的option
中的值
v-model中的修饰符:
.lazy
:使用change事件而非input事件,如果不需要实时更新,则可以用.lazy
.trim
:去掉前后的空格.number
:因为v-model绑定数据是一个字符串,会将数据中的字符串转为number类型
14、v-slot
v-slot
:插槽