绑定class样式与绑定style样式、条件渲染、列表渲染、key作用与原理、列表过滤、列表排序——Vue

目录

一、绑定class样式与绑定style样式

二、条件渲染

三、列表渲染

四、key作用与原理

五、列表过滤

六、列表排序

一、绑定class样式与绑定style样式

绑定样式:

        1.class样式

                写法::class = "xxx"   xxx可以是字符串、对象、数组

                        字符串写法适用于:类名不确定、要动态获取。

                        数组写法适用于:要绑定多个样式,个数不确定,名字也不确定

    <!-- 准备好一个容器 -->
    <div id="root">
        <!-- 数组写法 -->
        <div class="basic" :class="classArr">{{name}}</div>
    </div>

    <script type="text/javascript">
        new Vue({
            el: '#root',
            data: {
                name: '山龟骨',
                classArr: ['atguigu1', 'atguigu2', 'atguigu3']
            },
        })     
    </script>

                        对象写法适用于:要绑定多个样式,个数确定,名字也确定,但不确定用不用。用就将其该对象中的该类名的属性值设置为 true

    <div id="root">
        <!-- 对象写法 -->
        <div class="basic" :class="classObj">{{name}}</div>
    </div>

    <script type="text/javascript">
        new Vue({
            el: '#root',
            data: {
                name: '山龟骨',
                classObj: {
                    atguigu1: false,
                    atguigu2: true,
                    atguigu3: false,

                }
            },
        })     
    </script>

        2. style样式

                :style = "{fontSize: xxx}",对象的写法, 其中xxx是动态值,xxx交给了Vue管理,注意样式使用小驼峰,且将其放在一个对象中

    <!-- 准备好一个容器 -->
    <div id="root">
        <!-- 对象写法 -->
        <div class="basic" :style="{fontSize: fsize + 'px'}">{{name}}</div>
        <div class="basic" :style="styleObj">{{name}}</div>
    </div>

    <script type="text/javascript">
        new Vue({
            el: '#root',
            data: {
                name: '山龟骨',
                fsize: 30,
                styleObj: {
                    fontSize: '40px',
                    color: 'red',
                    backgroundColor: 'orange'
                }
            },
        })     
    </script>

                :style = "[a,b]"  其中a、b是样式对象 ,数组写法,比较少见

    <div id="root">
        <div class="basic" :style="[styleObj,styleObj2]">{{name}}</div>
        <!-- 或者 -->
        <div class="basic" :style="styleArr">{{name}}</div>
    </div>

    <script type="text/javascript">
        new Vue({
            el: '#root',
            data: {
                name: '山龟骨',
                styleObj: {
                    fontSize: '40px',
                    color: 'red',
                },
                styleObj2: {
                    backgroundColor: 'orange'
                },
                styleArr: [
                    {
                        fontSize: '40px',
                        color: 'red',
                    },
                    {
                        backgroundColor: 'orange'
                    }
                ]
            },
        })     
    </script>
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<title>document</title>
	<style>
		.basic{
			width: 400px;
			height: 100px;
			border: 1px solid black;
		}
		.happy{
			background-color: red;
		}
		.sad{
			background-color: gray;
		}
		.normal{
			background-color: skyblue;
		}
		.atguigu1{
			background-color: greenyellow;
		}
		.atguigu2{
			font-size:30px;
		}
		.atguigu3{
			border-radius: 0.5cm;
		}
	</style>
	<!-- <script type="text/javascript" src="../script/vue.js"></script> -->
	<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>	
	<div id="root">
		<!-- 绑定class样式 --字符串写法,适用于:要绑定的样式个数不确定、名字也不确定 -->
		<div class="basic" :class="mood" @click="changeMood">{{name}}</div><br>

		<!-- 绑定class样式 --数组写法,适用于:样式的类名不确定,需要动态指定 -->
		<div class="basic" :class="classArr">{{name}}</div>

		<!-- 绑定class样式 --对象写法,适用于:要绑定的样式的个数确定、名字也确定,
			但要动态决定用不用 -->
		<div class="basic" :class="classObj">{{name}}</div><br>

		<!-- 绑定style样式 --对象写法 -->
		<div class="basic" :style="styleObj">{{name}}</div><br>

		<!-- 绑定style样式 --数组写法 -->
		<div class="basic" :style="[styleObj,styleObj2]">{{name}}</div>
		<!-- 绑定style样式 --数组写法 -->
		<div class="basic" :style="styleArr">{{name}}</div>
	</div>
</body>
<script type="text/javascript">
	Vue.config.productionTip = false
 
	const vm = new Vue({
		el:'#root',
		data:{
			name:'尚硅谷',
			mood:'normal',
			classArr:['atguigu1','atguigu2','atguigu3'],
			classObj:{
				atguigu1:false,
				atguigu2:false,

			},
			styleObj:{
				fontSize:'40px',
				color:'red',
			},
			styleObj2:{
				backgroundColor:'orange'//两个单词注意要写成驼峰写法
			},
			styleArr:[
				{
					fontSize:'40px',
					color:'blue',
				},
				{
					backgroundColor:'gray'
				}
			]
		},
		methods:{
			changeMood(){
				const arr = ['happy','sad','normal']
				const index = Math.floor(Math.random()*3)
				this.mood = arr[index]
			}
		}		
	})
</script>
</html>

二、条件渲染

v-show和v-if的区别——高频面试题

1. v-if

        写法:(1). v-if = "表达式"

                   (2). v-else-if = "表达式"

                   (3). v-else   后面不用跟表达式

        适用于:切换频率较低的场景

        特点:不展示的DOM元素直接被移除,比较耗性能

        注意:v-if 可以和: v-else-if、v-else一起使用,但要求结构不能被“打断”。就是中间不能插入别的代码语句

    <div id="root">
        <!-- 需求: n=1时展示一个div,等于2再展示一个div -->
        <h2>当前的n值是:{{n}}</h2>
        <button @click="n++">点我n++</button>
        <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>hhh</div>  // v-else 后面不用跟表达式
    </div>

    <script type="text/javascript">
        new Vue({
            el: '#root',
            data: {
                n: 0
            },
        })     
    </script>

2.v- show

        写法:v-show="表达式"

        适用于:切换频率较高的场景,

        特点:不展示的DOM元素未被移除,仅仅是使用样式隐藏掉,本质为其添加了内联样式display:none

3.备注:使用v-if时,元素可能无法获取到,而使用v-show元素一定可以获取到。

              template 标签模板最大的特点是不影响结构,只能与v-if配合使用

          写结构的时候,可以使用 template进行包裹,页面渲染时 template不存在

    <div id="root">
        <h2>当前的n值是:{{n}}</h2>
        <button @click="n++">点我n++</button>
        <!-- 当n=1时,三个div全展示 -->
        <!-- 下面写比较麻烦 -->
        <!-- <h2 v-show="n===1">你好</h2>
        <h2 v-show="n===1">尚硅谷</h2>
        <h2 v-show="n===1">背景</h2> -->

        <!-- 下面这样写简单,但是破坏了结构 -->
       <!--  <div v-show="n===1">
            <h2>你好</h2>
            <h2>山龟骨</h2>
            <h2>背景</h2>
        </div> -->

        <!-- 使用template标签包裹,不会破坏结构,但只能配合v-if使用 -->
        <template v-if="n===1">
            <h2>你好</h2>
            <h2>山龟骨</h2>
            <h2>背景</h2>
        </template>
    </div>

    <script type="text/javascript">
        new Vue({
            el: '#root',
            data: {
                n: 0
            },
        })     
    </script>
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<title>document</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===2">欢迎来到{{name}}</h2> -->

		<!-- 使用v-if做条件渲染,确定是否隐藏,并直接将该结构去除了,所以比较耗性能 -->
		<!-- <h2 v-if="false">欢迎来到{{name}}</h2> -->
		<!-- <h2 v-if="1===2">欢迎来到{{name}}</h2> -->

		<!-- <div v-show="n === 1">Angular</div>
		<div v-show="n === 2">React</div>
		<div v-show="n === 3">Vue</div> -->

		<!-- 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> -->
		
		<!-- template模板,最大的特点是不影响结构,只能与v-if配合使用 -->
		<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:'尚硅谷',
			n:0,
		}
	})
</script>
</html>

三、列表渲染

v-for指令

        1.用于展示列表数据

        2.语法:v-for="(item,index) in xxx "  :key="yyy",保证遍历列表数据得到的元素的key不相同即可,所以yyy 可以使用 item.id  或者 index 

        3.可遍历:数组、对象、字符串(用得很少)、指定次数(用得很少)

想生成多个谁,就在谁身上用 v- for指令,就可以生成对应数量的该元素

插值语法中的表达式里面的变量有三个来源:1. data中的属性, 2.计算属性中的属性,3. 标签中的形参

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<title>document</title>
	
	<!-- <script type="text/javascript" src="../script/vue.js"></script> -->
	<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>	
	<div id="root">
		<!-- 遍历数组 -->
		<h2>人员列表(遍历数组)</h2>
		<ul>
			<!-- 保证该ul中每个人的key是不一样的就可,一般两种写法
				1.:key="p.id"
				2.:key="index" -->
			<li v-for="(p,index) in persons" :key="p.id">
				
				{{p.name}}-{{p.age}}
			</li>			
		</ul>

		<!-- 遍历对象 -->
		<h2>汽车信息(遍历对象)</h2>
		<ul>
			<li v-for="(value,k) in car" :key="k">
				{{k}}--{{value}}
			</li>
		</ul>

		<!-- 遍历字符串 -->
		<h2>测试遍历字符串(用得少)</h2>
		<ul>
			<li v-for="(char,index) in str" :key="index">
				{{char}}--{{index}}
			</li>
		</ul>

		<!-- 遍历指定次数 -->
		<h2>测试遍历指定次数(用得少)</h2>
		<ul>
			<li v-for="(number,index) in 5" :key="index">
				{{number}}--{{index}}
			</li>
		</ul>
	</div>
</body>
<script type="text/javascript">
	Vue.config.productionTip = false
 
	const vm = new Vue({
		el:'#root',
		data:{
			persons:[
				{id:'001',name:'张三',age:18},
				{id:'002',name:'李四',age:19},
				{id:'003',name:'王五',age:20}
			],
			car:{
				name:'奥迪A8',
				price:'70万',
				color:'黑色'
			},
			str:'hello'
		}
	})
</script>
</html>

四、key作用与原理

面试题:react、Vue中的key有什么作用?(key的内部原理)

1. 虚拟DOM中key 的作用:

        key 是虚拟DOM对象的标识,当状态中的数据发生变化时,Vue会根据【新数据】生成【新的虚拟DOM】,随后Vue进行【新虚拟DOM】【旧虚拟DOM】的差异比较,比较规则如下:

2.对比规则:

        (1).旧虚拟DOM中找到了与新虚拟DOM相同的 key:

                若虚拟DOM中内容没变,直接使用之前的真实DOM!

                若虚拟DOM中内容变了,则生成新的真实DOM,随后替换掉页面中之前的真实DOM

        (2).旧虚拟DOM中未找到与新虚拟DOM相同的key

                创建新的真实DOM,随后渲染到页面。

3. 用index作为key 可能会引发的问题:

        (1). 若对数据进行: 逆序添加、逆序删除等破坏顺序操作:

                会产生没有必要的真实DOM更新 ==> 界面效果没问题,但效率低。

        (2).如果结构中还包含输入类的DOM(如input框):

                会产生错误DOM更新 ==> 界面有问题。

4.开发中如何选择key?

        (1). 最好使用每条数据的唯一标识作为key,比如id、手机号、身份证号、学号等唯一值。

        (2).如果不存在对数据的逆序添加、逆序删除等破坏性操作,仅用于渲染列表用于展示,使用index作为key是没有问题的。

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<title>document</title>
	<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>	
	<div id="root">
		<h2>人员列表(遍历数组)</h2>
		<button @click.once="add">添加一个老刘</button>
		<ul>
			<li v-for="(p,index) in persons" :key="p.id">				
				{{p.name}}-{{p.age}}
				<input type="text">
			</li>			
		</ul>
	</div>

	<script type="text/javascript">
		Vue.config.productionTip = false
	
		new Vue({
			el:'#root',
			data:{
				persons:[
					{id:'001',name:'张三',age:18},
					{id:'002',name:'李四',age:19},
					{id:'003',name:'王五',age:20}				
				],
			},
			methods:{
				add(){
					const p = {id:'004',name:'老刘',age:40};
					this.persons.unshift(p);
				}
			},
		})
	</script>
</body>
</html>

五、列表过滤(使用监视实现,使用计算属性实现(更方便)

1.使用监视属性实现

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<title>document</title>
	<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>	
	<div id="root">
		<h2>人员列表(遍历数组)</h2>
		<!-- 收集用户的输入 -->
		<input type="text" placeholder="请输入名字" v-model="keyWord">
		<ul>
			<li v-for="(p,index) in filPersons" :key="index">				
				{{p.name}}-{{p.age}}--{{p.gender}}

			</li>			
		</ul>
	</div>

	<script type="text/javascript">
		Vue.config.productionTip = false
	
		new Vue({
			el:'#root',
			data:{
				keyWord:'',
				persons:[
					{id:'001',name:'马冬梅',age:18,gender:'女'},
					{id:'002',name:'周冬雨',age:19,gender:'女'},
					{id:'003',name:'周杰伦',age:20,gender:'男'},				
					{id:'004',name:'温兆伦',age:21,gender:'男'}				
				],
				filPersons:[]
			},
/* 			watch:{
				keyWord(val){
					this.filPersons = this.persons.filter((p)=>{
						// indexOf方法判断一个字符串是否包含指定内容,包含返回其索引位置,不包含返回-1
						return p.name.indexOf(val) !== -1
					})
				}
			} */
			watch:{
				keyWord:{
					immediate:true,
					handler(val){
						this.filPersons = this.persons.filter((p)=>{
							return p.name.indexOf(val) != -1
						})
					}				
				}
			}
		})
	</script>
</body>
</html>

2.使用计算属性实现(更方便)

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<title>document</title>
	<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>	
	<div id="root">
		<h2>人员列表(遍历数组)</h2>
		<!-- 收集用户的输入 -->
		<input type="text" placeholder="请输入名字" v-model="keyWord">
		<ul>
			<li v-for="(p,index) in filPersons" :key="p.id">	
            <!--注意key要使用p.id更好,因为整个操作一直是对列表进行修改-->			
				{{p.name}}-{{p.age}}--{{p.gender}}
			</li>			
		</ul>
	</div>

	<script type="text/javascript">
		Vue.config.productionTip = false

		new Vue({
			el:'#root',
			data:{
				keyWord:'',
				persons:[
					{id:'001',name:'马冬梅',age:18,gender:'女'},
					{id:'002',name:'周冬雨',age:19,gender:'女'},
					{id:'003',name:'周杰伦',age:20,gender:'男'},				
					{id:'004',name:'温兆伦',age:21,gender:'男'}				
				],
			},
			computed:{
				filPersons(){
					return this.persons.filter((p)=>{
						return p.name.indexOf(this.keyWord) !== -1
					})
				}
			}			
		})
	</script>
</body>
</html>

当代码被注释后,在注释代码的下面写新代码,那么被注释的代码无法被折叠,在想折叠的代码上方写#region 想折叠的代码的下方写#endregion

六、列表排序

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<title>document</title>
	<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>	
	<div id="root">
		<h2>人员列表(遍历数组)</h2>
		<!-- 收集用户的输入 -->
		<input type="text" placeholder="请输入名字" v-model="keyWord">
		<button @click="sortType = 2">年龄升序</button>
		<button @click="sortType = 1">年龄降序</button>
		<button @click="sortType = 0">原顺序</button>
		<ul>
			<li v-for="(p,index) in filPersons" :key="p.id">				
				{{p.name}}-{{p.age}}--{{p.gender}}
			</li>			
		</ul>
	</div>

	<script type="text/javascript">
		Vue.config.productionTip = false

		new Vue({
			el:'#root',
			data:{
				keyWord:'',
				persons:[
					{id:'001',name:'马冬梅',age:30,gender:'女'},
					{id:'002',name:'周冬雨',age:19,gender:'女'},
					{id:'003',name:'周杰伦',age:35,gender:'男'},				
					{id:'004',name:'温兆伦',age:50,gender:'男'}				
				],
				sortType:0,//0代表原顺序,1代表降序,2升序
			},
			computed:{
				filPersons(){
					const arr= this.persons.filter((p)=>{
						return p.name.indexOf(this.keyWord) !== -1
					})
					// 判断是否需要排序
					if(this.sortType){
						arr.sort((p1,p2)=>{
							return this.sortType === 1 ? p2.age-p1.age : p1.age-p2.age
						})
					}
					return arr
				}
			}			
		})		
	</script>
</body>
</html>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值