• Vue基础知识(条件渲染、列表渲染、收集表单数据、过滤器)(三)


    系列文章目录

    第一章:Vue基础知识笔记(模板语法、数据绑定、事件处理、计算属性)(一)
    第二章:Vue基础知识(计算属性、监视属性、computed和watch之间的区别、绑定样式)(二)
    第四章:Vue基础知识(内置指令、自定义指令、Vue生命周期)(四)
    第五章:Vue基础知识之组件机制(非单文件组件、单文件组件)(五)
    第六章:Vue创建脚手架(六)
    第七章:Vue使用脚手架(ref、props、mixin、插件、scoped)(七)
    第八章:Vue组件通信(组件的自定义事件、全局事件总线、消息订阅与发布、插槽、props)(八)
    第九章:Vue使用脚手架(nextTick、Vue封装的过度与动画、vue脚手架配置代理)(九)
    第十章:Vuex(十)
    第十一章:vue-router(基本使用、路由重定向、多级路由、路由命名、路由的query和params参数、路由的props配置)(十一)
    第十二章:vue-router(路由的两种工作模式、router-link的replace属性、编程式路由导航、缓存路由组件keep-alive、路由守卫【全局路由守卫、独享路由守卫、组件内路由守卫】)(十二)
    第十三章:Vue组件通信二&数据同步(v-model、属性修饰符.sync、 a t t r s 与 attrs与 attrslisteners、refs. c h i l d r e n 与 r e f s . children与refs. childrenrefs.parent、provide与inject )(十三)



    一、条件渲染

    1.v-if
    写法:

     v-if="表达式" 
     v-else-if="表达式"
     v-else="表达式"
    
    • 1
    • 2
    • 3

    适用于: 切换频率较低的场景。
    特点: 不展示的DOM元素直接被移除。
    注意: v-if可以和:v-else-if、v-else一起使用,但要求结构不能被“打断”。

    2.v-show
    写法:v-show=“表达式”
    适用于:切换频率较高的场景。
    特点:不展示的DOM元素未被移除,仅仅是使用样式display:node隐藏

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

    案例:

    <body>
        <div id="root">
            <h2>当前的n值是:{{n}}</h2>
            <button @click="n++">点我n+1</button>
            <!-- 使用v-show做条件渲染 -->
            <h2 v-show="n === 1">欢迎来到{{name}}</h2>
    
            <!-- 使用v-if做条件渲染 -->
            <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 v-if="n === 0">
    				<h2>你好</h2>
    				
    			</template>
    
        </div>
    </body>
    
    <script type="text/javascript">
        Vue.config.productionTip = false
    
        const vm = new Vue({
            el: '#root',
            data: {
                name: '广西',
                n: 0
            }
        })
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    运行结果:
    在这里插入图片描述
    在这里插入图片描述


    二、列表渲染

    (1)v-for指令

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

    案例:

    	<div id="root">
    			<!-- 遍历数组 -->
    			<h2>人员列表(遍历数组)</h2>
    			<ul>
    				<li v-for="(p,index) of persons" :key="index">
    					{{p.name}}-{{p.age}}
    				</li>
    			</ul>
    
    			<!-- 遍历对象 -->
    			<h2>汽车信息(遍历对象)</h2>
    			<ul>
    				<li v-for="(value,k) of car" :key="k">
    					{{k}}-{{value}}
    				</li>
    			</ul>
    
    			<!-- 遍历字符串 -->
    			<h2>测试遍历字符串(用得少)</h2>
    			<ul>
    				<li v-for="(char,index) of str" :key="index">
    					{{char}}-{{index}}
    				</li>
    			</ul>
    			
    			<!-- 遍历指定次数 -->
    			<h2>测试遍历指定次数(用得少)</h2>
    			<ul>
    				<li v-for="(number,index) of 5" :key="index">
    					{{index}}-{{number}}
    				</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}
    					],
    					car:{
    						name:'奥迪A8',
    						price:'70万',
    						color:'黑色'
    					},
    					str:'hello'
    				}
    			})
    		</script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54

    运行结果:
    在这里插入图片描述

    (2)key的原理

    面试题:react、vue中的key有什么作用?(key的内部原理)
    1. 虚拟DOM中key的作用:
    key是虚拟DOM对象的标识,当数据发生变化时,Vue会根据【新数据】生成【新的虚拟DOM】, 随后Vue进行【新虚拟DOM】与【旧虚拟DOM】的差异比较,比较规则如下:

    2.对比规则:

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

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

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

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

    4. 开发中如何选择key?:

    • 最好使用每条数据的唯一标识作为key, 比如id、手机号、身份证号、学号等唯一值。
    • 如果不存在对数据的逆序添加、逆序删除等破坏顺序操作,仅用于渲染列表用于展示,使用index作为key是没有问题的。
      案例:
    <body>
        <div id="root">
            <!-- 遍历数组 -->
            <h2>人员列表(遍历数组)</h2>
            <button @click.once="add">添加一个老刘</button>
            <ul>
                <li v-for="(p,index) of persons" :key="index">
                    {{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>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    运行结果:
    在这里插入图片描述
    在这里插入图片描述
    解析:
    在这里插入图片描述

    (3)数据监测

    Vue监视数据的原理:

    • vue会监视data中所有层次的数据

    2. 如何监测对象中的数据?
    通过setter实现监视,且要在new Vue时就传入要监测的数据。

    • 对象中后追加的属性,Vue默认不做响应式处理

    • 如需给后添加的属性做响应式,请使用如下API:
      Vue.set(target,propertyName/index,value)
      vm.$set(target,propertyName/index,value)

    3. 如何监测数组中的数据?
    通过包裹数组更新元素的方法实现,本质就是做了两件事:

    • 调用原生对应的方法对数组进行更新。
    • 重新解析模板,进而更新页面。

    4.在Vue修改数组中的某个元素一定要用如下方法

    • 使用这些API:push()、pop()、shift()、unshift()、splice()、sort()、reverse()
    • Vue.set() vm.$set()

    特别注意: Vue.set() 和 vm.$set() 不能给vm 或 vm的根数据对象 添加属性!!!

    案例:

    <body>
    	<div id="root">
    		<h1>学生信息</h1>
    		<!-- <button @click="student.age++">年龄+1</button> <br /> -->
    		<button @click="addSex">添加性别属性,默认值:男</button> <br />
    		<!-- <button @click="student.sex = '未知' ">修改性别</button> <br /> -->
    		<button @click="addFriend">在列表首位添加一个朋友</button> <br />
    		<button @click="updateFirstFriendName">修改第一个朋友的名字为:张三</button> <br />
    		<button @click="addHobby">添加一个爱好</button> <br />
    		<button @click="updateHobby">修改第一个爱好为:开车</button> <br />
    		<button @click="removeSmoke">过滤掉爱好中的抽烟</button> <br />
    		<h3>姓名:{{student.name}}</h3>
    		<h3>年龄:{{student.age}}</h3>
    		<h3 v-if="student.sex">性别:{{student.sex}}</h3>
    		<h3>爱好:</h3>
    		<ul>
    			<li v-for="(h,index) in student.hobby" :key="index">
    				{{h}}
    			</li>
    		</ul>
    		<h3>朋友们:</h3>
    		<ul>
    			<li v-for="(f,index) in student.friends" :key="index">
    				{{f.name}}--{{f.age}}
    			</li>
    		</ul>
    	</div>
    </body>
    
    <script type="text/javascript">
    	Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
    
    	const vm = new Vue({
    		el: '#root',
    		data: {
    			student: {
    				name: 'tom',
    				age: 18,
    				hobby: ['抽烟', '喝酒', '烫头'],
    				friends: [
    					{ name: 'jerry', age: 35 },
    					{ name: 'tony', age: 36 }
    				]
    			}
    		},
    		methods: {
    			addSex() {
    				// Vue.set(this.student,'sex','男')
    				this.$set(this.student, 'sex', '男')
    			},
    			addFriend() {
    				this.student.friends.unshift({ name: 'jack', age: 70 })
    			},
    			updateFirstFriendName() {
    				this.student.friends[0].name = '张三'
    			},
    			addHobby() {
    				this.student.hobby.push('学习')
    			},
    			updateHobby() {
    				// this.student.hobby.splice(0,1,'开车')
    				// Vue.set(this.student.hobby,0,'开车')
    				this.$set(this.student.hobby, 0, '开车')
    			},
    			removeSmoke() {
    				this.student.hobby = this.student.hobby.filter((h) => {
    					return h !== '抽烟'
    				})
    			}
    		}
    	})
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72

    运行结果:
    修改前:
    在这里插入图片描述
    修改后:
    在这里插入图片描述


    三、收集表单数据

    • 若: < input type="text"/>,则v-model收集的是value值,用户输入的就是value值。
    • 若:< input type="radio"/>,则v-model收集的是value值,且要给标签配置value值。
    • 若:< input type="checkbox"/>,则
      • 没有配置input的value属性,那么收集的就是checked(勾选 or 未勾选,是布尔值)
      • 配置input的value属性:
        (1)v-model的初始值是非数组,那么收集的就是checked(勾选 or 未勾选,是布尔值)
        (2)v-model的初始值是数组,那么收集的的就是value组成的数组

    备注: v-model的三个修饰符
    lazy失去焦点再收集数据
    number输入字符串转为有效的数字
    trim输入首尾空格过滤

    案例

    	<body>
    		<div id="root">
    			<form @submit.prevent="demo">
    				账号:<input type="text" v-model.trim="userInfo.account"> <br/><br/>
    				密码:<input type="password" v-model="userInfo.password"> <br/><br/>
    				年龄:<input type="number" v-model.number="userInfo.age"> <br/><br/>
    				性别:
    				男<input type="radio" name="sex" v-model="userInfo.sex" value="male"><input type="radio" name="sex" v-model="userInfo.sex" value="female"> <br/><br/>
    				爱好:
    				学习<input type="checkbox" v-model="userInfo.hobby" value="study">
    				打游戏<input type="checkbox" v-model="userInfo.hobby" value="game">
    				吃饭<input type="checkbox" v-model="userInfo.hobby" value="eat">
    				<br/><br/>
    				所属校区
    				<select v-model="userInfo.city">
    					<option value="">请选择校区</option>
    					<option value="beijing">北京</option>
    					<option value="shanghai">上海</option>
    					<option value="shenzhen">深圳</option>
    					<option value="wuhan">武汉</option>
    				</select>
    				<br/><br/>
    				其他信息:
    				<textarea v-model.lazy="userInfo.other"></textarea> <br/><br/>
    				<input type="checkbox" v-model="userInfo.agree">阅读并接受<a href="http://www.atguigu.com">《用户协议》</a>
    				<button>提交</button>
    			</form>
    		</div>
    	</body>
    
    	<script type="text/javascript">
    		Vue.config.productionTip = false
    
    		new Vue({
    			el:'#root',
    			data:{
    				userInfo:{
    					account:'',
    					password:'',
    					age:18,
    					sex:'female',
    					hobby:[],
    					city:'beijing',
    					other:'',
    					agree:''
    				}
    			},
    			methods: {
    				demo(){
    					console.log(JSON.stringify(this.userInfo))
    				}
    			}
    		})
    	</script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55

    运行结果:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    点击提交后的数据
    在这里插入图片描述


    四、过滤器

    定义: 对要显示的数据进行特定格式化后再显示(适用于一些简单逻辑的处理)。
    语法:
    1.注册过滤器Vue.filter(name,callback) new Vue{filters:{}}
    2.使用过滤器:{{ xxx | 过滤器名}}v-bind:属性 = "xxx | 过滤器名"
    备注:
    1.过滤器也可以接收额外参数、多个过滤器也可以串联
    2.并没有改变原本的数据, 是产生新的对应的数据

    案例:

    <body>
    
        <div id="root">
            <h2>显示格式化后的时间</h2>
            <!-- 计算属性实现 -->
            <h3>现在是:{{fmtTime}}</h3>
            <!-- methods实现 -->
            <h3>现在是:{{getFmtTime()}}</h3>
            <!-- 过滤器实现 -->
            <h3>现在是:{{time | timeFormater}}</h3>
            <!-- 过滤器实现(传参) -->
            <h3>现在是:{{time | timeFormater('YYYY_MM_DD') | mySlice}}</h3>
            <h3 :x="msg | mySlice">天安门</h3>
        </div>
    
        <div id="root2">
            <h2>{{msg | mySlice}}</h2>
        </div>
    </body>
    
    <script type="text/javascript">
        Vue.config.productionTip = false
            //全局过滤器
        Vue.filter('mySlice', function(value) {
            return value.slice(0, 4)
        })
    
        new Vue({
            el: '#root',
            data: {
                time: 1621561377603, //时间戳
                msg: '你好,天安门'
            },
            computed: {
                fmtTime() {
                    return dayjs(this.time).format('YYYY年MM月DD日 HH:mm:ss')
                }
            },
            methods: {
                getFmtTime() {
                    return dayjs(this.time).format('YYYY年MM月DD日 HH:mm:ss')
                }
            },
            //局部过滤器
            filters: {
                timeFormater(value, str = 'YYYY年MM月DD日 HH:mm:ss') {
                    // console.log('@',value)
                    return dayjs(value).format(str)
                }
            }
        })
    
        new Vue({
            el: '#root2',
            data: {
                msg: 'hello,atguigu!'
            }
        })
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59

    运行结果:
    在这里插入图片描述

  • 相关阅读:
    STM32内部flash详解(1)
    偶数科技发布 OushuDB 5.0,多活主节点、多虚拟集群等特性完美支持实时湖仓一体
    SpringBoot文件上传下载
    PTA 7-185 组个最小数
    C++入门介绍之“栈”
    卷积神经网络 图像识别,卷积神经网络车辆识别
    JavaScript:实现ExponentialSearch指数搜索算法(附完整源码)
    除铜树脂-KF340
    flinkcdc监控sqlserver,数据库的表中该字段是空值,而cdc中该字段的值是'N,不一致
    软件测试: 测试用例
  • 原文地址:https://blog.csdn.net/qq_48617322/article/details/126440866