"@
Vue.js官方给自己的定义为数据模版引擎,并给出了一套渲染数据的指令。本文将详细介绍Vue.js的常用指令
导入vue.js
https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js
Vue.js使用了基于HTML的模版语法,使用vue最简单的方式就是渲染数据,渲染数据最常见的形式就是使用"Mustache"语法(双大括号)的文本插值。
- - - - - - - - - - - - - - - - - - - - - -
一个简单的示例:
<body>
<div id="sign">{{ message }}</div>
<script>
let sign = new Vue({
el: '#sign',
data: {
message: 'Hello Vue!',
},
});
</script>
</body>
首先,创建一个vue实例,并在创建实例的过程中传入一个对象。
·
该对象的第一个属性名为el,它的值是我们需要渲染的目标标签,我们通过属性查找定位这个标签。
·
该对象的第二个属性名为data,里面就是我们要渲染给浏览器标签的数据,另外还有其它属性。
- - - - - - - - - - - - - - - - - - - - - -
看了上面的代码,可能大家觉得vue也不过如此,原生js代码两行就能完成的事情,vue需要6行代码来实现,还是原生js比较简洁,其实,上面的代码只是给大家演示了挂档的技术,究竟是汽车比较快,还是骑马比较好,我们通过后面的不断学习,来解释这个问题。
接下来,我们来介绍踩油门的技术。
上面的代码中,我们演示了如何将数据渲染进DOM标签,vue帮助我们找到标签并且渲染,对于程序员来说,我们不再需要重复的找标签,绑定事件,然后再找标签,再绑定事件这样的工作了,vue帮我们都做好了,我们只需要关注具体的数据,以及业务逻辑。这也是vue给自己的定位,数据模板引擎。
它是引擎,引擎帮助我们驱动数据渲染到模板。
所以,vue的大部分内容,都是为了渲染数据用的,接下来,我们介绍vue中用来渲染数据的常用指令。
v-html
双大括号语法无法渲染HTML标签,我们需要使用v-html.
<body>
<div id="sign" v-html="info"></div>
<script>
let sign = new Vue({
el: '#sign',
data: {
info: '<h1>Hello Vue!</h1>',
}
})
</script>
</body>
v-text
类似双大括号语法渲染数据的另一种方式是使用v-text.
<body>
<div id="sign" v-text="info"></div>
<script>
let sign = new Vue({
el: '#sign',
data: {
info: 'Hello Vue!',
},
});
</script>
</body>
v-for
接下来,我们看看数组和对象的渲染方式.
<body>
<div id="sign">
<h3>zyk的爱好</h3>
<ul><li v-for="item in zyk">{{ item }}</li></ul>
<h3>其它人的爱好</h3>
<ul><li v-for="famous in famouss">{{ famous.name }}的爱好是{{ famous.hobby }}</li></ul>
</div>
<script>
let sign = new Vue({
el: '#sign',
data: {
zyk: ["抽烟", "喝酒", "烫头"],
famouss: [
{name: "赵丽颖", hobby: "演戏"},
{name: "展展与罗罗", hobby: "沙漠骆驼"},
{name: "IG", hobby: "拿冠军"},
],
},
});
</script>
网页中的显示效果如下图:
v-if
渲染数据的时候,同样也可以使用条件判断.
v-if的作用是控制标签的显示,它通过判断来添加标签.
用法一:
# v-if连续判断
<body>
<div id="sign">
<div v-if="dep == '开发部'">各个大佬部门</div>
<div v-if="dep == '销售部'">花钱太多部门</div>
<div v-if="dep == '人事部'">招不到人部门</div>
<div v-if="dep == '行政部'">办不好事部门</div>
</div>
<script>
let sign = new Vue ({
el: '#sign',
data: {
dep: "开发部",
},
});
用法二:
# v-if v-else-if v-else
<div id="sign">
<div v-if="dep == '开发部'">各个大佬部门</div>
<div v-else-if="dep == '销售部'">花钱太多部门</div>
<div v-else="dep == '人事部'">招不到人部门</div>
</div>
<script>
let sign = new Vue ({
el: '#sign',
data: {
dep: "开发部",
},
});
</script>
注意查看HTML标签元素,v-if底层使用appendChild方法实现.
v-show
与v-if类似,也是控制标签显示的.
<body>
<!--!isShow:取反(!)-->
<!--<div id="sign" v-show="!isShow">Hello Vue!</div>-->
<div id="sign" v-show="isShow">Hello Vue!</div>
<script>
let sign = new Vue({
el: '#sign',
data: {
// isShow: 1, 通过布尔值来判断, 为true时显示标签
isShow: true,
},
});
</script>
</body>
与v-if不同的是,v-show通过样式的display控制标签的显示.
v-if与v-show的性能比较
·
实现方式:
v-if底层采用的是appendChild来实现的;
v-show通过样式的display: none;控制标签的显示;
正因为实现方式上的差异,导致了它们的加载速度方面产生了差异:
·
加载性能:v-if加载速度快,v-show加载速度慢.
切换开销:v-if切换开销大,v-show切换开销小.
·
v-if是惰性的,它是"真正"的条件渲染,因为它能确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建;
v-show也是惰性的,如果在初始渲染时条件为假,则什么也不做,直到条件第一次变为真时,才会开始渲染条件块;
·
v-show简单的多,不管初始条件是什么,元素总是会被渲染,并且只是简单地基于CSS进行切换.
·
一般来说,v-if有更高的切换开销,而v-show有更高的初始渲染开销。因此,得出结论:
·
需要频繁地切换时,使用v-show较好;
运行过程中条件很少改变时,使用v-if较好;
v-bind
绑定属性
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>
<title>test</title>
<style>
.active {
background-color: gray;
}
</style>
</head>
<body>
<!--注意冒号后面跟标签的属性,属性后面的等号指向数据,可以简写为 :class, :href-->
<a id="sign" v-bind:href="link" :class="{active: isActive}">CSDN</a>
<script>
let sign = new Vue({
el: '#sign',
data: {
link: 'https://blog.csdn.net/qq_41964425',
isActive: true,
},
});
</script>
</body>
</html>
v-on
使用v-on可以在标签上面绑定事件,注意我们新建的vue实例sign中多了一个属性:methods,在methods中,是我们具体事件的实现方式.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>
<title>test</title>
<style>
.active01 {
color: red;
}
.active02 {
font-size: 200%;
}
</style>
</head>
<body>
<div id="sign">
<button v-on:click="colorRed">点我变颜色</button>
<!-- v-on:可简写为@符 -->
<button @click="colorGreen">点我变大小</button>
<!-- 还可以向下面这样用(mouseenter与mouseleave是鼠标的事件)-->
<!-- :class是v-bind:class的简写 -->
<p :class="{active01: isActive01, active02: isActive02}"
v-on="{mouseenter: colorRed, mouseleave: colorGreen}">我变</p>
</div>
<script>
let sign = new Vue({
el: '#sign',
data: {
isActive01: false,
isActive02: false,
},
// methods中是我们具体事件的实现方式
methods: {
colorRed: function () {
this.isActive01 = !this.isActive01; // ! 取反
},
colorGreen: function () {
this.isActive02 = !this.isActive02;
}
},
});
</script>
</body>
</html>
v-model
双向数据绑定
上面的示例是通过vue实例将数据渲染进模版,我们修改数据后,被修改的数据能及时(官方称之为响应式)的渲染到模版层.
那么,如果有这样一个需求,比如一个input标签,当用户修改渲染的原始数据后,打印出修改后的数据.
简单说,我们需要vue实例帮我渲染数据并响应式的监听数据修改,同时我们还需要监听用户行为,如果用户在标签上面修改了数据(之前的修改,指的是通过vue实例sign进行的数据修改),我们需要获取到新数据,针对这个需求,我们可以使用v-model指定.
<body>
<div id="sign">
<p>
你的姓名:
<input type="text" v-model="name"/>
</p>
<p>
选择你的性别:
<label>男<input type="checkbox" value="男" v-model="genders"></label>
<label>女<input type="checkbox" value="女" v-model="genders"></label>
</p>
<p>
选择你的女朋友:
<select v-model="girlFriends">
<!--注意:value不要留空-->
<!--如果指定了value,则{{ girlFriends }}会显示value的值-->
<option value="01">赵丽颖01</option>
<option>赵丽颖02</option>
<option>赵丽颖03</option>
</select>
</p>
<p><textarea v-model="article"></textarea></p>
<hr>
你的姓名是:{{ name }}
<hr>
你的性别是:{{ genders }}
<hr>
你选择的女朋友是:{{ girlFriends }}
<hr>
你的简介是:{{ article }}
</div>
<script>
let sign = new Vue({
el: '#sign',
data: {
name: 'zyk',
genders: [],
girlFriends: [],
article: "此处省略800字",
},
});
</script>
</body>
指令修饰符
<body>
<div id="sign">
<table border="1">
<thead>
<tr>
<th>学科</th>
<th>成绩</th>
</tr>
</thead>
<tbody>
<tr>
<td>语文</td>
<!--v-model.number:将其值转化为int类型-->
<td><input type="text" v-model.number.lazy="语文"></td>
</tr>
<tr>
<td>英语</td>
<td><input type="text" v-model.number.lazy="英语"></td>
</tr>
<tr>
<td>数学</td>
<td><input type="text" v-model.number.trim="数学"></td>
</tr>
</tbody>
</table>
</div>
<script>
let sign = new Vue({
el: '#sign',
data: {
"语文": 77,
"英语": 88,
"数学": 99,
},
});
</script>
</body>
网页中的显示效果如下图:
计算与侦听属性
计算属性: computed
侦听属性: watch
<body>
<div id="sign">
<table border="1">
<thead>
<tr>
<th>学科</th>
<th>成绩</th>
</tr>
</thead>
<tbody>
<tr>
<td>语文</td>
<!--v-model.number:将其值转化为int类型-->
<td><input type="text" v-model.number="语文"></td>
</tr>
<tr>
<td>英语</td>
<td><input type="text" v-model.number="英语"></td>
</tr>
<tr>
<td>数学</td>
<td><input type="text" v-model.number="数学"></td>
</tr>
<tr>
<td>总分</td>
<!--<td>{{ 语文 + 英语 + 数学 }}</td>-->
<td>{{ sumScore }}</td>
</tr>
<tr>
<td>平均分</td>
<td>{{ avgScore }}</td>
</tr>
</tbody>
</table>
<hr>
{{ 数学 }}
</div>
<script>
let sign = new Vue({
el: '#sign',
data: {
"语文": 77,
"英语": 88,
"数学": 99,
},
// 计算属性放在缓存当中,只有数据修改时才重新计算,网页刷新时才执行
computed: {
sumScore: function () {
return this.语文 + this.英语 + this.数学;
},
avgScore: function () {
return this.sumScore / 3;
},
},
// 侦听属性
watch: {
数学: function () {
// 这里我实测未打印结果, 不明原因
console.log(this.数学);
},
},
});
</script>
</body>
自定义属性
<body>
<div id="sign" v-pos="position">Hello Vue!</div>
<script>
// 下面的pos <=> 上面调用时的v-post
Vue.directive('pos', function (el, bindding) {
console.log("大家好!我是自定义属性");
console.log("el的值为:", el);
console.log("bindding的值为:", bindding);
});
let sign = new Vue({
el: '#sign',
data: {
position: true,
},
})
</script>
</body>
获取DOM元素
<body>
<div id="sign">
<h1 ref="myRef">我是颜色</h1>
<button @click="greenColor">点我让颜色变绿</button>
<!-- @click 等同于 v-on:click -->
</div>
<script>
let sign = new Vue({
el: '#sign',
data: {
isActive: 'active',
},
// 获取DOM属性
methods: {
greenColor: function () {
this.$refs.myRef.className = this.isActive;
},
},
});
</script>
</body>
"