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="表达式"

适用于: 切换频率较低的场景。
特点: 不展示的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)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>

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

(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>

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

(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>

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


三、收集表单数据

  • 若: < 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.注册过滤器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>

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

  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值