0、關(guān)于vue的一些總結(jié):
1、只要data里面的數(shù)據(jù)發(fā)生變化,vue模板就重新執(zhí)行。
<div id="root">
<h1 :style="opacity1">學(xué)習(xí)vue</h1>
<h1 :style="{opacity:opacity}">學(xué)習(xí)vue</h1>
<h1 :style="{opacity}">學(xué)習(xí)vue</h1>
<button @click="change">點擊我可以漸變</button>
{{change()}}
</div>
<script>
const vm = new Vue({
el: '#root',
data: {
opacity1: 'opacity: .1',
opacity: .6,
},
methods: {
change() {
setInterval(() => {
this.opacity = this.opacity - 0.01
if (this.opacity <= 0) {
this.opacity = 1
}
}, 16)
}
},
});
</script>
在這個例子中,vue模板中的change()
會首先得到執(zhí)行,然后調(diào)用methods中的定時器
,定時器發(fā)生變化,修改了opacity
,data里面的數(shù)據(jù)發(fā)生了變化,然后就重新解析vue模板,就又重新生成了一個定時器,導(dǎo)致一個循環(huán),會不停生成定時器。
1、特點
1.采用組件化模式,提高代碼復(fù)用率、且讓代碼更好維護。
2.聲明式編碼,讓編碼人員無需直接操作DOM,提高開發(fā)效率
命令式編碼
3.使用虛擬DOM+優(yōu)秀的Diff 算法,盡量復(fù)用DOM節(jié)點。
2、hello vue
vue的引入
就是寫在引入css的地方就行了
例如:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
在這里引入
<script src="../vue.js"></script>
</head>
<body>
</body>
</html>
在線地址引入:
vue2
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.10/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.10"></script>
vue3
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
注意:
1.想讓Vue工作,就必須創(chuàng)建一個Vue實例,且要傳入一個配置對象new Vue;
2.root容器里的代碼依然符合html規(guī)范,只不過混入了一些特殊的Vue語法;
3.root容器里的代碼被稱為[Vue模板];
4.Vue實例和容器是一一對應(yīng)的
;
5.真實開發(fā)中只有一個vue實例,并且會配合著組件一起使用;
6.{{xxx}中的xxx要寫js表達式,且xxx可以自動讀取到data中的所有屬性
7.一旦data中的數(shù)據(jù)發(fā)生改變,那么頁面中用到該數(shù)據(jù)的地方也會自動更新;
注意區(qū)分: js表達式 和 s代碼(語句)
表達式:一個表達式會產(chǎn)生一個值,可以放在任何一個需要值的地方:
(1). a
(2). a+b
(3). demo(1)
(4). x === y ?a’: b’
js代碼(語句)
(1). if( ){ }
(2). for( ){ }
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="../vue.js"></script>
</head>
<body>
<!-- 準(zhǔn)備一個容器 -->
//-------------------------------------------------------
<div id="root">
<h1>hello,{{name}}</h1>
<h1>今年{{age}}歲了!</h1>
</div>
<!-- 這個就沒有效果,以為沒有選擇器選中他 -->
<h1>{{name}}</h1>
//-----------------------------------------------------------
<script type="text/javascript">
// Vue.config.productionTip = false;//設(shè)置為 false 以阻止 vue 在啟動時生成生產(chǎn)提示。
// 創(chuàng)建vue實例--------------------------------------------------
const x = new Vue({
// el:document.querySelector("#root"), //這樣也是可以的
el: '#root', //el用于指定當(dāng)前Vue實例為那個容器服務(wù),值通常是css選擇器字符串
data: {
name: 'world',
age: 23,
}
});
//--------------------------------------------------------
</script>
</body>
</html>
3、模板語法
注意:
Vue模板語法有2大類:
1.插值語法:
功能:用于解析標(biāo)簽體內(nèi)容。
寫法: {{xxx}},xxx是js表達式,且可以直接讀取到data中的所有屬性。
2.指令語法:
功能:用于解析標(biāo)簽(包括: 標(biāo)簽屬性、標(biāo)簽體內(nèi)容、綁定事件…)
舉例: v-bind:href="xxx”或 簡寫為 :href=“xxx”,
xxx同樣要寫is表達式,且可以直接讀取到data中的所有屬性。
備注: Vue中有很多的指令,且形式都是: v-???,此處我們只是拿v-bind舉個例子。
v-bind:xxx=?。?可以直接寫變量,而不用寫{{ }}
<!-- 準(zhǔn)備一個容器 -->
<div id="root">
<h1>插值語法</h1>
<h1>hello,{{name}}</h1>
<h1>今年{{age}}歲了!</h1>
<h1>指令語法</h1>
<a v-bind:href="url" target="_blank">點我去百度學(xué)習(xí)</a>
<a :href="url">v-bind:可以簡寫成:</a>
<h2>我的學(xué)校是{{school.name}}</h2>
</div>
<script type="text/javascript">
// 創(chuàng)建vue實例
const x = new Vue({
// el:document.querySelector("#root"), //這樣也是可以的
el: '#root', //el用于指定當(dāng)前Vue實例為那個容器服務(wù),值通常是css選擇器字符串
data: {
name: 'world',
age: 23,
url: 'https://www.baidu.com',
// 如果有多個name,不想換名字的情況下,可以用一個對象包括
school:{
name:'家里蹲',
}
}
});
</script>
3、數(shù)據(jù)綁定
1、單向綁定
<div id="root">
<!-- v-bind: 是單向綁定 -->
單向數(shù)據(jù)綁定:<input type="text" :value="name">
</div>
<script>
new Vue({
el:'#root',
data:{
name:'李旭亮',
}
})
</script>
data中的name屬性,通過v-bind:屬性綁定到value身上,如何input輸入框里面的值就發(fā)生了變化。
通過修改vue工具中的name屬性,可以改變input輸入框里面的值。但是直接修改input輸入框里面的值,卻不能修改data里面的值。
v-bind:value=
name
類似于一個賦值
操作。
等號后面的值可以賦值給前面,而前面的值,不能給后面。
2、雙向綁定
<div id="root">
<!-- v:bind 是單向綁定 -->
單向數(shù)據(jù)綁定:<input type="text" v-bind:value="name"><br>
雙向數(shù)據(jù)綁定:<input type="text" v-model:value="name">
</div>
<!-- 這是錯誤的。因為v-model只能用在表單類元素(輸出類元素)上 -->
<h2 v-model="name"></h2>
<!-- 簡寫形式 -->
單向數(shù)據(jù)綁定:<input type="text" :value="name"><br>
雙向數(shù)據(jù)綁定:<input type="text" v-model="name">
Vue中有2種數(shù)據(jù)綁定的方式:
- 單向綁定(v-bind): 數(shù)據(jù)只能從data流向頁面。
- 雙向綁定(v-model): 數(shù)據(jù)不僅能從data流向頁面,還可以從頁面流向data。
備注:
- 雙向綁定一般都應(yīng)用在表單類元素上 (如: input、select等)
-
v-model:value 可以簡寫為 v-model
,因為v-model默認(rèn)收集的就是value值。
4、el和data的二種寫法
1、el
<div id="root">
<h1>hello,{{new Date()}}</h1>
<h1>hello,{{name}}</h1>
</div>
<script>
const v1 = new Vue({
// el: '#root',
data: {
name: '2023-4-6',
}
});
v1.$mount('#root');//和el:'#root'的效果一樣
console.log(v1);
// 這樣可以實現(xiàn)時鐘效果
// setInterval(function () {
// v1.$mount('#root');//和el:'#root'的效果一樣
// }, 1000)
</script>
2、data
<div id="root">
<h1>hello,{{new Date()}}</h1>
<h1>hello,{{name}}</h1>
</div>
<script>
// data的二種寫法
new Vue({
el: '#root',
// 1、對象式-----------
// data:{
// name:'對象式'
// }
// 2、函數(shù)式-----------
data: function () {
console.log(this);//指的是實例對象,例如v1
return {
name: '函數(shù)式'
}
}
});
</script>
data與el的2種寫法
e1有2種寫法
- new Vue時候配置el屬性。
- 先創(chuàng)建Vue實例,隨后再通過vm.$mount('#root )指定el的值
data有2種寫法
- 對象式
- 函數(shù)式
如何選擇:目前哪種寫法都可以,以后學(xué)習(xí)到組件時,data必須使用函數(shù)式,
否則會報錯。
一個重要的原則:
由Vue管理的函數(shù)
一定不要寫箭頭函數(shù),一但寫了箭頭函數(shù),this就不再是Vue實例了。而是指向window
5、mvvm模型
<div id="root">
<input type="text" v-model="name">
<h3>{{$options}}</h3>
</div>
<script>
const vm = new Vue({
el: '#root',
data: {
name: "河南牧業(yè)經(jīng)濟學(xué)院"
}
});
console.log(vm);
console.log(vm.name);//河南牧業(yè)經(jīng)濟學(xué)院
</script>
這個實例對象里面的所有東西,都可以直接用{ { } }
輸出。
MVVM模型
- M:模型(Model) : data中的數(shù)據(jù)
- V:視圖(view) : 模板代碼
- VM: 視圖模型(ViewModel): Vue實例
觀察發(fā)現(xiàn):
1.data中所有的屬性,最后都出現(xiàn)在了vm身上。
2.vm身上所有的屬性 及 Vue原型上所有屬性,在Vue模板中都可以直接使用。
6、defineProperty
let person = {
name: 'lxl',
sex: '男'
}
Object.defineProperty(person, 'age', {
//這個值不可以被枚舉、不可以被修改、不可以被刪除
value: 54,
enumerable: true,//控制屬性是否可以被枚舉,默認(rèn)值是false
writable: true,//控制屬性是否可以被修改,默認(rèn)值是false
configurable: true,//控制屬性是否可以被刪除,默認(rèn)值是false
})
console.log(person);
// Object.keys(person) 可以輸出對象的屬性名
console.log(Object.keys(person));
set和get
- 注意:當(dāng)使用了getter或setter方法,不允許使用writable和value這兩個屬性
- getter: 當(dāng)訪問該屬性時,該方法會被執(zhí)行。函數(shù)的返回值 會作為 該屬性的值返回.
- setter: 當(dāng)屬性值修改時,該方法會被執(zhí)行。該方法將接受唯一參數(shù),即該屬性新的參數(shù)值。
- 不要在getter中再次獲取該屬性值,也不要在setter中再次設(shè)置改屬性,否則會棧溢出!
let num=19;
let person = {
name: 'lxl',
sex: '男'
}
Object.defineProperty(person, 'age', {
// 當(dāng)有人讀取person的age屬性時,get函數(shù)就會被調(diào)用,且返回值就是age的值
get:function(){
console.log('有人讀取age屬性了');
// return 'age的值';
return num;
},
// 當(dāng)有人修改person的age屬性值時,set函數(shù)的(setter)就會被調(diào)用,且會收到修改的具體值
set(value){
console.log('有人修改了age屬性值,其值是',value);
num=value;
// age=num=value;
}
})
console.log(person);
// Object.keys(person) 可以輸出對象的屬性名
console.log(Object.keys(person));
7、數(shù)據(jù)代理
// 數(shù)據(jù)代理:通過一個對象代理 對另一個對象屬性的操作(讀、寫)
let obj = { x: 100 };
let obj2 = { y: 200 };
// 感覺就是
// 把對象obj的屬性x追加給obj2,修改obj2的這個x還會影響obj的x屬性
Object.defineProperty(obj2, "x", {
get() {
return obj.x;
},
set(value) {
obj.x = value;
}
});
1.Vue中的數(shù)據(jù)代理:
通過vm對象來代理data對象中屬性的操作 (讀/寫)
2.Vue中數(shù)據(jù)代理的好處:
更加方便的操作data中的數(shù)據(jù)
3.基本原理:
- 通過object.defineProperty()把data對象中所有屬性添加到vm上。
- 為每一個添加到vm上的屬性,都指定一個getter/setter。
- 在getter/setter內(nèi)部去操作 (讀/寫) data中對應(yīng)的屬性。
8、事件處理
事件的基本使用:
1、使用v-on:xxx 或 @xxx 綁定事件,其中xxx是事件名。
1、v-on:click='abc’可以簡寫成@click=‘a(chǎn)bc’
2、事件的回調(diào)需要配置在methods對象中,最終會在vm上;
3、methods中配置的函數(shù),不要用箭頭函數(shù)! 否則this就不是vm了;
4、methods中配置的函數(shù),都是被Vue所管理的函數(shù),this的指向是vm 或 組件實例對象;
5、@click="demo"和 @click="demo($event)"效果一致,但后者可以傳參;
<div id="root">
<h2>在{{address}}學(xué)習(xí)</h2>
<button v-on:click="showInfo1">點擊提示信息1</button>
<button @click="showInfo2(985,$event)">點擊提示信息2</button>
</div>
<script>
new Vue({
el: '#root',
data: {
address: '宿舍',
},
methods: {
// 在對象里面可以省略function
showInfo1(e) {
console.log(e.target);
alert('好好學(xué)習(xí)!');
},
showInfo2(num, e) {
console.log('showInfo2=' + num);
console.log(e);
},
},
});
</script>
1、事件修飾符
vue中的事件修飾符:
1、prevent: 阻止默認(rèn)事件(常用) ;
2、stop: 阻止事件冒泡(常用) ;
3、once:事件只觸發(fā)一次(常用) :
4、capture:使用事件的捕獲模式:
5、self: 只有event.target是當(dāng)前操作的元素是才觸發(fā)事件:
6、passive:事件的默認(rèn)行為立即執(zhí)行,無需等待事件回調(diào)執(zhí)行完畢:
<div id="root">
<a href="https://www.baidu.com/" @click.prevent="show">點擊</a>
<!-- 如果是二層結(jié)構(gòu),只給孩子加stop就行了
如果有三層結(jié)構(gòu),那么就需要再加一個stop
-->
<div class="father" @click="show">
<button class="son" @click.stop="show">ok</button>
</div>
<!-- 無論點擊多少次,只會觸發(fā)一次事件 -->
<button @click.once="show">點擊只觸發(fā)一次</button>
<!-- 把默認(rèn)的事件冒泡,改成捕獲:捕獲在父盒子身上加就可以了 -->
<div class="d1" @click.capture="showmsg(1)">
div1
<div class="d2" @click="showmsg(2)">
div2
</div >
</div>
<!-- <div class="father" @click.self="show"> -->
<div class="father" @click="show">
<button class="son" @click="show">ok</button>
</div>
</div>
<script>
new Vue({
el: '#root',
data:{
},
methods: {
show(e){
// e.preventDefault();//阻止默認(rèn)事件
// e.stopPropagation();//阻止冒泡
// console.log('加油!');
console.log(e.target);
},
showmsg(msg){
console.log(msg);
}
},
});
</script>
事件冒泡
<!-- 如果是二層結(jié)構(gòu),只給孩子加stop就行了
如果有三層結(jié)構(gòu),那么就需要再加一個stop
因為冒泡是從內(nèi)到外的,在vue中的.stop必須加在子盒子上
-->
<div class="father" @click="show">
<button class="son" @click.stop="show">ok</button>
</div>
點擊ok,不會彈出父盒子的信息。
事件捕獲
<!-- 把默認(rèn)的事件冒泡,改成捕獲:捕獲在父盒子身上加就可以了 -->
<div class="d1" @click.capture="showmsg(1)">
div1
<div class="d2" @click="showmsg(2)">
div2
</div >
</div>
點擊div2,先打印1,再打印2,符合捕獲規(guī)則。
2、鍵盤事件
1.Vue中常用的按鍵別名:
回車 => enter
刪除 => delete (捕獲“刪除”和“退格”鍵)
退出 => esc
空格 => space
換行 => tab
上 => up
下=> down
左=> left
右=> right
2.Vue未提供別名的按鍵,可以使用按鍵原始的key值去綁定,但注意要轉(zhuǎn)為kebab-case (短橫線命名)
3.系統(tǒng)修飾鍵(用法特殊) : ctr1、alt、shift、meta
(1).配合keyup使用: 按下修飾鍵的同時,再按下其他鍵,隨后釋放其他鍵,事件才被觸發(fā)。
(2).配合keydown使用: 正常觸發(fā)事件。
4.也可以使用keyCode去指定具體的按鍵(不推薦)
5.Vue.config.keyCodes.自定義鍵名 = 鍵碼,可以去定制按鍵別名
<div id="root"> <!--按下回車鍵會輸出-->
<input type="text" placeholder="按下回車鍵會輸出!" @keyup.enter="show">
<!-- 按下切換大小寫鍵輸出! 大寫變小寫,且變成小寫的按鈕前,需要加- -->
<input type="text" placeholder="按下切換大小寫鍵輸出" @keyup.caps-lock="show">
<!-- 按下ctrl寫鍵輸出! -->
<input type="text" placeholder="按下ctrl寫鍵輸出!" @keyup.ctrl="show">
</div>
<script>
new Vue({
el: '#root',
data: {
},
methods: {
show(e) {
// 當(dāng)回車的時候輸出------------------------
// console.log(e.keyCode);//回車鍵是13
// if (e.keyCode === 13) {
// console.log(e.target.value);
// } else {
// return console.log('請繼續(xù)輸入!');
// }
// if (e.keyCode !== 13) return
// console.log(e.target.value);
console.log(e.target.value);
}
},
});
</script>
<!-- 按下ctrl+y鍵輸出! -->
<input type="text" placeholder="按下ctrl寫鍵輸出!" @keyup.ctrl.y="show">
3、計算屬性
計算屬性:
1.定義:要用的屬性不存在,要通過已有屬性計算得來。
2.原理: 底層借助了objcet.defineproperty方法提供的getter和setter。
3.get函數(shù)什么時候執(zhí)行?(1).初次讀取時會執(zhí)行一次。(2).當(dāng)依賴的數(shù)據(jù)發(fā)生改變時會被再次調(diào)用。4.優(yōu)勢:與methods實現(xiàn)相比,內(nèi)部有緩存機制(復(fù)用),效率更高,調(diào)試方便。5.備注:
1.計算屬性最終會出現(xiàn)在vm上,直接讀取使用即可。
2.如果計算屈性要被修改,那必須寫set函數(shù)去響應(yīng)修改,且set中要引起計算時依賴的數(shù)據(jù)發(fā)生改變。
<div id="root">
姓:<input type="text" v-model="firstName"><br>
名:<input type="text" v-model="secondName"><br>
全名:<span>{{fullName}}</span> <br>
全名:<span>{{fullName}}</span> <br>
全名:<span>{{fullName}}</span> <br>
全名:<span>{{fullName}}</span> <br>
全名:<span>{{fullName}}</span> <br>
全名:<span>{{fullName}}</span> <br>
</div>
<script>
// vm中的數(shù)據(jù)只要發(fā)生變化,模版中的數(shù)據(jù)就會重新刷新
const vm= new Vue({
el: '#root',
data: {
firstName: "張",
secondName: '三',
},
computed: {
fullName: {
// get有啥作用:當(dāng)有人讀取fullName時,get就會被調(diào)用,且返回值就作為fullName的值
// get什么時候被調(diào)用:1、初次讀取fullName時。2、所依賴的數(shù)據(jù)發(fā)生變化時。
get() {
console.log('有人讀取fullName時,get就會被調(diào)用,');
// console.log(this);//此處的this是vm
return this.firstName + '-' + this.secondName;
},
// set什么時候被調(diào)用,當(dāng)fullName修改的時候
set(value) {
console.log('有人修改fullName時,set就會被調(diào)用,');
console.log('set', value);
const arr = value.split('-');
this.firstName = arr[0];
this.secondName = arr[1];
}
}
},
});
</script>
9、監(jiān)視屬性
1、天氣案例
<div id="root">
在Vue中,當(dāng)一個函數(shù)被定義為computed屬性時,它會被自動緩存,
這意味著只有當(dāng)其依賴的響應(yīng)式數(shù)據(jù)發(fā)生變化時才會重新計算。
因此,在視圖中使用computed屬性時不需要加括號,
因為Vue會自動調(diào)用并返回計算結(jié)果。
<h2>今天天氣很{{info}}!</h2>
<button @click="qieHuan">點擊切換天氣</button>
<!-- @xxx="yyy" yyy指可以寫一些簡單的語句 -->
<button @click="isHot = !isHot">點擊切換天氣2</button>
</div>
<script>
let flag = true;
const vm = new Vue({
el: '#root',
data: {
isHot: true,
},
computed: {
info: {
// get有啥作用:當(dāng)有人讀取info時,get就會被調(diào)用,且返回值就作為info的值
get() {
console.log('有人讀取info時,get就會被調(diào)用,');
return this.isHot ? '炎熱' : '涼爽';//返回值給了info
}
}
},
methods: {
// 這是一個函數(shù)
qieHuan() {
return this.isHot = !this.isHot;
}
// 點擊切換按鈕,假如返回一個false,然后data里面的屬性發(fā)生了變化,
// 然后使computed里面發(fā)生改變
},
});
console.log(vm);
</script>
1.2、computed和methods有什么區(qū)別
Vue中的computed和methods都是用來處理數(shù)據(jù)邏輯的選項,但它們有一些區(qū)別:
computed屬性是基于它的依賴緩存,只有在相關(guān)依賴發(fā)生改變時才會重新計算;而methods方法則是在每次調(diào)用時都執(zhí)行一遍。
computed屬性主要用于對多個數(shù)據(jù)進行計算得出結(jié)果,常用于模板中的表達式計算結(jié)果;而methods方法主要用于觸發(fā)某個事件或操作,例如點擊事件等。
在使用時,computed屬性更像是一個響應(yīng)式的變量,而methods方法更像是普通的函數(shù)。因此,當(dāng)我們需要對數(shù)據(jù)進行計算并獲得一個結(jié)果時,優(yōu)先考慮computed屬性;當(dāng)我們需要觸發(fā)一些事件或操作時,則選擇methods方法。
2、監(jiān)視屬性
監(jiān)視屬性watch:
1.當(dāng)被監(jiān)視的屬性變化時,回調(diào)函數(shù)自動調(diào)用,進行相關(guān)操作
2.監(jiān)視的屬性必須存在,才能進行監(jiān)視!!
3.監(jiān)視的兩種寫法:
(1).new Vue時傳入watch配置
(2).通過vm.$watch監(jiān)視
<div id="root">
<h2>今天天氣很{{info}}!</h2>
<button @click="qieHuan">點擊切換天氣</button>
<!-- @xxx="yyy" yyy指可以寫一些簡單的語句 -->
<button @click="isHot = !isHot">點擊切換天氣2</button>
</div>
<script>
let flag = true;
const vm = new Vue({
el: '#root',
data: {
isHot: true,
},
computed: {
info: {
// get有啥作用:當(dāng)有人讀取info時,get就會被調(diào)用,且返回值就作為info的值
get() {
console.log('有人讀取info時,get就會被調(diào)用,');
return this.isHot ? '炎熱' : '涼爽';//返回值給了info
}
}
},
methods: {
// 這是一個函數(shù)
qieHuan() {
return this.isHot = !this.isHot;
}
// 點擊切換按鈕,假如返回一個false,然后data里面的屬性發(fā)生了變化,
// 然后使computed里面發(fā)生改變
},
// 監(jiān)視屬性
// watch: {
// isHot: {
// immediate: true,//初始化時,讓handler調(diào)用一下
// // handler什么時候調(diào)用?當(dāng)isHot發(fā)生改變時
// handler(newValue, oldValue) {
// console.log('isHot發(fā)生改變了', newValue, oldValue);
// }
// }
// }
});
console.log(vm);
vm.$watch('isHot', {
immediate: true,//初始化時,讓handler調(diào)用一下
// handler什么時候調(diào)用?當(dāng)isHot發(fā)生改變時
handler(newValue, oldValue) {
console.log('isHot發(fā)生改變了', newValue, oldValue);
}
})
</script>
3、深度監(jiān)視
深度監(jiān)視:
(1).Vue中的watch默認(rèn)不監(jiān)測對象內(nèi)部值的改變 (一層)
(2).配置deep:true可以監(jiān)測對象內(nèi)部值改變 (多層)。
備注:
(1).Vue自身可以監(jiān)測對象內(nèi)部值的改變,但Vue提供的watch默認(rèn)不可以!
(2).使用watch時根據(jù)數(shù)據(jù)的具體結(jié)構(gòu),決定是否采用深度監(jiān)視。
<div id="root">
<h2>今天天氣很{{info}}!</h2>
<button @click="qieHuan">點擊切換天氣</button>
<!-- @xxx="yyy" yyy指可以寫一些簡單的語句 -->
<button @click="isHot = !isHot">點擊切換天氣2</button>
<hr>
<h3>a的值是{{num.a}}</h3>
<button @click="add">點擊讓a的值++</button>
<button @click="num.a++">點擊讓a的值++</button>
<button @click="num={a:675,b:5643}">徹底改變num</button>
</div>
<script>
let flag = true;
const vm = new Vue({
el: '#root',
data: {
isHot: true,
num: {
a: 1,
b: 1,
}
},
computed: {
// info: {
// // get有啥作用:當(dāng)有人讀取info時,get就會被調(diào)用,且返回值就作為info的值
// get() {
// console.log('有人讀取info時,get就會被調(diào)用,');
// return this.isHot ? '炎熱' : '涼爽';//返回值給了info
// }
// }
// 省略get的寫法
info() {
return this.isHot ? '炎熱' : '涼爽';//返回值給了info
},
},
methods: {
// 這是一個函數(shù)
qieHuan() {
return this.isHot = !this.isHot;
},
// 點擊切換按鈕,假如返回一個false,然后data里面的屬性發(fā)生了變化,
// 然后使computed里面發(fā)生改變
add() {
return this.num.a++;
}
},
// 監(jiān)視屬性
watch: {
isHot: {
// immediate: true,//初始化時,讓handler調(diào)用一下
// handler什么時候調(diào)用?當(dāng)isHot發(fā)生改變時
handler(newValue, oldValue) {
console.log('isHot發(fā)生改變了', newValue, oldValue);
}
},
// 'num.a': {
// handler() {
// console.log('a發(fā)生了變化');
// }
// },
num: {
// 監(jiān)視多級結(jié)構(gòu)中所有屬性的變化
// num或者num里面的屬性變了,都是變化
deep: true,
handler() {
console.log('num發(fā)生了變化');
}
}
}
});
console.log(vm);
</script>
4、監(jiān)視屬性的簡寫形式
<div id="root">
<h2>今天天氣很{{info}}!</h2>
<button @click="qieHuan">點擊切換天氣</button>
<!-- @xxx="yyy" yyy指可以寫一些簡單的語句 -->
<button @click="isHot = !isHot">點擊切換天氣2</button>
</div>
<script>
let flag = true;
const vm = new Vue({
el: '#root',
data: {
isHot: true,
},
computed: {
info() {
return this.isHot ? '炎熱' : '涼爽';//返回值給了info
},
},
methods: {
// 這是一個函數(shù)
qieHuan() {
return this.isHot = !this.isHot;
}
},
// 監(jiān)視屬性
watch: {
// 完整寫法---------------------------------
// isHot: {
// immediate: true,//初始化時,讓handler調(diào)用一下
// // handler什么時候調(diào)用?當(dāng)isHot發(fā)生改變時
// handler(newValue, oldValue) {
// console.log('isHot發(fā)生改變了', newValue, oldValue);
// }
// },
// 當(dāng)不需要配置項,例如immediate,deep的時候就可以簡寫
// 簡寫-----------------------------------------
// isHot(newValue, oldValue) {
// console.log('isHot發(fā)生改變了', newValue, oldValue);
// }
}
});
console.log(vm);
// 完整寫法:------------------------------------------------
// vm.$watch('isHot', {
// immediate: true,//初始化時,讓handler調(diào)用一下
// deep: true,
// // handler什么時候調(diào)用?當(dāng)isHot發(fā)生改變時
// handler(newValue, oldValue) {
// console.log('isHot發(fā)生改變了', newValue, oldValue);
// }
// });
// 簡寫:---------------------------------------------------
vm.$watch('isHot', function (newValue, oldValue) {
console.log('isHot發(fā)生改變了', newValue, oldValue);
})
</script>
5、姓名案例-watch實現(xiàn)
computed和watch之間的區(qū)別:
1.computed能完成的功能,watch都可以完成。
2.watch能完成的功能,computed不一定能完成,例如: watch可以進行異步操作。
兩個重要的小原則:
1.所被Vue管理的函數(shù),最好寫成普通函數(shù),這樣this的指向才是vm 或 組件實例對象。
2.所有不被Vue所管理的函數(shù)(定時器的回調(diào)函數(shù)、ajax的回調(diào)函數(shù)等、Promise的回調(diào)函數(shù)),最好寫成箭頭函數(shù),這樣this的指向才是vm 或 組件實例對象。
<div id="root">
姓:<input type="text" v-model="one"><br>
名:<input type="text" v-model="two"><br>
姓名:<span>{{three}}</span>
</div>
<script>
const vm = new Vue({
el: '#root',
data: {
one: '張',
two: '三',
three: '張-三'
},
computed: {
// fullName: {
// get() {
// return this.one + '-' + this.two;
// },
// set(value) {//fullName修改的值就是value
// let arr = value.split('-');
// this.one = arr[0];
// this.two = arr[1];
// }
// }
// 當(dāng)不要set的時候,可以簡寫
// fullName() {
// return this.one + '-' + this.two;
// },
},
watch: {
one(newValue){//誰調(diào)用?this就指向誰
// 普通one函數(shù)里面的this
console.log(this);//vue
// 需求:延遲1s輸出-------------------
setTimeout(()=> {
this.three = newValue + "-" + this.two;
// 這個this指向vue,而用正常函數(shù)的this,卻指向function
// 箭頭函數(shù)沒有自己的this值,它會繼承外部函數(shù)作用域中的this,也就是vm
// 如果是普通函數(shù),這個函數(shù)在定時器里面,是window調(diào)用的
console.log(this);
},1000)
},
two(newValue) {
setTimeout(()=>{
this.three = this.one + "-" + newValue;
},1000)
}
}
});
</script>
10、綁定class、style樣式
1、class樣式寫法
:class="xxx”xxx可以是字符串、對象、數(shù)組。
字符串寫法適用于:類名不確定,要動態(tài)獲取。
對象寫法適用于:要綁定多個樣式,個數(shù)不確定,名字也不確定。
數(shù)組寫法適用于:要綁定多個樣式,個數(shù)確定,名字也確定,但不確定用不用。
2、style樣式
:style="{fontsize: xxx}"其中xxx是動態(tài)值。
:style="其中a、b是樣式對象。樣式對象里面的key不能瞎寫,必須是存在的style樣式
<style>
#root div {
width: 300px;
height: 150px;
border: 1px solid pink;
}
.red {
background-color: red;
}
.green {
background-color: green;
}
.blue {
background-color: blue;
}
/* ---------------------------------- */
.cu {
font-weight: 700;
}
.size {
font-size: 70px;
}
.fStyle {
font-family: 華康娃娃體W5;
}
</style>
<div id="root">
<!-- 這里的change加不加()都行。這個color 必須綁定才有用 -->
<!-- 綁定class樣式--字符串寫法,適用于:樣式的類名不確定,需要動態(tài)指定 -->
<div @click="change" v-bind:class="color">123</div> <br>
<!-- 綁定class樣式--數(shù)組寫法,適用于:要綁定的樣式個數(shù)不確定、名字也不確定 -->
<div :class="classArr">123</div>
<button @click="shanchu">點擊刪除一個屬性</button>
<!-- 綁定class樣式--對象寫法,適用于: 要綁定的樣式個數(shù)確定、名字也確定,但要動態(tài)決定用不用 -->
<div :class="classObj">123</div>
<!-- 這個地方必須寫style樣式 -->
<div :style="classStyle">綁定style樣式</div>
<!-- 數(shù)組寫法 -->
<div :style="[classStyle,classStyle2]">綁定style樣式2</div>
<div :style="styleArr">綁定style樣式3</div>
</div>
<script>
new Vue({
el: '#root',
data: {
color: null,
classArr: ['cu', 'size', 'fStyle', 'red'],
classObj: {
green: true,
cu: true,
fStyle: true,
size: true,
},
classStyle: {
fontSize: '40px',
color: 'red',
},
classStyle2: {
backgroundColor: 'yellow',
},
// 不常用---------------------------
styleArr: [
{
fontSize: '40px',
color: 'red',
},
{
backgroundColor: 'yellow',
}
]
},
methods: {
change() {
const arr = ['red', 'green', 'blue'];
const index = Math.floor(Math.random() * 3);
console.log(index);
this.color = arr[index];
},
shanchu() {
this.classArr.pop();
}
},
});
</script>
11、條件渲染
1.V-if
寫法:
v-if=“表達式”
v-else-if=“表達式”
v-else=“表達式”
適用于:切換頻率較低的場景。
特點:不展示的DOM元素直接被移除
。
注意: v-if可以和:v-else-if、v-else一起使用,但要求結(jié)構(gòu)不能被“打斷”
2.V-show
寫法: v-show=“表達式”
適用于:切換頻率較高的場景。
特點:不展示的DOM元素未被移除,僅僅是使用樣式隱藏掉
3.備注: 使用v-if的時,元素可能無法獲取到,而使用v-show一定可以獲取到
被設(shè)置為 display: none 的盒子會從渲染樹中移除,它不再占據(jù)自己原先的盒子位置并且對文檔的布局也沒有任何影響。這意味著其他元素可以占據(jù)該盒子原本所在的區(qū)域。
與之相反,如果將一個元素的 visibility 屬性設(shè)置為 hidden,則改元素將隱藏,但仍會保留其原始空間,因此對布局仍有影響。
<div id="root">
<!-- 使用v-show做條件渲染 -->
<h2 v-show="1===4">正在學(xué)習(xí){{name}}</h2>
<h2 v-show="true">正在學(xué)習(xí){{name}}</h2>
<h2 v-show="a">正在學(xué)習(xí){{name}}</h2>
</div>
<script>
const vm = new Vue({
el: '#root',
data: {
name: 'vue',
a: true,
},
});
</script>
<div id="root">
<h2>當(dāng)前的n值是:{{n}}</h2>
<button @click="n++">點擊按鈕n++</button>
<button @click="add">點擊按鈕(add)n++</button>
<!-- add的返回值是一個數(shù)和n++的效果一樣 -->
<h2 v-if="1===n">anglar</h2>
<h2 v-if="2===n">react</h2>
<h2 v-if="3===n">vue</h2>
重點 如果if是正確條件,那么else if后面的代碼將不會被執(zhí)行-->
<h2 v-if="1===n">anglar</h2>
<h2 v-else-if="1===n">react</h2>
<h2 v-else-if="3===n">vue</h2>
<!-- template和if搭配 -->
<template v-if="n===1">
<h2>當(dāng)n=1時,展示出來</h2>
</template>
</div>
<script>
const vm = new Vue({
el: '#root',
data: {
name: 'vue',
a: true,
n: 0,
},
methods: {
add() {
let num = this.n++;
if (num > 2) {
this.n = 1;
}
return num;
}
},
});
</script>
12、列表渲染
1、遍歷數(shù)組對象
<div id="root">
<h2>遍歷數(shù)組對象</h2>
<ul>
<!-- 遍歷數(shù)組對象-------------------------------------------- -->
<!-- 這個:key,就是每一個節(jié)點的標(biāo)識,就相當(dāng)于身份證號 -->
<li v-for="p in persons" :key="p.id">
{{p.name}}-{{p.age}}
</li> <br>
<!--
()里面只有二個值
第一個:每一個對象
第二個:索引值:默認(rèn)從0開始
第三個:是underfined。即未定義,未定義的不顯示
-->
<li v-for="(a,b,c) in persons">
{{a}}-{{b}}----{{c}}
</li> <br>
<!--
p:是第一個,即是每一個對象
index:是二個,是索引號
-->
<li v-for="(p,index) in persons" :key="index">
{{p.name}}----{{p.age}}歲----{{index}}
</li> <br>
</ul>
</div>
new Vue({
el: '#root',
data: {
persons: [
{
id: 9,
name: '張三',
age: 345,
},
{
id: 2,
name: '李四',
age: 45,
},
{
id: 3,
name: '王五',
age: 57,
},
],
},
});
2、遍歷對象與、字符串
<div id="root">
<h2>遍歷對象</h2>
<ul>
<!--
第一個:屬性值
第二個:屬性名
第三個:索引號
第四個:未定義
-->
<li v-for="(a,b,c,d) in car">
{{a}}--{{b}}--{{c}}--{{d}}
</li>
</ul>
<h2>遍歷字符串</h2>
<ul>
<!--
第一個:屬性值
第二個:索引號
第三個:未定義(即:沒有,可以直接忽略)
-->
<li v-for="(a,b,c,d) in str">
{{a}}--{{b}}--{{c}}--{{d}}
</li>
</ul>
</div>
new Vue({
el: '#root',
data: {
car: {
name: '紅旗',
price: "50快",
origin: '中國',
},
str: 'hello',
},
});
只有遍歷對象:
第一個是屬性值
第二個是屬性名
第三個是索引號
其他都是:
第一個是值
第二個是索引號
13、收集表單數(shù)據(jù)
若:<input type="text"/>
,則v-model收集的是value值,用戶輸入的就是value值。
賬號:<input type="text" v-model.trim="accont">
密碼:<input type="text" v-model.trim="password">
若:<input type="radio"/>
,則v-model收集的是value值,且要給標(biāo)簽配置value值。
性別:
<input type="radio" name="sex" v-model="sex" value="male">男
<input type="radio" name="sex" v-model="sex" value="female">女
若: <input type="checkbox"/>
1.沒有配置input的value屬性,那么收集的就是checked (勾選 or 未勾選,是布爾值)
2.配置input的value屬性:
(1)v-model的初始值是非數(shù)組,那么收集的就是checked (勾選 or 未勾選,是布爾值)
(2)v-model的初始值是數(shù)組,那么收集的的就是value組成的數(shù)組備注。
愛好:
<input type="checkbox" v-model="hobby" value="study">學(xué)習(xí)
<input type="checkbox" v-model="hobby" value="eat">吃飯
<input type="checkbox" v-model="hobby" value="sleep">睡覺
v-model的三個修飾符:
lazy:失去焦點再收集數(shù)據(jù)
number:輸入字符串轉(zhuǎn)為有效的數(shù)字
trim: 輸入首尾空格過濾
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="../vue.js"></script>
</head>
<body>
<div id="root">
<form @submit.prevent="demo"><!-- 綁定默認(rèn)提交事件,并阻止提交 -->
<label>賬號:<input type="text" v-model.trim="accont"></label> <br>
<label>密碼:<input type="text" v-model.trim="password"></label> <br>
<label>年齡:<input type="number" v-model.number="age"></label> <br><br>
性別:
<label><input type="radio" name="sex" v-model="sex" value="male">男</label>
<label><input type="radio" name="sex" v-model="sex" value="female">女</label> <br><br>
愛好:
<label><input type="checkbox" v-model="hobby" value="study">學(xué)習(xí)</label>
<label><input type="checkbox" v-model="hobby" value="eat">吃飯</label>
<label><input type="checkbox" v-model="hobby" value="sleep">睡覺</label> <br><br>
所屬校區(qū):
<select v-model="city">
<option>請選擇所在校區(qū)</option>
<option value="beijing">北京</option>
<option value="henan">河南</option>
<option value="shanghai">上海</option>
<option value="wuhan">武漢</option>
</select><br><br>
其他信息:
<textarea v-model.lazy="other"></textarea><br><br>
<input type="checkbox" v-model="agree">閱讀并接受<a
href="https://passport.baidu.com/static/passpc-account/html/protocal.html">《用戶協(xié)議》</a>
<button>提交</button>
</form>
</div>
<script>
new Vue({
el: '#root',
data: {
accont: '',
password: '',
age: '',
sex: 'female',
hobby: [],
city: 'henan',
other: '',
agree: '',
},
methods: {
demo() {
console.log(this._data);
console.log(JSON.stringify(this._data));
}
},
});
</script>
</body>
</html>
14、腳手架
0、腳手架的安裝
具體步驟:
- 第一步(僅第一次執(zhí)行):全局安裝@vue/cli。
安裝一次,以后都不用安裝了
npm install -g @vue/cli
出現(xiàn)命令行界面,就表示安裝成功了。
- 第二步:
切換到你要創(chuàng)建項目的目錄
,然后使用命令創(chuàng)建項目。xxxx是項目名
vue create xxxx
然后選擇vue3或者2。
安裝成功!
- 4、運行vue。在項目根目錄下,輸入
npm run serve
成功訪問!
1、ref屬性
1.被用來給元素或子組件注冊引用信息 (id的替代者)
2.應(yīng)用在htm1標(biāo)簽上獲取的是真實DOM元素,應(yīng)用在組件標(biāo)簽上是組件實例對象(vc)
3.使用方式:
打標(biāo)識: <h1 ref="xxx">.....</h1>
或<School ref="xxx"</School>
獲取: this.$refs.xxx
<template>
<div>
<h2 v-text="msg" ref="hh2"></h2>
<button @click="show">點我可以看見h1</button>
<School ref="sch"></School>
</div>
</template>
<script>
// 引入School組件
import School from "./components/School.vue";
export default {
name: "App",
data() {
return {
msg: "好好學(xué)習(xí)Vue",
};
},
methods: {
show() {
console.log(document.querySelector("h2"));//真實dom
console.log(this.$refs.hh2);//真實dom
// 這個vc指的是school里面的
console.log(this.$refs.sch);//school組件的實例對象
},
},
// 注冊組件
components: {
School,
},
};
</script>
2、props配置
功能:讓組件接收外部傳過來的數(shù)據(jù)。
傳遞數(shù)據(jù):
<Student name='李四' :age=56 sex='男'></Student>
<Student name='張三' sex='女'></Student>
接收數(shù)據(jù):
第一種方式(只接收)
props:['name','age','sex',]
第二種方式(限制類型)
props:{
name:String,
age:Number,
sex:String,
}
第三種方式(限制類型、限制必要性、指定默認(rèn)值)
props: {
name: {
type: String, //name的類型是字符串
required: true, //name是必要的
},
age: {
type: Number,
default: 999, //默認(rèn)值
},
sex: {
type: String,
required: true,
},
},
備注: props是只讀的,Vue底層會監(jiān)測你對props的修改,如果進行了修改,
就會發(fā)出警告,若業(yè)務(wù)需求確實需要修改,那么請復(fù)制props的內(nèi)容到data
中一份,然后去修改data中的數(shù)據(jù)。
完整寫法
Student.vue
<template>
<!--組件的結(jié)構(gòu) -->
<div class="demo">
<h2>學(xué)生名字:{{ name }}</h2>
<h2>學(xué)生年齡:{{ myAge }}</h2>
<h2>學(xué)生性別:{{ sex }}</h2>
<button @click="addAge">點我年齡加1</button>
<h2>{{ msg }}</h2>
</div>
</template>
<script >
// 組件交互相關(guān)的腳本
//簡化版寫法
export default {
// 如果不寫name,別人在注冊組件的時候,隨便起名
// name的名稱與文件名保持一致
name: "Student",
data() {
return {
// name: "lxl",
// age: 23,
// sex:'男',
msg: "--------------加油----------------",
// myAge是屬性名,傳過來的數(shù)據(jù),先到props,再到data里面
myAge: this.age,
};
},
methods: {
addAge() {
this.myAge++;
},
},
// props:['name','age','sex',],//普通接收
// 接收的同時對數(shù)據(jù)進行類型限制
// props:{
// name:String,
// age:Number,
// sex:String,
// }
// 接收的同時對數(shù)據(jù):進行類型限制+默認(rèn)值的指定+必要性的限制
props: {
name: {
type: String, //name的類型是字符串
required: true, //name是必要的
},
age: {
type: Number,
default: 999, //默認(rèn)值
},
sex: {
type: String,
required: true,
},
},
};
</script>
<style>
.demo {
background-color: pink;
}
</style>
App.vue
<template>
<div>
<Student name='李四' :age=56 sex='男'></Student>
<Student name='張三' sex='女'></Student>
</div>
</template>
<script>
// 引入組件
import Student from "./components/Student.vue";
export default {
// app的作用:匯總所有組件
name: "App",
//注冊組件
components: {
Student,
},
};
</script>
<style>
</style>
3、mixin混入
mixin(混入)
功能: 可以把多個組件共用的配置提取成一個混入對象使用方式:
第一步定義混合,例如:
{
data(){…},
methods:{…}
}
第二步使用混入,例如:
(1).全局混入: Vue.mixin(xxx)
(2).局部混入:mixins:[ ‘xxx’ ]
項目結(jié)構(gòu)
mixin.js------------------------------------------------------------文章來源:http://www.zghlxwxcb.cn/news/detail-411399.html
// 分別暴漏
export const mixin = {
methods: {
tishi() {
alert(this.name);
}
},
}
// 除了方法,還可以暴露數(shù)據(jù)
export const mixin2 = {
data() {
return {
x: 100,
y: 200,
}
},
}
School.vue---------------------------------------------------------文章來源地址http://www.zghlxwxcb.cn/news/detail-411399.html
<template>
<!--組件的結(jié)構(gòu) -->
<div class="demo">
<h2>學(xué)校名字:{{ name }}</h2>
<h2>學(xué)校名字:{{ address }}</h2>
<button @click="tishi">點我提示學(xué)校</button>
</div>
</template>
<script >
// 引入mixin
import {mixin} from '../mixin'
//簡化版寫法
export default {
// 如果不寫name,別人在注冊組件的時候,隨便起名
// name的名稱與文件名保持一致
name: "School",
data() {
return {
name: "b站大學(xué)",
address: "online",
};
},
mixins:[mixin],
};
</script>
<style>
/* 組件的樣式 */
.demo {
background-color: pink;
}
</style>
到了這里,關(guān)于vue基礎(chǔ)知識的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!