本章主要内容:
一、原生与VUE渲染的区别
二、VUE的条件渲染
三、VUE的列表渲染
四、(条件渲染+列表渲染)结合使用
条件渲染,顾名思义,将满足一定条件的内容进行渲染。
我们在原生js中如何来实现对DOM进行控制,只把想要的内容呈献给用户?
display、visibility
我们通过对display:none进行设置,来决定dom元素是否会呈现在页面上,这样做实际上DOM任然是存在的,不过是将它隐藏了,它隐藏后并不会占据原有的页面位置,之后页面会进行重新布局,所以感觉它不存在。
visibility,元素的可见性进行设置,但是这样设置之后你会发现页面上确实看不见它了,但是它所在的位置还是空着的。整体布局还是和原来一样。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>VUE教程</title>
<style>
.div{
width: 100px;
height: 100px;
background-color: red;
margin-top: 20px;
}
.div_none{
display: none;
width: 100px;
height: 100px;
background-color: red;
margin-top: 20px;
}
.div_visibility{
width: 100px;
height: 100px;
background-color: red;
margin-top: 20px;
visibility: hidden;
}
</style>
</head>
<body>
<div class="div">
1
</div>
<div class="div_none">
2
</div>
<div class="div">
3
</div>
<div class="div_visibility">
4
</div>
<div class="div">
5
</div>
</body>
</html>
这样做有什么不好的地方呢?
首先无论使用上述哪种,都存在一个问题,DOM已经渲染了,资源已经占用了,再有,控制的时候都需要你通过元素属性进行控制,这样是极为不方便的。
️而在VUE中是如何来处理这块内容呢?
条件渲染
VUE条件渲染涉及关键词v-if、v-slse、v-else-if、v-show
v-if
v-if是VUE定义的指令,书写在HTML中,控制元素的渲染与否,如:
<div v-if="true">
<p>内容</p>
</div>
在v-if=之后,可以直接跟随true或者false,当为真的时候VUE将渲染这个DIV,当然也可以跟随一个表达式,如
<div v-if="1>3">
<p>内容</p>
</div>
VUE将根据表达式的真假决定是否对DIV进行渲染,也可以使用变量作为判断,如:
<div v-if="divShow" id="app">
<p>内容</p>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
divShow: 1
}
})
</script>
最终,满足条件的VUE都渲染出来,而不满足的你则不会看见。
v-else
v-else并不能单独出现,必须跟着v-if或者v-else-if成对出现,它会将结合v-else-if或者v-if,如果满足前面两点,则v-else的内容不会渲染,如不满足,则将v-else所在的DOM进行渲染。
<div v-if="sex=='女'">
性别为:女
</div>
<div v-else>
性别为:男
</div>
如果变量sex的值为女,则渲染【性别为:女】所在DIV,如不为女 ,则渲染【性别为:男
】所在DIV,除了sex=‘女’这一种结果,其他任何结果都会渲染【性别为:男
】所在DIV。
v-else-if
v-else-if是VUE2.1.0
新增的,主要功能用于多重判断渲染,多种可能,如果你满足其中哪种就进行渲染,当然也有可能列出来的每一种都不满足,可以使用 v-else来包囊其他情况。
<div v-if="choose=== 'A'">
A
</div>
<div v-else-if="choose=== 'B'">
B
</div>
<div v-else-if="choose=== 'C'">
C
</div>
<div v-else>
Not A/B/C
</div>
v-show
v-show的使用方法和v-if一致,将满足条件的展示出来。
<div v-show="true">
<p>内容</p>
</div>
与之相对应的还有v-hide将满足条件的隐藏。
<div v-hide="true">
<p>内容</p>
</div>
大概会有人疑惑,既然v-if与v-show都是只对满足条件的进行展示,那他们有什么区别?
官网的解释是这样的【v-if 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。】【v-show 就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。】
简单来说如果用v-show,你在元素审查的时候发现这个元素实际是存在的,不过他的css样式中的display被设置为了none,而v-if,在不满足的时候它并不会去渲染这个元素,是真实的不存在。
v-if减少了整个页面的元素节点,但是如果存在经常切换显示与否的状态,就需要使用v-show,因为重新渲染或者销毁元素的消耗会远远大于简单的CSS样式隐藏与显示。
在原生JS或者利用jQuery,我们是如何来实现渲染多个一样DOM的呢?
我们会采用for循环,在循环中创建元素,对元素进行属性设置,然后将创建好的元素追加到其他元素中。或者将html代码写为文本,通过对DOM元素的innerHTML属性赋值实现。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>VUE教程</title>
<style>
</style>
</head>
<body>
<div id="dom">
</div>
<div id="dom2">
</div>
</body>
</html>
<script>
function createElementByTag() {
var dataList=[1,2,3,4,5];
var nameList=['上单','中路','打野','ADC','辅助'];
var bodyDom=document.getElementById('dom');
for(var i=0;i<dataList.length;i++){
var newDom=document.createElement("div");
newDom.style.width="200px";
newDom.style.height="200px";
newDom.style.backgroundColor="red";
newDom.style.marginTop="20px";
newDom.innerText="这是appendChild方法创建的第"+(i+1)+"个元素"+nameList[i];
bodyDom.appendChild(newDom)
}
}
function createInnerHTML() {
var bodyDom=document.getElementById('dom2');
var str='';
var dataList=[1,2,3,4,5];
var nameList=['上单','中路','打野','ADC','辅助'];
for(var i=0;i<dataList.length;i++){
str+="<div style='width:200px;height:200px;background-color:red;margin-top:20px'>"+"这是innerHTML方法创建第"+(i+1)+"个元素"+nameList[i]+"</div>"
}
bodyDom.innerHTML=str
}
createElementByTag();
createInnerHTML()
</script>
在我们日常工作中,在不使用框架的情况下基本都需要这样进行处理,在元素内容较少,样式比较简单的情况下使用起来还是比较方便的,但是当随着我们的样式复杂,数据的增加,这样的方法就显得十分的不适用了,面对项目中越来越复杂的内容,使用原生的js来完成功能显得十分困难,于是在vue中遍有了列表渲染v-for,用新的方式来解决此类问题。
v-for
如何使用v-for来完成列表渲染?
首先你需要在html中写上你的元素,就像平时写代码一样,将需要遍历的样式写一个出来,然后将数据放在vue的data中,它会自动根据你的数据来进行渲染。
v-for能将一组数组中的值挨个渲染到页面中,他有特定的语法格式【item in items】其中【items】VUE中的数据源,也就是data中数组的名字,而【item】则是在元素渲染中数组名的替代,可以随意取。
<div id="app">
<p v-for="item in weeks" >星期:{{item}}</p>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
weeks: [‘一’,‘二’,‘三’,‘四’,‘五’,‘六’,‘日’]
}
})
</script>
渲染结果如图:
所循环的数据源本身是一个数组,数组中的值则可以是各种各样的,同时v-for还可以拥有一个索引参数,来对应数组下标,这个索引参数名称可以自定义,也可以当作一个变量传递给函数。
<div id="app">
<p v-for="(item,index) in weeks" @click="nowIndex(index)">星期:{{item}},当前数组下标为{{index}}</p>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
weeks: [‘一’,‘二’,‘三’,‘四’,‘五’,‘六’,‘日’]
}
})
</script>
渲染及点击事件如图:
v-for也可以使用对象作为数据源:
<div id="app">
<p v-for="(item,key) in obj">信息{{key}},{{item}}</p>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
obj:{
name:'三思先生',
age:'24',
sex:'男'
}
}
})
</script>
其中item是会遍历每个键的键值,而key对应的则是键名,它实现的效果与数组是一致的。同时他也可以支持下标索引:
<div id="app">
<p v-for="(item,key,index) in obj" @click="nowIndex(index)">信息{{index}}:{{key}},{{item}}</p>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
obj:{
name:'三思先生',
age:'24',
sex:'男'
}
},
methods: {
nowIndex:function (index) {
alert('当前下标为'+index)
}
}
})
</script>
其中在括号中的参数顺序不能弄错,第一个表示值,第二个是键名,第三个是索引。
最后来讲述v-for与v-if结合使用,这在我们日常工作中是使用频繁的,可以通过v-for来渲染我们的列表数据,而v-if与之结合则可以进一步控制,只渲染列表中我们需要渲染的部分。
<div id="app">
<p v-for="(item,index) in info" @click="nowAge(item.age)" v-if="item.age>23">姓名:{{item.name}}--年龄:{{item.age}}</p>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
info:[
{
name:'joker',
age:18
},
{
name:'uu',
age:23
},
{
name:'nick',
age:33
},
{
name:'duck',
age:25
},
{
name:'poke',
age:12
}
]
},
methods: {
nowAge:function (age) {
alert('他的年龄为'+age)
}
}
})
</script>
在v-if中写表达式,只渲染年龄>23岁的数据。代码中有item.age这样的写法,因为在这组数组中的值都是对象,所以可以使用item.age来获取其中的年龄,也可以在v-for的范围内作为一个参数传递给方法。
代码及点击事件效果执行如图:
以上内容为v-for及v-if的使用,后续还会涉及到这块知识,因为需要其他知识模块的支撑,所以在后续过程中会为大家陆续补充。
实战训练:
盗取了GitChat的样式图,我们要渲染下面的内容,附加一条要求,只渲染名称为小于四个字的模块。
首先我准备了一个数据源,一个数组,数组由多个对象组成,对象的格式为
{
src:‘XXXXXXXXX’,
name:‘前端’
}
包含一个图片路径和一个标题名称。首先我们应该写出外部样式以及其中一个模块的样式。
然后再根据数据源进行渲染,首先我们要渲染多个模块,v-for=“item in list”,然后将图片路径绑定为对应的src,以及输出模块名称。
<div class="box" v-for="item in list">
<img :src="item.src" alt="" width="25" class="img">
<span class="title">{{item.name}}</span>
</div>
然后我们还有一个要求,只渲染名字长度小于四个字的,就需要在代码中增加一个v-if判断渲染与否 v-if=“item.name.length<4”,然后就可以得到你想要的效果,如图:
小实例要点提示:
1.v-for列表渲染
2.v-bind绑定属性,缩写【:】,属性值可以是定义的变量,也可以是列表渲染中的数据
3.v-if条件渲染,简单的判断条件
全部代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>VUE教程</title>
<style>
body {
background-color: #04babe;
}
.content {
width: 370px;
height: auto;
padding-top: 10px;
background-color: #999;
}
.box {
position: relative;
display: inline-block;
width: 170px;
height: 40px;
background-color: white;
margin-top: 10px;
margin-left: 10px;
}
.img {
margin-top: 8px;
margin-left: 5px;
}
.title {
position: absolute;
left: 35px;
line-height: 40px;
}
.title:hover {
color: orange;
cursor: pointer;
}
</style>
</head>
<body>
<div id="app">
<div class="content">
<div class="box" v-for="item in list" v-if="item.name.length<4">
<img :src="item.src" alt="" width="25" class="img">
<span class="title">{{item.name}}</span>
</div>
</div>
</div>
</body>
</html>
<script src="vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
list: [
{
src: 'http://images.gitbook.cn/dd53cb80-1c05-11e7-8187-65a30c956cd7',
name: '前端'
}, {
src: 'http://images.gitbook.cn/4b807350-348a-11e7-8728-a9cb89af1d5d',
name: '移动开发'
}, {
src: 'http://images.gitbook.cn/d5c726d0-b635-11e7-955b-b55efdfa1bf6',
name: '硬件与物联网'
}, {
src: 'http://images.gitbook.cn/45741e20-5bdc-11e7-a916-3bc36c078bd8',
name: '区块链'
}, {
src: 'http://images.gitbook.cn/cc8a9d60-1c05-11e7-8187-65a30c956cd7',
name: '架构'
}, {
src: 'http://images.gitbook.cn/fa6cb380-2b2d-11e7-93f9-893e15f43873',
name: '运维'
}, {
src: 'http://images.gitbook.cn/d5a56510-1c05-11e7-9d4d-1121a99bb498',
name: '大数据'
}, {
src: 'http://images.gitbook.cn/85241c80-1c05-11e7-9d4d-1121a99bb498',
name: '其他'
}]
}
})
</script>
在vue中,列表渲染及条件渲染,都是通过vue的语法使用数据来进行控制的,这样你只需要关注你的数据,不再需要你对其他进行额外的控制。
关于列表渲染及条件渲染是VUE中使用最频繁的功能,希望大家能够彻底掌握本章内容。