<template>
<div>
<h1>列表渲染</h1>
</div>
<h5>基本渲染</h5>
<hr/>
<div>
<h2>人员列表(遍历数组)</h2>
<ul>
<li v-for="(p,index) in persons" :key="index">
{{p.name}}-{{p.age}} --{{index}}
</li>
<!-- <li>xxx-xxx</li>
<li>xxx-xxx</li> -->
</ul>
<hr/>
<h2>汽车信息(遍历对象)</h2>
<ul>
<li v-for="(val,k) in car" :key="k">
{{k}}-{{val}}
</li>
</ul>
<hr/>
<h2>测试遍历字符串(遍历字符串)</h2>
<ul>
<li v-for="(char,index) in str" :key="index">
{{index}}-{{char}}
</li>
</ul>
<hr/>
<h2>测试遍历指定次数(遍历指定次数)</h2>
<ul>
<li v-for="(number,index) in 5" :key="index">
{{index}}-{{number}}
</li>
</ul>
</div>
v-for 指令<hr/>
1.用于展示列表数据<hr/>
2.语法: v-for="(item, index) in xxx" v-bind:key = "yyy" <hr/>
3.可遍历: 数组、对象、字符串(用的很少)、指定次数(用的很少)<hr/>
<div>
<h1>key的原理</h1>
<h2>人员列表(遍历数组)</h2>
<button v-on:click="add">添加一个老刘</button>
<ul>
<li v-for="(p) in persons" :key="p.id">
{{p.name}}-{{p.age}}
<input type="text">
</li>
<!-- <li>xxx-xxx</li>
<li>xxx-xxx</li> -->
</ul>
<hr/>
面试题: react, vue,中的key有什么作用? (key的内部原理) <hr/>
1.虚拟DOM中key的作用: <hr/>
key是虚拟DOM对象的标识,当状态中的数据发生变化时,Vue会根据[新数据]生成[新的虚拟DOM], <hr/>
随后Vue进行[新虚拟DOM] 与 [旧虚拟DOM]的差异比较,比较规则如下: <hr/>
2.对比规则: <hr/>
(1).旧虚拟DOM中找到了与新虚拟DOM相同的key: <hr/>
①.若虚拟DOM中内容没变,直接使用之前的真实DOM! <hr/>
②.若虚拟DOM中内容变了,则生成新的真实DOM,随后替换页面中之前的真实DOM。 <hr/>
(2).旧虚拟DOM中未找到与新虚拟DOM相同的key <hr/>
创建新的真实DOM,随后渲染到页面。 <hr/>
3.用index作为key可能会引发的问题: <hr/>
1. 若对数据进行:逆序添加,逆序删除等破坏顺序操作: <hr/>
会产生没有必要的真实DOM更新 ==> 界面效果没问题,但效率低 <hr/>
2. 如果结构中还包含输入类的DOM: <hr/>
会产生错误DOM更新 ==> 界面有问题 <hr/>
4.开发中如何选择key? <hr/>
1.最好使用每条数据的唯一标识作为key,比如id,手机号,身份证号,学号等唯一值。 <hr/>
2.如果不存在对数据的逆序添加,逆序删除等破坏顺序操作,仅用于渲染列表用于展示。 <hr/>
使用index作为key是没有问题的。 <hr/>
</div>
</template>
<script>
// import 01_初始Vue from './components.';
export default {
//data的第二种写法:函数式
data() {
// console.log('@@@',this);
return {
persons:[
{id:'001',name:'张山',age:18},
{id:'002',name:'李四',age:19},
{id:'003',name:'王五',age:20},
],
car:{
name:'奥迪a8',
price:'70万',
color:'黑色'
},
str:'hello',
}
},
methods:{
add () {
const p = {id:'004',name:'老刘',age:40}
this.persons.unshift(p)
}
},
computed: {
},
watch: {
}
}
</script>
<style scoped>
</style>
----------------------------------------------------------------------------------------
<template>
<div>
<h1>列表渲染</h1>
</div>
<h5>列表过滤</h5>
<hr/>
<h2>人员列表(watch实现)</h2>
<input type="text" placeholder="请输入名字" v-model="keyWord">
<ul>
<li v-for="(p,index) in filPerons" :key="index">
{{p.name}}-{{p.age}} --{{p.sex}}
</li>
</ul>
<hr/>
<h2>人员列表(computed实现)</h2>
<input type="text" placeholder="请输入名字" v-model="keyWord2">
<ul>
<li v-for="(p,index) in filPerons2" :key="index">
{{p.name}}-{{p.age}} --{{p.sex}}
</li>
</ul>
</template>
<script>
// import 01_初始Vue from './components.';
export default {
//data的第二种写法:函数式
data() {
// console.log('@@@',this);
return {
keyWord:'',
persons:[
{id:'001',name:'马冬梅',age:18,sex:'女'},
{id:'002',name:'周冬雨',age:19,sex:'女'},
{id:'003',name:'周杰伦',age:20,sex:'男'},
{id:'004',name:'温兆伦',age:21,sex:'男'},
],
filPerons:[],
keyWord2:'',
persons2:[
{id:'001',name:'马冬梅',age:18,sex:'女'},
{id:'002',name:'周冬雨',age:19,sex:'女'},
{id:'003',name:'周杰伦',age:20,sex:'男'},
{id:'004',name:'温兆伦',age:21,sex:'男'},
],
}
},
methods:{
add () {
const p = {id:'004',name:'老刘',age:40}
this.persons.unshift(p)
}
},
computed: {
//用computed实现
filPerons2(){
return this.persons2.filter((p)=>{
return p.name.indexOf(this.keyWord2) !== -1
})
}
},
watch: {
// 用watch实现
keyWord:{
immediate:true,
handler (val) {
// console.log(val);
this.filPerons=this.persons.filter((p)=>{
//函数体 indexOf(一个空的字符串返回不是-1是0)
return p.name.indexOf(val) !==-1
})
}
}
}
}
</script>
<style scoped>
</style>
-----------------------------------------------------------------------------------------
<template>
<div>
<h1>列表渲染</h1>
</div>
<h5>列表过滤</h5>
<hr/>
<h2>人员列表(computed实现)</h2>
<input type="text" placeholder="请输入名字" v-model="keyWord2">
<button v-on:click="sortType = 2">年龄升序</button>
<button v-on:click="sortType = 1">年龄降序</button>
<button v-on:click="sortType = 0">原顺序</button>
<ul>
<li v-for="(p) in filPerons2" :key="p.id">
{{p.name}}-{{p.age}} --{{p.sex}}
</li>
</ul>
</template>
<script>
// import 01_初始Vue from './components.';
export default {
//data的第二种写法:函数式
data() {
// console.log('@@@',this);
return {
keyWord2:'',
sortType:0, // 0代表原顺序,1代表降序 2 代表升序
persons2:[
{id:'001',name:'马冬梅',age:30,sex:'女'},
{id:'002',name:'周冬雨',age:35,sex:'女'},
{id:'003',name:'周杰伦',age:18,sex:'男'},
{id:'004',name:'温兆伦',age:20,sex:'男'},
],
}
},
methods:{
},
computed: {
//用computed实现
filPerons2(){
const arr = this.persons2.filter((p)=>{
return p.name.indexOf(this.keyWord2) !== -1
})
// 判断一下是否需要排序
//1 或 2 转成Boolean都是真 0 根本进不来。
if (this.sortType) {
arr.sort((p1,p2)=>{
//函数体
return this.sortType ===1 ? p2.age - p1.age : p1.age -p2.age
})
}
return arr
}
},
watch: {
}
}
// let arr = [1,3,2,6,4,5]
// arr.sort((a,b)=>{
// return a-b
// })
// console.log(arr)
</script>
<style scoped>
</style>
----------------------------------------------------------------------------------------
<template>
<div>
<h1>列表渲染</h1>
</div>
<h5>更新时的一个问题</h5>
<hr/>
<button v-on:click="updateMei">更新马冬梅的信息</button>
<ul>
<li v-for="(p) in persons2" :key="p.id">
{{p.name}}-{{p.age}} --{{p.sex}}
<!-- <input type="text"> -->
</li>
</ul>
</template>
<script>
// import 01_初始Vue from './components.';
export default {
//data的第二种写法:函数式
data() {
// console.log('@@@',this);
return {
persons2:[
{id:'001',name:'马冬梅',age:30,sex:'女'},
{id:'002',name:'周冬雨',age:35,sex:'女'},
{id:'003',name:'周杰伦',age:18,sex:'男'},
{id:'004',name:'温兆伦',age:20,sex:'男'},
],
}
},
methods:{
updateMei () {
// this.persons2[0].name = '马老师' // 奏效
// this.persons2[0].age = '50' // 奏效
// this.persons2[0].sex = '男' // 奏效
this.persons2[0] = {id:'001',name:'马老师',age:50,sex:'男'}
}
},
computed: {
},
watch: {
}
}
</script>
<style scoped>
</style>
----------------------------------------------------------------------------------------
<template>
<div>
<h1>Vue.set的使用</h1>
</div>
<div id="root">
<h2>姓名:{{ name }}</h2>
<h2>地址:{{ address }}</h2>
<hr>
<button v-on:click="addInfo">点我点我快点我</button>
<h5 v-if="question.question2">12180{{question.question2}}</h5>
<h2>问题:{{question.question1}}</h2>
<h2>回答:{{question.answer.answer1}}</h2>
<ul>
<li v-for="(f1,index) in question.friends" v-bind:key="index">
{{f1.name}} -- {{f1.age}}
</li>
</ul>
</div>
</template>
<script>
export default {
//data的第二种写法:函数式
data() {
return {
name: '别怕,反正只能活一次',
address:'人为什么要喝酒,因为不喝酒的时候不快乐,你说我为什么要熬夜因为我的生活是空虚的。',
question:{
question1:'你为什么不在白天去填补你的空虚而非要熬夜来填补你的空虚呢',
// 此处如果在添加一个不确定的属性(后添加的属性不做响应式) Vue.set(target,key,val) vm.$set(target,key,val)
// question2:'为什么就是不喜欢睡觉呢,因为我知道现在我睡了明天的世界又是别人的我又得去拼搏了',
answer:{
answer1:'白天的世界是不属于你的,因为我要睡觉又要工作,我没有时间娱乐'
},
friends:[
{name:'手机',age:'365'},
{name:'电脑',age:'366'}
]
},
}
},
methods:{
addInfo () {
// vue3 此API无
// Vue.set(this.question,'question2','为什么就是不喜欢睡觉呢,因为我知道现在我睡了明天的世界又是别人的我又得去拼搏了')
}
},
computed: {
},
watch: {
}
}
</script>
<style scoped>
</style>
push最后位置 pop删除最后位置 shift删除第一个 unshift第一个添加 splic指定位置添加删除替换 sort对数组进行排序 reverse反转数组
filter不影响原数组 可以过滤完的数组替换原数组 0,1,'你猜'
-----------------------------------------------------------------------------------------
<template>
<div>
<h1>总结</h1>
</div>
<div id="root">
<h1>一个人的信息</h1>
<button @click="student.age++">年龄加1岁</button>
<button @click="addSex" >添加一个性别默认值是男</button>
<button @click="student.sex = '未知'">修改性别</button><br>
<button @click="addFriend" >在列表首位添加一个朋友</button>
<button @click="updataFirstFriendName">修改第一个朋友的名字为老张</button>
<button @click="addHobby">添加一个爱好</button>
<button @click="undateHobby">修改第一个爱好为开车</button>
<button @click="removeSmoke">过滤掉爱好中的抽烟</button>
<h2>姓名:{{ student.name }}</h2>
<h2>年龄:{{ student.age }}</h2>
<h2 v-if="student.sex">性别:{{ student.sex}}</h2>
<hr>
<h3>爱好</h3>
<ul>
<li v-for="(h,index) in student.hobby" v-bind:key="index">
{{h}}
</li>
</ul>
<h3>朋友们</h3>
<ul>
<li v-for="(f,index) in student.friends" v-bind:key="index">
{{f.name}} -- {{f.age}}
</li>
</ul>
</div>
Vue监视数据的原理 <hr/>
1.vue会监视data中所有层次的数据。<hr/>
2.如何监测对象中的数据?<hr/>
通过setter实现监控,且要在new Vue时就传入要监测的数据。<hr/>
(1.)对象中后追加的属性,Vue默认不做响应式处理<hr/>
(2.)如需给后添加的属性做响应式,请使用如下API;<hr/>
Vue.set(target,propertyName/index,value)<hr/>
vm.$set(target,propertyName/index,value)<hr/>
3.如何监测数组中的数据?<hr/>
通过包裹数组更新元素的方法实现,本质就是做了两件事;<hr/>
(1.)调用原生对应的方法对数组进行更新。<hr/>
(2.)重新解析模板,进而更新页面。<hr/>
4.在Vue修改数组中的某个元素一定要用如下方法:<hr/>
1.使用这些API:push(),pop(),shift(),unshift(),splice(),sort(),reverse()<hr/>
2.Vue.set() 或vm.$set()<hr/>
特别注意: Vue.set() 和 vm.$set() 不能给vm 或 vm的根数据对象, 添加属性!!!<hr/>
</template>
<script>
export default {
//data的第二种写法:函数式
data() {
return {
student: {
name:'zhangsan',
age: '18',
hobby:['抽烟','喝酒','打牌'],
friends:[
{name:'李四',age:'19'},
{name:'王五',age:'17'}
]
}
}
},
methods:{
addSex () {
// vue3 此API无
// Vue.set(this.student,'sex','男')
this.$set(this.student,'sex','男')
},
addFriend () {
this.student.friends.unshift({name:'老刘',age:'21'})
},
updataFirstFriendName () {
// 对象. 属性 有get set 数组没有0的get和set但是0本身是一个对象,对象里有属性就有set和get
this.student.friends[0].name = '老张'
this.student.friends[0].age = '6'
},
addHobby () {
this.student.hobby.push('学习')
},
undateHobby () {
this.student.hobby.splice(0,1,"开车") //从第0个开始删除,删除一个在插入一个
// vue3 此API无
// Vue.set(this.student.hobby,'0','开车')
},
removeSmoke () {
this.student.hobby = this.student.hobby.filter((h) =>{
return h !== '抽烟'
})
}
},
computed: {
},
watch: {
}
}
</script>
<style scoped>
</style>
12列表渲染
最新推荐文章于 2024-07-10 21:37:49 发布