學(xué)習(xí)鏈接:尚硅谷Vue2.0+Vue3.0全套教程丨vuejs從入門到精通,本文對應(yīng)p26-p52,博客參考尚硅谷公開筆記,補(bǔ)充記錄實(shí)操。
??class與style綁定
- 在應(yīng)用界面中, 某個(gè)(些)元素的樣式是變化的。
- class/style 綁定就是專門用來實(shí)現(xiàn)動態(tài)樣式效果的技術(shù)。
- class樣式
- 寫法:
class="xxx"
,xxx可以是字符串、對象、數(shù)組。 - 字符串寫法適用于:類名不確定,要?jiǎng)討B(tài)獲取。
- 對象寫法適用于:要綁定多個(gè)樣式,個(gè)數(shù)不確定,名字也不確定。
- 數(shù)組寫法適用于:要綁定多個(gè)樣式,個(gè)數(shù)確定,名字也確定,但不確定用不用。
- 寫法:
- style樣式
-
:style="{fontSize: xxx}"
其中xxx是動態(tài)值。 -
:style="[a,b]"
其中a、b是樣式對象。
-
- 所有不變化的東西正常寫,變化的東西用
:
綁定,動態(tài)調(diào)整。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>綁定樣式</title>
<style>
.basic{
width: 400px;
height: 100px;
border: 1px solid black;
}
.happy{
border: 4px solid red;;
background-color: rgba(255, 255, 0, 0.644);
background: linear-gradient(30deg,yellow,pink,orange,yellow);
}
.sad{
border: 4px dashed rgb(2, 197, 2);
background-color: gray;
}
.normal{
background-color: skyblue;
}
.atguigu1{
background-color: yellowgreen;
}
.atguigu2{
font-size: 30px;
text-shadow:2px 2px 10px red;
}
.atguigu3{
border-radius: 20px;
}
</style>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<!-- 準(zhǔn)備好一個(gè)容器-->
<div id="root">
<!-- 綁定class樣式--字符串寫法,適用于:樣式的類名不確定,需要?jiǎng)討B(tài)指定 -->
<div class="basic" :class="mood" @click="changeMood">{{name}}</div> <br/><br/>
<!-- 綁定class樣式--數(shù)組寫法,適用于:要綁定的樣式個(gè)數(shù)不確定、名字也不確定 -->
<div class="basic" :class="classArr">{{name}}</div> <br/><br/>
<!-- 綁定class樣式--對象寫法,適用于:要綁定的樣式個(gè)數(shù)確定、名字也確定,但要?jiǎng)討B(tài)決定用不用 -->
<div class="basic" :class="classObj">{{name}}</div> <br/><br/>
<!-- 綁定style樣式--對象寫法 -->
<div class="basic" :style="styleObj">{{name}}</div> <br/><br/>
<!-- 綁定style樣式--數(shù)組寫法 -->
<div class="basic" :style="styleArr">{{name}}</div>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false
const vm = new Vue({
el:'#root',
data:{
name:'lalayouyi',
mood:'normal',
classArr:['atguigu1','atguigu2','atguigu3'],
classObj:{
atguigu1:false,
atguigu2:false,
},
styleObj:{
fontSize: '40px',
color:'red',
},
styleObj2:{
backgroundColor:'orange'
},
styleArr:[
{
fontSize: '40px',
color:'blue',
},
{
backgroundColor:'gray'
}
]
},
methods: {
changeMood(){
const arr = ['happy','sad','normal']
// floor向下取整,隨機(jī)生成0,1,2,實(shí)現(xiàn)樣式隨機(jī)切換
const index = Math.floor(Math.random()*3)
this.mood = arr[index]
}
},
})
</script>
</html>
借助Vue開發(fā)者工具,實(shí)現(xiàn)動態(tài)樣式調(diào)整。實(shí)操見真知??
??條件渲染
-
v-if
- (1).
v-if="表達(dá)式"
- (2).
v-else-if="表達(dá)式"
- (3).
v-else="表達(dá)式"
- 適用于:切換頻率較低的場景。
- 特點(diǎn):不展示的DOM元素直接被移除。
- 注意:
v-if
可以和v-else-if
、v-else
一起使用,但要求結(jié)構(gòu)不能被“打斷”。
- (1).
-
v-show
- 寫法:
v-show="表達(dá)式"
- 適用于:切換頻率較高的場景。
- 特點(diǎn):不展示的DOM元素未被移除,僅僅是使用樣式隱藏掉。
- 寫法:
- 備注:使用
v-if
時(shí),元素可能無法獲取到,而使用v-show
一定可以獲取到。 -
v-if
可與template
的配合使用,使得不用引入div
包裹,從而不影響結(jié)構(gòu)((v-show不行)。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>條件渲染</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<!-- 準(zhǔn)備好一個(gè)容器-->
<div id="root">
<!-- 使用v-show做條件渲染 -->
<h2 v-show="false">歡迎來到{{name}}1.1</h2>
<h2 v-show="1 === 1">歡迎來到{{name}}1.2</h2>
<!-- 使用v-if做條件渲染 -->
<h2 v-if="false">歡迎來到{{name}}1.3</h2>
<h2 v-if="1 === 1">歡迎來到{{name}}1.4</h2>
<h2>當(dāng)前的n值是:{{n}}</h2>
<button @click="n++">點(diǎn)我n+1</button>
<!-- 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>lalalala</div>
<!-- v-if(v-show不行)與template的配合使用(不影響結(jié)構(gòu)) -->
<template v-if="n === 1">
<h2>你好</h2>
<h2>lala</h2>
<h2>youyi</h2>
</template>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false
const vm = new Vue({
el:'#root',
data:{
name:'lalayouyi',
n:0
}
})
</script>
</html>
??列表渲染
??基本列表
-
v-for
指令:- 用于展示列表數(shù)據(jù)
- 語法:
v-for="(item, index) in xxx" :key="yyy"
- 可遍歷:數(shù)組、對象、字符串(用的很少)、指定次數(shù)(用的很少)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>基本列表</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<!-- 準(zhǔn)備好一個(gè)容器-->
<div id="root">
<!-- 遍歷數(shù)組 -->
<h2>人員列表(遍歷數(shù)組)</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>
<!-- 遍歷指定次數(shù) -->
<h2>測試遍歷指定次數(shù)(用得少)</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:'lala',age:18},
{id:'002',name:'youyi',age:19},
{id:'003',name:'tutu',age:20}
],
car:{
name:'瑪卡巴卡',
price:'兩塊',
color:'粉色'
},
str:'youyi'
}
})
</script>
</html>
??key的原理
- ??虛擬DOM中key的作用:key是虛擬DOM對象的標(biāo)識,當(dāng)數(shù)據(jù)發(fā)生變化時(shí),Vue會根據(jù)【新數(shù)據(jù)】生成【新的虛擬DOM】, 隨后Vue進(jìn)行【新虛擬DOM】與【舊虛擬DOM】的差異比較,比較規(guī)則如下:
-
舊虛擬DOM中找到了與新虛擬DOM相同的key:
- ①.若虛擬DOM中內(nèi)容沒變, 直接使用之前的真實(shí)DOM!
- ②.若虛擬DOM中內(nèi)容變了, 則生成新的真實(shí)DOM,隨后替換掉頁面中之前的真實(shí)DOM。
- 舊虛擬DOM中未找到與新虛擬DOM相同的key:創(chuàng)建新的真實(shí)DOM,隨后渲染到到頁面。
-
舊虛擬DOM中找到了與新虛擬DOM相同的key:
-
??用index作為key可能會引發(fā)的問題:
-
若對數(shù)據(jù)進(jìn)行:逆序添加、逆序刪除等破壞順序操作:會產(chǎn)生沒有必要的真實(shí)DOM更新 ==> 界面效果沒問題, 但效率低。
-
如果結(jié)構(gòu)中還包含輸入類的DOM:會產(chǎn)生錯(cuò)誤DOM更新 ==> 界面有問題。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>key的原理</title> <script type="text/javascript" src="../js/vue.js"></script> </head> <body> <!-- 準(zhǔn)備好一個(gè)容器--> <div id="root"> <!-- 遍歷數(shù)組 --> <h2>人員列表(遍歷數(shù)組)</h2> <button @click.once="add">添加一個(gè)貓貓</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:'lala',age:18}, {id:'002',name:'youyi',age:19}, {id:'003',name:'tutu',age:20} ] }, methods: { add(){ const p = {id:'004',name:'maomao',age:13} // 前序添加 this.persons.unshift(p) } }, }) </script> </html>
-
若把
key
設(shè)置為p.id
,則不會出現(xiàn)上述混亂。
-
-
??開發(fā)中如何選擇key?
- 最好使用每條數(shù)據(jù)的唯一標(biāo)識作為key,比如id、手機(jī)號、身份證號、學(xué)號等唯一值。
- 如果不存在對數(shù)據(jù)的逆序添加、逆序刪除等破壞順序操作,僅用于渲染列表用于展示,使用index作為key是沒有問題的。
??列表過濾(搜索)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>列表過濾</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<!-- 準(zhǔn)備好一個(gè)容器-->
<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實(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:'男'}
],
// 開新數(shù)組避免對原數(shù)據(jù)的影響
filPerons:[]
},
watch:{
keyWord:{
// 初始回調(diào)使得列表顯現(xiàn)
// 所有字符串都包含空字符串
// 'abcde'.indexOf('')為0,不是-1!
// 'abcde'.indexOf('a')也為0
immediate:true,
handler(val){
this.filPerons = this.persons.filter((p)=>{
return p.name.indexOf(val) !== -1
})
}
}
}
}) */
//用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>
</html>
??列表排序
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>列表排序</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<!-- 準(zhǔn)備好一個(gè)容器-->
<div id="root">
<h2>人員列表</h2>
<input type="text" placeholder="請輸入名字" v-model="keyWord">
<button @click="sortType = 2">年齡升序</button>
<button @click="sortType = 1">年齡降序</button>
<button @click="sortType = 0">復(fù)原</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>
</html>
- 升序
- 降序
- 復(fù)原(因?yàn)樵瓟?shù)據(jù)本身根本不動)
??Vue數(shù)據(jù)監(jiān)測
-
??更新時(shí)的一個(gè)問題:需求是修改馬冬梅。用
this.persons[0] = {id:'001',name:'馬老師',age:50,sex:'男'}
語句,點(diǎn)擊按鈕后不奏效,Vue沒有監(jiān)測到數(shù)據(jù)改變?。ń鉀Q辦法見后文??)<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>更新時(shí)的一個(gè)問題</title> <script type="text/javascript" src="../js/vue.js"></script> </head> <body> <!-- 準(zhǔn)備好一個(gè)容器--> <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:'男'} //不奏效,因?yàn)閂ue沒檢測到 } } }) </script> </html>
-
??模擬一個(gè)數(shù)據(jù)監(jiān)測
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>Document</title> </head> <body> <script type="text/javascript" > let data = { name:'山東大學(xué)', address:'山東', } //創(chuàng)建一個(gè)監(jiān)視的實(shí)例對象,用于監(jiān)視data中屬性的變化 const obs = new Observer(data) console.log(obs) //準(zhǔn)備一個(gè)vm實(shí)例對象 let vm = {} vm._data = data = obs function Observer(obj){ //匯總對象中所有的屬性形成一個(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> </body> </html>
-
??
Vue.set
的使用-
Vue.set
方法允許我們通過指定鍵和值來向響應(yīng)式對象添加新屬性,同時(shí)確保添加的屬性也是響應(yīng)式的。這樣,當(dāng)新屬性發(fā)生變化時(shí),Vue將能夠正確地進(jìn)行依賴追蹤和重新渲染。 -
Vue.set
的使用方法如下:Vue.set(obj, key, value)
,其中obj是要添加屬性的對象,key是屬性名,value是屬性值。 - ??只能給data里的某一個(gè)對象添加屬性,而不能直接給data添加屬性。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>Vue監(jiān)測數(shù)據(jù)改變的原理</title> <!-- 引入Vue --> <script type="text/javascript" src="../js/vue.js"></script> </head> <body> <!-- 準(zhǔn)備好一個(gè)容器--> <div id="root"> <h1>學(xué)生信息</h1> <button @click="addSex">添加一個(gè)性別屬性,默認(rèn)值是男</button> <h2>姓名:{{student.name}}</h2> <h2 v-if="student.sex">性別:{{student.sex}}</h2> <h2>年齡:真實(shí){{student.age.rAge}},對外{{student.age.sAge}}</h2> <h2>朋友們</h2> <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 const vm = new Vue({ el:'#root', data:{ student:{ name:'tom', age:{ rAge:22, sAge:20, }, friends:[ {name:'Tracy',age:20}, {name:'lily',age:19} ] } }, methods: { addSex(){ // 后天添加實(shí)現(xiàn)響應(yīng)式 Vue.set(this.student,'sex','男') //以下語句同理,實(shí)現(xiàn)效果一樣 //this.$set(this.student,'sex','男') } } }) </script> </html>
-
??Vue監(jiān)測數(shù)據(jù)改變的原理_對象
??Vue監(jiān)測數(shù)據(jù)改變的原理_數(shù)組
- ??小結(jié):Vue監(jiān)視數(shù)據(jù)的原理:
- vue會監(jiān)視data中所有層次的數(shù)據(jù)。
-
如何監(jiān)測對象中的數(shù)據(jù)?
- 通過setter實(shí)現(xiàn)監(jiān)視,且要在new Vue時(shí)就傳入要監(jiān)測的數(shù)據(jù)。
- (1).對象中后追加的屬性,Vue默認(rèn)不做響應(yīng)式處理
- (2).如需給后添加的屬性做響應(yīng)式,請使用如下API:
Vue.set(target,propertyName/index,value)
或vm.$set(target,propertyName/index,value)
。
-
如何監(jiān)測數(shù)組中的數(shù)據(jù)?
- 通過包裹數(shù)組更新元素的方法實(shí)現(xiàn),本質(zhì)就是做了兩件事:
- (1).調(diào)用原生對應(yīng)的方法對數(shù)組進(jìn)行更新。
- (2).重新解析模板,進(jìn)而更新頁面。
-
??在Vue修改數(shù)組中的某個(gè)元素一定要用如下方法:
- ①使用這些API:
push()
、pop()
、shift()
、unshift()
、splice()
、sort()
、reverse()
- ②
Vue.set()
或vm.$set()
- ①使用這些API:
- 特別注意:
Vue.set()
和vm.$set()
不能給vm 或 vm的根數(shù)據(jù)對象 添加屬性?。。?/li>
-
所以上述更新問題的修改方法為:
// this.persons[0] = {id:'001',name:'馬老師',age:50,sex:'男'} //不奏效,因?yàn)閂ue沒檢測到 this.persons.splice(0,1,{id:'001',name:'馬老師',age:50,sex:'男'})
-
this.splice()
是JavaScript數(shù)組對象的一個(gè)方法,用于修改數(shù)組,可以刪除、添加和替換數(shù)組中的元素。 - 語法:
this.splice(start, deleteCount, item1, item2, ...)
- start:要修改的起始位置,如果為負(fù)數(shù),表示倒數(shù)的位置(-1表示最后一個(gè)元素)。
- deleteCount:要?jiǎng)h除的元素個(gè)數(shù)。
- tem1, item2, …:要添加到數(shù)組中的元素。
- 返回值: 返回被刪除元素的數(shù)組。
-
- ??綜合案例
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>總結(jié)數(shù)據(jù)監(jiān)視</title> <style> button{ margin-top: 10px; } </style> <!-- 引入Vue --> <script type="text/javascript" src="../js/vue.js"></script> </head> <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.once="addFriend">在列表首位添加一個(gè)朋友</button> <br/> <button @click="updateFirstFriendName">修改第一個(gè)朋友的名字為:張三</button> <br/> <button @click.once="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 在啟動時(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(){ 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.$set(this.student.hobby,0,'畫畫') }, removeSmoke(){ this.student.hobby = this.student.hobby.filter((h)=>{ return h !== '喝酒' }) } } }) </script> </html>
??收集表單數(shù)據(jù)
- 若:
<input type="text"/>
,則v-model
收集的是value值,用戶輸入的就是value值。 - 若:
<input type="radio"/>
,則v-model
收集的是value值,且要給標(biāo)簽配置value值。 - 若:
<input type="checkbox"/>
- 沒有配置input的value屬性,那么收集的就是checked(勾選 or 未勾選,是布爾值)
- 配置input的value屬性:
- (1)v-model的初始值是非數(shù)組,那么收集的就是checked(勾選 or 未勾選,是布爾值)
- (2)v-model的初始值是數(shù)組,那么收集的的就是value組成的數(shù)組
- 備注:v-model的三個(gè)修飾符:
-
lazy
:失去焦點(diǎn)再收集數(shù)據(jù) -
number
:輸入字符串轉(zhuǎn)為有效的數(shù)字 -
trim
:輸入首尾空格過濾
-
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>收集表單數(shù)據(jù)</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<!-- 準(zhǔn)備好一個(gè)容器-->
<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/>
愛好:
學(xué)習(xí)<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/>
所屬校區(qū)
<select v-model="userInfo.city">
<option value="">請選擇校區(qū)</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">《用戶協(xié)議》</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>
</html>
補(bǔ)充:關(guān)于console.log(JSON.stringify(this.userInfo))
-
JSON.stringify()
:將 JavaScript 對象轉(zhuǎn)換為 JSON 字符串的方法。它接受一個(gè)對象作為參數(shù),并返回其對應(yīng)的 JSON 字符串表示。 - 意思是將當(dāng)前對象的userInfo屬性轉(zhuǎn)換為 JSON 字符串,并使用console.log()函數(shù)將其輸出到控制臺。
??過濾器
-
BootCDN,分享第三庫分享庫的網(wǎng)站,Day.js 是一個(gè)輕量的處理時(shí)間和日期的 JavaScript 庫,和 Moment.js 的 API 設(shè)計(jì)保持完全一樣(更輕量級)。
-
時(shí)間戳獲取
-
定義:對要顯示的數(shù)據(jù)進(jìn)行特定格式化后再顯示(適用于一些簡單邏輯的處理)。
-
語法:
-
- 注冊過濾器:
Vue.filter(name,callback)
或new Vue{filters:{}}
- 注冊過濾器:
-
- 使用過濾器:
{{ xxx | 過濾器名}}
或v-bind:屬性 = "xxx | 過濾器名"
- 使用過濾器:
-
-
備注:
-
- 過濾器也可以接收額外參數(shù)、多個(gè)過濾器也可以串聯(lián)。
-
- 并沒有改變原本的數(shù)據(jù), 是產(chǎn)生新的對應(yīng)的數(shù)據(jù)。
-
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>過濾器</title>
<script type="text/javascript" src="../js/vue.js"></script>
<script type="text/javascript" src="../js/dayjs.min.js"></script>
</head>
<body>
<!-- 準(zhǔn)備好一個(gè)容器-->
<div id="root">
<h2>顯示格式化后的時(shí)間</h2>
<!-- 計(jì)算屬性實(shí)現(xiàn) -->
<h3>現(xiàn)在是:{{fmtTime}}</h3>
<!-- methods實(shí)現(xiàn) -->
<h3>現(xiàn)在是:{{getFmtTime()}}</h3>
<!-- 過濾器實(shí)現(xiàn) -->
<h3>現(xiàn)在是:{{time | timeFormater}}</h3>
<!-- 過濾器實(shí)現(xiàn)(傳參) -->
<h3>現(xiàn)在是:{{time | timeFormater('YYYY_MM_DD') | mySlice}}</h3>
<!-- 罕見 -->
<h3 v-bind:x="msg | mySlice">lalayouyi</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,7)
})
new Vue({
el:'#root',
data:{
time:1708265557066, //時(shí)間戳
msg:'你好,lalayouyi'
},
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'){
return dayjs(value).format(str)
}
}
})
new Vue({
el:'#root2',
data:{
msg:'hello,lalayouyi!'
}
})
</script>
</html>
??內(nèi)置指令與自定義指令
??回顧
-
v-bind
:單向綁定解析表達(dá)式,可簡寫為:xxx
-
v-model
:雙向數(shù)據(jù)綁定 -
v-for
:遍歷數(shù)組/對象/字符串 -
v-on
:綁定事件監(jiān)聽, 可簡寫為@
-
v-if
:條件渲染(動態(tài)控制節(jié)點(diǎn)是否存存在) -
v-else
:條件渲染(動態(tài)控制節(jié)點(diǎn)是否存存在) -
v-show
:條件渲染(動態(tài)控制節(jié)點(diǎn)是否展示)
??v-text指令
- 作用:向其所在的節(jié)點(diǎn)中渲染文本內(nèi)容,但不會解析標(biāo)簽。
-
與插值語法的區(qū)別:
v-text
會替換掉節(jié)點(diǎn)中的內(nèi)容,{{xx}}
則不會。<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>v-text指令</title> <!-- 引入Vue --> <script type="text/javascript" src="../js/vue.js"></script> </head> <body> <!-- 準(zhǔn)備好一個(gè)容器--> <div id="root"> <div>你好,{{name}}</div> <div v-text="name">我會被換掉嗚嗚</div> <div v-text="str"></div> </div> </body> <script type="text/javascript"> Vue.config.productionTip = false new Vue({ el:'#root', data:{ name:'啦啦右一', // 標(biāo)簽解析不了———— str:'<h3>你好??!</h3>' } }) </script> </html>
??v-html指令
-
作用:向指定節(jié)點(diǎn)中渲染包含html結(jié)構(gòu)的內(nèi)容。
-
與插值語法的區(qū)別:
- (1).v-html會替換掉節(jié)點(diǎn)中所有的內(nèi)容,{{xx}}則不會。
- (2).v-html可以識別html結(jié)構(gòu)。
-
嚴(yán)重注意:v-html有安全性問題!?。?!
- (1).在網(wǎng)站上動態(tài)渲染任意HTML是非常危險(xiǎn)的,容易導(dǎo)致XSS攻擊。
- (2).一定要在可信的內(nèi)容上使用v-html,永不要用在用戶提交的內(nèi)容上!
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>v-html指令</title> <!-- 引入Vue --> <script type="text/javascript" src="../js/vue.js"></script> </head> <body> <div id="root"> <div>你好,{{name}}</div> <div v-html="str"></div> <div v-html="str2"></div> </div> </body> <script type="text/javascript"> Vue.config.productionTip = false new Vue({ el:'#root', data:{ name:'lalayouyi', str:'<h3>你好?。?lt;/h3>', str2:'<a href=javascript:location., } }) </script> </html>
??v-cloak指令
- v-cloak是Vue.js框架中的一個(gè)指令,用于隱藏在頁面加載之前尚未完成編譯的Vue實(shí)例,從而提供更好的用戶體驗(yàn)。
- 本質(zhì)是一個(gè)特殊屬性,Vue實(shí)例創(chuàng)建完畢并接管容器后,會刪掉v-cloak屬性。
- v-cloak指令的使用方法很簡單,只需將v-cloak添加到包含Vue實(shí)例的元素上即可。例如:
<div v-cloak> {{ message }} </div>
- 需要注意的是,為了讓v-cloak指令生效,必須在CSS中定義一個(gè)v-cloak的樣式,并設(shè)置元素為隱藏狀態(tài):
[v-cloak] { display: none; }
- 在頁面加載之前,v-cloak指令會將元素隱藏起來,直到Vue實(shí)例完成編譯之后才會顯示出來。這樣用戶就不會看到未處理的Mustache標(biāo)簽,而是直接看到渲染完成后的結(jié)果。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>v-cloak指令</title> <style> [v-cloak]{ display:none; } </style> <!-- 引入Vue --> </head> <body> <!-- 準(zhǔn)備好一個(gè)容器--> <div id="root"> <h2 v-cloak>{{name}}</h2> </div> <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> </body> <script type="text/javascript"> console.log(1) Vue.config.productionTip = false new Vue({ el:'#root', data:{ name:'lalayouyi' } }) </script> </html>
??v-once指令
-
v-once
所在節(jié)點(diǎn)在初次動態(tài)渲染后,就視為靜態(tài)內(nèi)容了。 -
以后數(shù)據(jù)的改變不會引起
v-once
所在結(jié)構(gòu)的更新,可以用于優(yōu)化性能。<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>v-once指令</title> <!-- 引入Vue --> <script type="text/javascript" src="../js/vue.js"></script> </head> <body> <!-- 準(zhǔn)備好一個(gè)容器--> <div id="root"> <h2 v-once>初始化的n值是:{{n}}</h2> <h2>當(dāng)前的n值是:{{n}}</h2> <button @click="n++">點(diǎn)我n+1</button> </div> </body> <script type="text/javascript"> Vue.config.productionTip = false new Vue({ el:'#root', data:{ n:1 } }) </script> </html>
??v-pre指令
- 跳過其所在節(jié)點(diǎn)的編譯過程。
- 可利用它跳過:沒有使用指令語法、沒有使用插值語法的節(jié)點(diǎn),會加快編譯。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>v-pre指令</title>
<!-- 引入Vue -->
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<!-- 準(zhǔn)備好一個(gè)容器-->
<div id="root">
<h2 v-pre>Vue其實(shí)很簡單</h2>
<h2 >當(dāng)前的n值是:{{n}}</h2>
<button @click="n++">點(diǎn)我n+1</button>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false
new Vue({
el:'#root',
data:{
n:1
}
})
</script>
</html>
??自定義指令
-
定義語法:
-
(1).局部指令:
new Vue({ directives:{指令名:配置對象} }) //或者 new Vue({ directives:{指令名:回調(diào)函數(shù)} })
-
(2).全局指令:
Vue.directive(指令名,配置對象)
或Vue.directive(指令名,回調(diào)函數(shù))
-
-
配置對象中常用的3個(gè)回調(diào):
- (1).bind:指令與元素成功綁定時(shí)調(diào)用。
- (2).inserted:指令所在元素被插入頁面時(shí)調(diào)用。
- (3).update:指令所在模板結(jié)構(gòu)被重新解析時(shí)調(diào)用。
-
備注:
- 1.指令定義時(shí)不加
v-
,但使用時(shí)要加v-
; - 2.指令名如果是多個(gè)單詞,要使用kebab-case命名方式,不要用camelCase命名。
- 1.指令定義時(shí)不加
需求1:定義一個(gè)v-big指令,和v-text功能類似,但會把綁定的數(shù)值放大10倍。
需求2:定義一個(gè)v-fbind指令,和v-bind功能類似,但可以讓其所綁定的input元素默認(rèn)獲取焦點(diǎn)。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>自定義指令</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<!-- 準(zhǔn)備好一個(gè)容器-->
<div id="root">
<h2>{{name}}</h2>
<h2>當(dāng)前的n值是:<span v-text="n"></span> </h2>
<!-- <h2>放大10倍后的n值是:<span v-big-number="n"></span> </h2> -->
<h2>放大10倍后的n值是:<span v-big="n"></span> </h2>
<button @click="n++">點(diǎn)我n+1</button>
<hr/>
<input type="text" v-fbind:value="n">
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false
//定義全局指令
/* Vue.directive('fbind',{
//指令與元素成功綁定時(shí)(一上來)
bind(element,binding){
element.value = binding.value
},
//指令所在元素被插入頁面時(shí)
inserted(element,binding){
element.focus()
},
//指令所在的模板被重新解析時(shí)
update(element,binding){
element.value = binding.value
}
}) */
new Vue({
el:'#root',
data:{
name:'尚硅谷',
n:1
},
directives:{
big(element,binding){
console.log('big',this) //注意此處的this是window
element.innerText = binding.value * 10
},
fbind:{
//指令與元素成功綁定時(shí)(一上來)
bind(element,binding){
element.value = binding.value
},
//指令所在元素被插入頁面時(shí)
inserted(element,binding){
element.focus()
},
//指令所在的模板被重新解析時(shí)
update(element,binding){
element.value = binding.value
}
}
}
})
</script>
</html>
??Vue實(shí)例生命周期
- 又名:生命周期回調(diào)函數(shù)、生命周期函數(shù)、生命周期鉤子。
- 是什么:Vue在關(guān)鍵時(shí)刻幫我們調(diào)用的一些特殊名稱的函數(shù)。
- 生命周期函數(shù)的名字不可更改,但函數(shù)的具體內(nèi)容是程序員根據(jù)需求編寫的。
- 生命周期函數(shù)中的this指向是vm 或 組件實(shí)例對象。
-
常用的生命周期鉤子:
-
mounted
: 發(fā)送ajax請求、啟動定時(shí)器、綁定自定義事件、訂閱消息等【初始化操作】。<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>引出生命周期</title> <!-- 引入Vue --> <script type="text/javascript" src="../js/vue.js"></script> </head> <body> <!-- 準(zhǔn)備好一個(gè)容器--> <div id="root"> <h2 v-if="a">你好啊</h2> <h2 :style="{opacity}">歡迎學(xué)習(xí)Vue</h2> </div> </body> <script type="text/javascript"> Vue.config.productionTip = false new Vue({ el:'#root', data:{ a:false, opacity:1 }, //Vue完成模板的解析并把初始的真實(shí)DOM元素放入頁面后(掛載完畢)調(diào)用mounted mounted(){ setInterval(() => { this.opacity -= 0.01 if(this.opacity <= 0) this.opacity = 1 },16) }, }) </script> </html>
-
beforeDestroy
: 清除定時(shí)器、解綁自定義事件、取消訂閱消息等【收尾工作】。
-
-
關(guān)于銷毀Vue實(shí)例:
- 1.銷毀后借助Vue開發(fā)者工具看不到任何信息。
- 2.銷毀后自定義事件會失效,但原生DOM事件依然有效。
- 3.一般不會在beforeDestroy操作數(shù)據(jù),因?yàn)榧幢悴僮鲾?shù)據(jù),也不會再觸發(fā)更新流程了。
??分析生命周期文章來源:http://www.zghlxwxcb.cn/news/detail-827167.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>分析生命周期</title>
<!-- 引入Vue -->
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<!-- 準(zhǔn)備好一個(gè)容器-->
<div id="root" :x="n">
<h2 v-text="n"></h2>
<h2>當(dāng)前的n值是:{{n}}</h2>
<button @click="add">點(diǎn)我n+1</button>
<button @click="bye">點(diǎn)我銷毀vm</button>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false
new Vue({
el:'#root',
data:{
n:1
},
methods: {
add(){
console.log('add')
this.n++
},
bye(){
console.log('bye')
this.$destroy()
}
},
watch:{
n(){
console.log('n變了')
}
},
beforeCreate() {
console.log('beforeCreate')
},
created() {
console.log('created')
},
beforeMount() {
console.log('beforeMount')
},
mounted() {
console.log('mounted')
},
beforeUpdate() {
console.log('beforeUpdate')
},
updated() {
console.log('updated')
},
beforeDestroy() {
console.log('beforeDestroy')
},
destroyed() {
console.log('destroyed')
},
})
</script>
</html>
文章來源地址http://www.zghlxwxcb.cn/news/detail-827167.html
到了這里,關(guān)于Vue | (一)Vue核心(下) | 尚硅谷Vue2.0+Vue3.0全套教程的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!