vue学习三

监视属性

监视属性就是监视某一属性的变化

使用watch

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!-- 引入Vue -->
    <script src="./js/vue.js">
    </script>
</head>
<body>
    <div class='root'>
        <!-- 点击按钮,显示的数字在1和0之间切换 -->
        现在是{{ans}}
        <button @click='change'>点击切换</button>
    </div>
    <script>
        Vue.config.productionTip=false
        new Vue({
            el:'.root',
            data:{
               is1:true,
               ans:1 
            },
            methods: {
                change(){
                    this.is1=!this.is1
                }
            },
            // 使用监视属性
            watch:{
                // is1是被监视的属性
                is1:{
                    // 初始化时调用Handler
                    //immediate:true,
                    //当is1发生改变了,就会调用Handel
                    // 参数有两个,一个是新的is1的值,一个是旧的is1的值
                    handler(newvalue,oldvalue) {
                        if(this.ans==1){
                            this.ans=0;
                        }else{
                            this.ans=1;
                        }
                    }
                }
            }
        })
    </script>
    
</body>
</html>

深度监视

监视多级结构中某个属性的变化,例如要监视number对象中a的变化,可以使用'number.a':{Handler函数}

当要监视一个多级结构中的所有属性是否发生了变化,可以使用深度监视,即在handle函数前加上deep:true

简写

当配置项中只有Handler函数时,可以使用简写

和计算属性相似

watch:{
    is1(newvalue,oldvalue) {
        if(this.ans==1){
            this.ans=0;
        }else{
            this.ans=1;
        }
    }
}

面临异步操作时,往往选择watch

computed和watch之间的区别

computed能完成的功能,watch都可以完成。
watch能完成的功能,computed不一定能完成,例如:watch可以进行异步操作。
注意:

所被Vue管理的函数,最好写成普通函数,这样this的指向才是vm 或 组件实例对象。
所有不被Vue所管理的函数(定时器的回调函数、ajax的回调函数等、Promise的回调函数),最好写成箭头函数,这样this的指向才是vm 或 组件实例对象。

绑定class样式

可以使用:class='属性名'来动态绑定类名,绑定的类名可以以字符串形式(样式的类名不确定,需要动态指定时),也可以以数组的形式(要绑定的样式、动态、名字都不确定时),还可以使用对象的形式(要绑定的样式、动态、名字都确定,但要动态决定用不用时时),在这种形式中,通过设置类名的值为false或true来设置该类是否被添加

//以数组的形式
classary:['classname1','classname2']
//以类的形式
classobj:{
    classname1:false,
    classname1:true,
}

绑定style

可以使用:style绑定样式,具体使用方法为模版中:style='样式对象名',对象在Vue中定义

条件渲染

在模版中使用v-show可以进行条件渲染,设置是否显示,v-show='false'表示隐藏,也可以写一个判断表达式,还可以写一个变量名(data中的变量)

还可以使用v-if进行条件渲染,设置是否显示。v-if='false'表示隐藏,也可以写一个判断表达式,还可以写一个变量名(data中的变量)。与if、if else、else的逻辑相同,还有v-else-if、v-else,其中if-else后不跟判断条件。注意,使用v-if、v-else-if、v-else时,不允许打断,即中间不能有别的语句。

当使用v-if时,多个标签判断条件一样时,可以使用<template></template>标签将其进行包裹,然后对这个标签进行判断。这个标签不会对样式结构有影响,并且不能使用在v-show。

如果变化频率很高,最好使用v-show。

使用v-show时,不显示的DOM元素没有被移除,仅仅是使用样式隐藏掉。

使用v-if时,不显示的DOM元素被移除

使用v-if时,元素可能无法获取到,而使用v-show时一定可以获取到

列表渲染

基本使用

遍历数组:

<body>
    <div class="root">
        <ul>
            <!-- 使用v-for进行列表渲染 -->
            <!-- 遍历数组 -->
            <!-- v-for里面的语句中的for也可以使用of -->
            <!-- stu是stus数组中的对象,index是stu的索引 -->
            <li v-for='(stu,index) in stus' :key='stu.id'>
                {{stu.name}} {{stu.age}}
            </li>
        </ul>
    </div>
    <script>
        Vue.config.productionTip=false
        new Vue({
            el:'.root',
            data:{
                // stus以数组中存对象的形式展现
                stus:[
                    {id:'000',name:'lili',age:16},
                    {id:'001',name:'Anna',age:17},
                    {id:'002',name:'Tom',age:24},
                ]
            }
        })
    </script>
    
</body>

v-for指令用于展示列表数据
语法:v-for="(item, index) in xxx" :key="yyy"
可以遍历:数组(item, index)、对象(value, key)、字符串((char, index)用的很少)、指定次数((number, index)用的很少)

key的作用与原理

key的作用就是给节点的标识

虚拟DOM中key的作用

key是虚拟DOM对象的标识,当数据发生变化时,Vue会根据【新数据】生成【新的虚拟DOM】, 随后Vue进行【新虚拟DOM】与【旧虚拟DOM】的差异比较

对比规则

(1) 旧虚拟DOM中找到了与新虚拟DOM相同的key:
    ①若虚拟DOM中内容没变, 直接使用之前的真实DOM
    ②若虚拟DOM中内容变了, 则生成新的真实DOM,随后替换掉页面中之前的真实DOM

(2) 旧虚拟DOM中未找到与新虚拟DOM相同的key创建新的真实DOM,随后渲染到到页面。

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

 (1) 若对数据进行:逆序添加、逆序删除等破坏顺序操作: 会产生没有必要的真实DOM更新 ==> 界面效果没问题, 但效率低
  (2) 如果结构中还包含输入类的DOM: 会产生错误DOM更新 ==>界面有问题

开发中如何选择key

(1)最好使用每条数据的唯一标识作为key, 比如id、手机号、身份证号、学号等唯一值。
(2)如果不存在对数据的逆序添加、逆序删除等破坏顺序操作,仅用于渲染列表用于展示,使用index作为key是没有问题的

列表过滤

根据条件过滤列表,筛选出符合条件的列表

使用filter函数

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>列表过滤</title>
		<script type="text/javascript" src="./js/vue.js"></script>
	</head>
	<body>
		<div id="root">
			<h2>人员列表</h2>
			<input type="text" placeholder="请输入名字" v-model="keyWord">
			<ul>
				<li v-for="(p,index) of filPerons" :key="index">
					{{p.name}}-{{p.age}}-{{p.sex}}
				</li>
			</ul>
		</div>

		<script type="text/javascript">
			Vue.config.productionTip = false
			
			//用watch实现
			/* new Vue({
				el:'#root',
				data:{
					keyWord:'',
					persons:[
						{id:'001',name:'马冬梅',age:19,sex:'女'},
						{id:'002',name:'周冬雨',age:20,sex:'女'},
						{id:'003',name:'周杰伦',age:21,sex:'男'},
						{id:'004',name:'温兆伦',age:22,sex:'男'}
					],
					filPerons:[]
				},
				watch:{
					keyWord:{
						immediate:true,
						handler(val){
							this.filPerons = this.persons.filter((p)=>{
								return p.name.indexOf(val) !== -1
							})
						}
					}
				}
			}) */			
			//用computed实现
			new Vue({
				el:'#root',
				data:{
					keyWord:'',
					persons:[
						{id:'001',name:'马冬梅',age:19,sex:'女'},
						{id:'002',name:'周冬雨',age:20,sex:'女'},
						{id:'003',name:'周杰伦',age:21,sex:'男'},
						{id:'004',name:'温兆伦',age:22,sex:'男'}
					]
				},
				computed:{
					filPerons(){
						return this.persons.filter((p)=>{
							return p.name.indexOf(this.keyWord) !== -1
						})
					}
				}
			}) 
		</script>
</html>

列表排序

也是使用计算属性,使用sort方法

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>列表过滤</title>
		<script type="text/javascript" src="./js/vue.js"></script>
	</head>
<body>
    <div id="test">
        <input type="text" v-model="searchName">
        <ul>
            <li v-for="(p, index) in filterPersons" :key="index">
                {{index}}---{{p.name}}---{{p.age}}
            </li>
        </ul>
        <button @click="orderType = 1">年龄升序</button>
        <button @click="orderType = 2">年龄降序</button>
        <button @click="orderType = 0">还原顺序</button>
    </div>
        <script>
            new Vue({
                el: '#test',
                data: {
                    searchName: '',
                    orderType: 0, //0代表原本, 1代表升序, 2代表降序
                    persons: [
                        {name: 'Tom', age: 10},
                        {name: 'Jack', age: 16},
                        {name: 'Rose', age: 12},
                        {name: 'Aka', age: 18}
                    ]
                },
                computed: {
                    filterPersons(){
                        // 2. 对persons进行过滤
                        let fPersons = this.persons.filter(p => p.name.indexOf(this.searchName) !== -1);
                        // 3. 排序
                        if(this.orderType){
                            // 使用sort排序
                            fPersons.sort((p1, p2)=>{
                                // 返回负数p1在前,返回正数p2在前
                                return this.orderType==1 ? p1.age - p2.age : p2.age - p1.age
                            })
                        }
                        return fPersons;
                    }
                },
                methods: {
                    setOrderType(orderType){
                        this.orderType = orderType;
                    }
                }
            })
        </script>
    </body>
</html>
    
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值