基本列表
v-for指令
- 用于展示列表數(shù)據(jù)
- 語法:v-for=“(item,index) in xxx” :key=“yyy”
- 可遍歷:數(shù)組,對(duì)象,字符串(用的很少),指定次數(shù)(用的很少)
<div id="root">
<!--遍歷數(shù)組-->
<ul>
<h3>遍歷數(shù)組</h3>
<li v-for="p in persons " :key="p.id">
{{p.name}}-{{p.age}}
</li>
<h3>遍歷數(shù)組-index</h3>
<li v-for="(p,index) in persons" :key="index">
{{p.name}}--{{p.age}}-{{index}}
</li>
</ul>
<!--遍歷對(duì)象-->
<ul>
<h3>遍歷對(duì)象</h3>
<li v-for="(value,k) of car" :key="k">
{{k}}-{{value}}
</li>
</ul>
<!--遍歷字符串-->
<ul>
<h3>遍歷字符串</h3>
<li v-for="(char,index) of str" :key="index">
{{char}}-{{index}}
</li>
</ul>
<!--測(cè)試遍歷指定次數(shù)-->
<ul>
<h3>測(cè)試遍歷指定次數(shù)</h3>
<li v-for="(number,index) of 5" :key="index">
{{number}}-{{index}}
</li>
</ul>
</div>
<script type="text/javascript">
Vue.config.productionTip =false 阻止Vue啟動(dòng)時(shí)生成提示
//創(chuàng)建Vue實(shí)列
const vm=new Vue({
el:'#root', //el 用于指定當(dāng)前Vue實(shí)例未哪個(gè)容器服務(wù),值通常為css選擇器字符串。document.getElementById(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>
Key的作用與原理
原理:
面試題:react. vue中的key有什么用?(key的內(nèi)部原理)
- 虛擬Dom中key的作用:
- key是虛擬DOM對(duì)象的標(biāo)識(shí),檔數(shù)據(jù)發(fā)生改變時(shí),Vue會(huì)根據(jù)【新數(shù)據(jù)】生成【新的虛擬DOM】,
- 隨后Vue進(jìn)行【新虛擬DOM】與【舊虛擬DOM】的差異比較,比較規(guī)則如下:
- 對(duì)比規(guī)則:
(1)舊虛擬DOM中找到了與虛擬DOM相同的key:
1. 若虛擬DOM中內(nèi)容沒有變,直接使用之前的真實(shí)DOM!
2. 若虛擬DOM中內(nèi)容變了,則生成新的真實(shí)DOM,隨后替換掉頁面中之前的真實(shí)DOM
(2)舊虛擬DOM中未找到與新虛擬DOM相同的key
創(chuàng)建新的真實(shí)的DOM。隨后渲染到頁面。 - 用index作為key可能會(huì)引發(fā)的問題:
1. 若對(duì)數(shù)據(jù)進(jìn)行:逆序添加,逆序刪除等破壞順序操作:
會(huì)產(chǎn)生沒有必要的真實(shí)DOM更新==> 界面效果沒問題,但效率低
2.如果結(jié)構(gòu)中還包含輸入類的DOM:
會(huì)產(chǎn)生錯(cuò)誤DOM更新==》界面有問題 - 開發(fā)中如何選擇key
1.最好使用每條數(shù)據(jù)的唯一標(biāo)識(shí)作為key,比如id,手機(jī)號(hào),身份證,學(xué)號(hào)等唯一值。
2.如果不存在對(duì)數(shù)據(jù)的逆序添加,逆序刪除等破壞順序操作。僅用于渲染列表用于展示。
使用index作為leuy是沒有問題的。
<div id="root">
<!--遍歷數(shù)組-->
<h3>遍歷數(shù)組</h3>
<button @click.once="add">添加一個(gè)老劉</button>
<ul>
<li v-for="p in persons " :key="p.id">
{{p.name}}-{{p.age}}
<input type="text">
</li>
</ul>
</div>
<script type="text/javascript">
Vue.config.productionTip =false 阻止Vue啟動(dòng)時(shí)生成提示
//創(chuàng)建Vue實(shí)列
const vm=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>
列表過濾
<!-- 準(zhǔn)備好一個(gè)容器-->
<div id="root">
<h2>人員列表</h2>
<input type="text" placeholder="請(qǐng)輸入名字" 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實(shí)現(xiàn)
//#region
/* 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
})
}
}
}
}) */
//#endregion
//用computed實(shí)現(xiàn)
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>
列表排序
<div id="root">
<h2>人員列表</h2>
<input type="text" placeholder="請(qǐng)輸入名字" v-model="keyWord">
<button @click="sortType = 2">年齡升序</button>
<button @click="sortType = 1">年齡降序</button>
<button @click="sortType = 0">原順序</button>
<ul>
<li v-for="(p,index) of filPerons" :key="p.id">
{{p.name}}-{{p.age}}-{{p.sex}}
<input type="text">
</li>
</ul>
</div>
<script type="text/javascript">
Vue.config.productionTip = false
new Vue({
el:'#root',
data:{
keyWord:'',
sortType:0, //0原順序 1降序 2升序
persons:[
{id:'001',name:'馬冬梅',age:30,sex:'女'},
{id:'002',name:'周冬雨',age:31,sex:'女'},
{id:'003',name:'周杰倫',age:18,sex:'男'},
{id:'004',name:'溫兆倫',age:19,sex:'男'}
]
},
computed:{
filPerons(){
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>
Vue 數(shù)據(jù)監(jiān)視
更新時(shí)的一個(gè)問題
this.persons[0] = {id:‘001’,name:‘馬老師’,age:50,sex:‘男’} 更改data數(shù)據(jù),Vue不監(jiān)聽,模板不改變。
<div id="root">
<h2>人員列表</h2>
<button @click="updateMei">更新馬冬梅的信息</button>
<ul>
<li v-for="(p,index) of persons" :key="p.id">
{{p.name}}-{{p.age}}-{{p.sex}}
</li>
</ul>
</div>
<script type="text/javascript">
Vue.config.productionTip = false
const vm = new Vue({
el:'#root',
data:{
persons:[
{id:'001',name:'馬冬梅',age:30,sex:'女'},
{id:'002',name:'周冬雨',age:31,sex:'女'},
{id:'003',name:'周杰倫',age:18,sex:'男'},
{id:'004',name:'溫兆倫',age:19,sex:'男'}
]
},
methods: {
updateMei(){
// this.persons[0].name = '馬老師' //奏效
// this.persons[0].age = 50 //奏效
// this.persons[0].sex = '男' //奏效
// this.persons[0] = {id:'001',name:'馬老師',age:50,sex:'男'} //不奏效
this.persons.splice(0,1,{id:'001',name:'馬老師',age:50,sex:'男'})
}
}
})
</script>
模擬數(shù)據(jù)監(jiān)測(cè):
<script type="text/javascript" >
let data = {
name:'尚硅谷',
address:'北京',
}
//創(chuàng)建一個(gè)監(jiān)視的實(shí)例對(duì)象,用于監(jiān)視data中屬性的變化
const obs = new Observer(data)
console.log(obs)
//準(zhǔn)備一個(gè)vm實(shí)例對(duì)象
let vm = {}
vm._data = data = obs
function Observer(obj){
//匯總對(duì)象中所有的屬性形成一個(gè)數(shù)組
const keys = Object.keys(obj)
//遍歷
keys.forEach((k)=>{
Object.defineProperty(this,k,{
get(){
return obj[k]
},
set(val){
console.log(`${k}被改了,我要去解析模板,生成虛擬DOM.....我要開始忙了`)
obj[k] = val
}
})
})
}
</script>
原理
Vue監(jiān)視數(shù)據(jù)的原理:
-
vue會(huì)監(jiān)視data中所有層次的數(shù)據(jù)。
-
如何監(jiān)測(cè)對(duì)象中的數(shù)據(jù)?
通過setter實(shí)現(xiàn)監(jiān)視,且要在new Vue時(shí)就傳入要監(jiān)測(cè)的數(shù)據(jù)。
(1).對(duì)象中后追加的屬性,Vue默認(rèn)不做響應(yīng)式處理
(2).如需給后添加的屬性做響應(yīng)式,請(qǐng)使用如下API:
Vue.set(target,propertyName/index,value) 或
vm.$set(target,propertyName/index,value) -
如何監(jiān)測(cè)數(shù)組中的數(shù)據(jù)?
通過包裹數(shù)組更新元素的方法實(shí)現(xiàn),本質(zhì)就是做了兩件事:
(1).調(diào)用原生對(duì)應(yīng)的方法對(duì)數(shù)組進(jìn)行更新。
(2).重新解析模板,進(jìn)而更新頁面。 -
在Vue修改數(shù)組中的某個(gè)元素一定要用如下方法:
1.使用這些API:push()、pop()、shift()、unshift()、splice()、sort()、reverse()
2.Vue.set() 或 vm.$set()
特別注意:Vue.set() 和 vm.$set() 不能給vm 或 vm的根數(shù)據(jù)對(duì)象 添加屬性!??!文章來源:http://www.zghlxwxcb.cn/news/detail-424253.html
<body>
<!-- 準(zhǔn)備好一個(gè)容器-->
<div id="root">
<h1>學(xué)生信息</h1>
<button @click="student.age++">年齡+1歲</button> <br/>
<button @click="addSex">添加性別屬性,默認(rèn)值:男</button> <br/>
<button @click="student.sex = '未知' ">修改性別</button> <br/>
<button @click="addFriend">在列表首位添加一個(gè)朋友</button> <br/>
<button @click="updateFirstFriendName">修改第一個(gè)朋友的名字為:張三</button> <br/>
<button @click="addHobby">添加一個(gè)愛好</button> <br/>
<button @click="updateHobby">修改第一個(gè)愛好為:開車</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 在啟動(dòng)時(shí)生成生產(chǎn)提示。
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('學(xué)習(xí)')
},
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>
文章來源地址http://www.zghlxwxcb.cn/news/detail-424253.html
到了這里,關(guān)于【Vue】學(xué)習(xí)筆記-列表渲染/數(shù)據(jù)監(jiān)視的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!