一、什么是指令
1、指令是vue内置的一套“模板”(都是以v-开头的)
以后自定义指令也要用v-开头,因为vue编译器看到v-开头,知道是指令,而指令绑的表达式,编译器就会去编译表达式
2、指令的作用
用于在视图节点上动态绑定变量的
3、指令可以理解成一套符号
要非常的熟
4、指令实际上是DOM功能的抽象
背后也是在做DOM操作
我 -> 指令 -> DOM操作
5、指令等号右边的值是表达式
怎么判断一个内容是不是表达式,表达式用()括号包起来,不会报错
二、文本类指令
指令 | 是否有值 | 说明 |
{{}} | 有 | 文本插值,在以前前后端不分离的项目中常见到 用于绑定节点的文本值,它和v-text功能是一样的,区别是{{}}这种绑值的方式会出现一闪而过,建议使用v-cloak来解决 |
v-text | 有 | 用于绑定节点的文本值,它和{{}}可以相互替换 |
v-once | 无 | 变量初始化的时候只绑一次,以后变量发生变化,页面不更新。最好跟文本插值一起用 就是说你改了变量,变量变了,但是页面没更新 |
v-cloak | 无 | 要增加一个样式,当渲染还没完成的时候,不显示内容 |
v-html | 有 | 用于绑定动态的html节点,相当于DOM中的innerHTML,渲染成标签不是单纯的文本 |
三、文本类指令-例子代码
<html>
<head>
<title>指令基础-1</title>
<style>
[v-cloak] {display: none;}
</style>
</head>
<body>
<div id="app">
<h1>{{msg}}</h1>
<h1 v-cloak>{{msg}}</h1>
<h1 v-text="msg"></h1>
<h1 v-text='("年龄:" + age)'></h1>
<h1 v-text="`年龄:${age}`"></h1>
<h1 v-html="content"></h1>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.16/dist/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
msg: 'HelloWorld',
age: 20,
content: '<a href="https://www.baidu.com">百度</a>'
}
})
</script>
</body>
</html>
1、打印app对象
2、app对象类型
3、每一个Vue组件都有个id,“_uid: 0”
0表示它是根组件
4、$开头的符号,是vue官方提供的内置属性和方法
5、什么是this
this是new的结果,它的实例对象等于this,在代码块中访问变量用this
问题:
为什么访问变量可以用this.xxx来访问?
变量不是放在data中吗,为什么访问变量不用this.data.msg?
回答:
因为vue在组件实例化的时候,会对data进行遍历,会把所有的变量都放在this上(就是new的app上)。
我们可以看到用this.msg可以访问,用this.data.msg也可以访问。
6、{{msg}}的问题,在刷新页面时会看到模板一闪而过
用v-cloak解决花括号一闪而过,还要添加样式
<style>
[v-cloak] {display: none;}
</style>
7、表达式内包含中文
(1)表达式内中文要用""包括,所以外面一层用单引号''
<h1 v-text='("年龄:" + age)'></h1>
(2)用ES6模板字符串
<h1 v-text="`年龄:${age}`"></h1>
8、绑定动态html标签中途被黑客劫持怎么办
v-html这个指令默认已经做了防注入攻击XSS的处理
四、动态属性指令
指令 | 是否有值 | 说明 |
v-bind | 是 | 用于动态绑定html视图节点的属性(比如title、value、class、style) |
由于v-bind用的非常多,所以经常简写成 : (冒号)
五、动态属性指令-例子代码
<html>
<head>
<title>指令基础-2</title>
<style>
.a1 {color: red;}
.a2 {color: green;}
.a3 {color: blue;}
.f1 {font-size: 20px;}
.f2 {font-size: 30px;}
.f3 {font-size: 40px;}
</style>
</head>
<body>
<div id="app">
<h1 v-bind:title="tt">教育</h1>
<h1 :title="tt">教育</h1>
<h1 v-bind="{title: tt}">教育</h1>
<h1 :class='`${cc} ${ff}`'>测试动态样式</h1>
<h1 :class='[cc, ff]'>测试动态样式</h1>
<h1 :style='`color:red;fontSize:20px`'>测试动态样式2</h1>
<h1 :style='[{color:"red", fontSize:"20px"}]'>测试动态样式2</h1>
<h1 :style='{color:"red", fontSize:"20px"}'>测试动态样式2</h1>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.16/dist/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
tt: '标题标题标题',
cc: 'a1',
ff: 'f1'
}
})
</script>
</body>
</html>
1、动态属性
(1)h1这个标签加了title之后鼠标移上去会显示
(2)修改tt的值
(3)再把鼠标移上去显示
2、v-bind简写方式
<h1 :title="tt">教育</h1>
3、v-bind第三种写法(很少用)
<h1 v-bind="{title: tt}">教育</h1>
4、vue中有很多小技巧,但不用搞花里胡哨的,就用一种写法就行了,减少阅读代码的难度
5、动态class语法
<div :class='变量'></div>
<div :class='`${变量1} ${变量2} ...`'></div>
<div :class='[表达式1, 表达式2, ...]'></div> --数组语法
<div :class='{类名1: 布尔值1, 类名2: 布尔值2, ...}'></div> --对象语法
6、如何动态更改样式
在控制台修改,cc和ff变量,页面就变化了
7、动态style语法
<div :style='`color:red;fontSize:20px`'></div>
<div :style='[{css键值对}, {css键值对}, ...]'></div> --数组语法
<div :style='{color:"red", fontSize:"20px"}'></div> --对象语法
六、事件绑定指令
指令 | 是否有值 | 说明 |
v-on | 是 | 用于给视图节点绑定各种JS事件(比如:click、mouseenter、blur、keyup等等) |
因为v-on用的非常多,所以简写成:@
七、事件绑定指令-例子代码
<html>
<head>
<title>指令基础-3</title>
<style>
.outer {
width: 200px;
height: 200px;
border: 1px solid red;
}
.inner {
width: 100px;
height: 100px;
border: 1px solid blue;
}
</style>
</head>
<body>
<div id="app">
<button v-on:click="handle">点击</button>
<div class="outer" @click="outerClick">
<div class="inner" @click.stop="innerClick"></div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.16/dist/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
},
methods: {
handle(event) {
console.log('---clicked', event)
},
outerClick(event) {
console.log('---outr clicked')
},
innerClick(event) {
console.log('---inner clicked')
}
}
})
</script>
</body>
</html>
1、绑定点击事件并打印
2、v-on基本语法
<div @事件名.事件修饰符='事件处理器'></div>
3、事件修饰符
阻止事件冒泡
在v-on上可以使用事件修饰符:
.stop 阻止冒泡
.prevent 阻止默认事件
.enter 绑定键盘Enter键
很多很多。。。
八、表单绑定指令
指令 | 是否有值 | 说明 |
v-model | 是 | 用于表单取值(表单双向绑定),比如input/select/textarea等等 |
九、表单绑定指令-例子代码
<html>
<head>
<title>指令基础-4</title>
</head>
<body>
<div id="app">
姓名:<input type="text" v-model.trim="todo" /> <br>
年龄:<input type="number" v-model.number="age" /> <br>
介绍:<textarea cols="30" rows="2" v-model.lazy="desc"></textarea>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.16/dist/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
todo: '',
age: 0,
desc: ''
},
methods: {
}
})
setInterval(()=>{
console.log("---desc: " + app.desc)
}, 500)
</script>
</body>
</html>
1、v-model基本语法
<input type="text" v-model.表单修饰符='变量' />
让表单取的值放在这个变量上
2、什么是双向绑定
界面 <=> 变量,任何一个变了,另一个跟着变,表单的双向绑定,取值特别方便
3、事件修饰符
.trim 自动去除文本首尾空格
.number 做隐式类型转换,变成Number类型
.lazy 用于性能优化,当表单失去焦点时再进行双向绑定
4、表单只要发生了变化,都变为字符串类型
5、每次输入表单都会触发,vue变量赋值,性能较差,所以加上.lazy
增加个定时器,看看不加.lazy的效果:
在介绍框里输入1234567890
6、v-model还有很多高级用法,在组件化中进一步讲解
十、列表渲染指令
指令 | 是否有值 | 说明 |
v-for | 是 | 用于渲染列表、对象、数值类型等等 |
十一、列表渲染指令-例子代码
<html>
<head>
<title>指令基础-5</title>
</head>
<body>
<div id="app">
<div v-for='(item, index) in todoList'>
<div :style='{background: item.computed ? "red" : "transparent"}'>
<input type="checkbox" @click.prevent="transform(item, index)" /> <!--事件传参-->
<span v-text='item.task'></span> <!--直接取list里的字段-->
<span>x</span>
</div>
</div>
<div v-for='(value,key,index) in info'>
<span v-text="index"></span>
:
<span v-text="key"></span>
:
<span v-text="value"></span>
</div>
<div v-for='(num, index) in 5'>
<span v-text="index"></span>
:
<span v-text="num"></span>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.16/dist/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
todoList: [
{id: 1, task: '吃饭', computed: false},
{id: 2, task: '睡觉', computed: false},
{id: 3, task: '读书', computed: false}
],
info: {
name: '张三',
age: 20,
addr: '广东深圳'
}
},
methods: {
transform(item, index) {
console.log('准备把当前这条任务变成已完成', item, index)
this.todoList[index].computed = true
}
}
})
</script>
</body>
</html>
1、v-for基本语法
<div v-for='(item,index) in array'></div> --渲染列表
<div v-for='(value,key,index) in obj'></div> --渲染对象,obj就是json串
<div v-for='(num, index) in number类型'></div> --渲染Number变量
2、事件传参
把v-for的item和index参数传到事件中,@click.prevent="transform(item, index)
3、v-for在循环渲染时要求加key
十二、条件渲染指令
指令 | 是否有值 | 说明 |
v-show | 是 | 用于显示或隐藏视图节点,背后使用的(display:block或者display:none)来实现的 |
v-if / v-else-if / v-else | 是 (v-else没有) | 用于显示或隐藏视图节点,背后是真正的移除或插入节点 |
十三、条件渲染指令-例子代码
<html>
<head>
<title>指令基础-6</title>
</head>
<body>
<div id="app">
<h1 v-show="bol2">测试条件渲染</h1>
<h1 v-if="bol2">测试条件渲染2</h1>
<h1 v-if='row===0'>第一行</h1>
<h1 v-else-if='row===1'>第二行</h1>
<h1 v-else-if='row===2'>第三行</h1>
<h1 v-else>第四行</h1>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.16/dist/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
bol2: true,
row: 0
},
methods: {
}
})
</script>
</body>
</html>
1、v-show的DOM结构
切换app.bol2=false和app.bol2=true
<h1 style="display: none;">测试条件渲染</h1>
真实DOM还在,是通过修改样式来实现的
2、v-if的DOM结构
真实DOM不在了,它是通过移除和插入DOM来实现的
3、v-if因为是节点的插入或移除,做大量的DOM操作比较耗费性能。v-show只是通过样式来实现显示与隐藏,性能开销更小
4、v-if不建议和v-for一起使用,如果一定要在同一个节点上使用v-if和v-for,v-for有更高优先级(3.0时候反过来了)
十四、其他指令
这些是vue3.0新增的指令
指令 | 是否有值 | 说明 |
v-pre | 用于调试,可以阻止vue编译器对指令的编译,生产上很少使用 | |
v-slot | 在组件化时,用于指定具名插槽 | |
v-memo | 缓存一个模板的子树 |