視頻:【尚硅谷Vue2.0+Vue3.0全套教程丨vuejs從入門到精通】https://www.bilibili.com/video/BV1Zy4y1K7SH?vd_source=10e3dfac95ac3a6883b1f8a6c3bc65d5
看了很多市面上以后的筆記,大多都是復(fù)制粘貼代碼,讓我看的知其然而不知其所以然,于是打算自己寫一下這個課程的筆記,把一些老師的講解結(jié)合自己的理解也寫下來
教程內(nèi)容:
1.vue基礎(chǔ)
2.vue-cli
3.vue-router
4.vuex
5.element-ui
6.vue3
注:因為筆者學(xué)習(xí)過程中需要參與一個小項目,該項目需要使用到vue,但是記詳細(xì)的講解比較較為耗時,所以在1.10之后的筆記是只記錄使用方法和案例,不添加詳細(xì)講解。實際上,您可以直接訪問官網(wǎng)的文檔教程,如果您看了我的筆記的1.10之前的內(nèi)容,理解官網(wǎng)的教程應(yīng)該就比較簡單了,如果有不理解的,再去看老師的講解視頻,個人覺得這是較快的學(xué)習(xí)方法(當(dāng)然 ,時間充裕的,最好去聽老師講的課)
第1章 vue核心
1.1 vue簡介
1.1.1vue是什么
一套用于構(gòu)建用戶界面的漸進(jìn)式j(luò)s框架
-
構(gòu)建用戶界面:我只關(guān)注,你把數(shù)據(jù)給我,我怎么把數(shù)據(jù)變成界面
-
漸進(jìn)式:可以自底向上逐層應(yīng)用:
- 簡單應(yīng)用:只需要一個小巧的核心庫
- 復(fù)雜應(yīng)用:可以引入各式各樣的vue插件
1.1.2 誰開發(fā)的
1.1.3 vue的特點
- 采用組件化模式,提高代碼復(fù)用率、且讓代碼更好維護(hù)。
組件化:
以后其他人想用這個activity功能,直接應(yīng)用我的這個文件就行
更好維護(hù):哪個部分出了問題,就到哪個組件維護(hù)
- 聲明式編碼,讓編碼人員無需直接操作DOM,提高開發(fā)效率。
js:用代碼拼接html 這是命令式編碼
命令式:同學(xué),我渴了,你往前走兩步,到飲水機面前,拿出杯子,倒點水,回頭走到我旁邊,往我嘴里倒水
聲明式:同學(xué),我渴了。然后同學(xué)就把水裝給我了
- 使用虛擬DOM+優(yōu)秀的Dif算法,盡量復(fù)用DOM節(jié)點。
咱們還是用js舉例
原來你聲明了變量,賦值以后寫到html頁面上,之后,如果你的數(shù)據(jù)變了,刷新頁面的時候,相當(dāng)于把原來的刪除了,又從頭添加了數(shù)據(jù)。
而vue呢,先把三個數(shù)據(jù)轉(zhuǎn)換成虛擬dom,然后再轉(zhuǎn)換成頁面中的真實dom
數(shù)據(jù)變化之后,又生成了新的虛擬dom,他會把新的虛擬dom和原來的dom進(jìn)行比較,然后會把原本的數(shù)據(jù)復(fù)用,再添加上多出來的dom(這里的趙六)
- 學(xué)習(xí)Vue之前要掌握的javaScript基礎(chǔ)知識:
ES6語法規(guī)范 結(jié)構(gòu)函數(shù),模板字符串,箭頭函數(shù)
ES6模塊化 默認(rèn)暴露,同意暴露,分別暴露
包管理器 npm yarn cnpm
原型、原型鏈
數(shù)組常用方法 過濾一個數(shù)組,
axios
promise
當(dāng)然,如果哪個不會,老師也會簡單回顧一下
1.1.4 vue網(wǎng)站簡單了解(vue2文檔)
Vue.js (vuejs.org)
- 教程
按照教程說的一步一步來
- API
不會的就找字典
- 風(fēng)格指南
會教你怎么寫出優(yōu)雅的vue代碼
- 示例
看示例的時候,往右劃一劃,就能看到代碼
- cookbook
編碼技巧: 1 js基本功 2 vue代碼一些小技巧
指南和cookbook的不同:指南教你什么好,什么不好;cookbook教你實用的技巧
- 工具 核心插件
公司開發(fā)時用到的 ,很重要
- Awssome vue/瀏覽和vue相關(guān)的包
很多vue的周邊庫(steam的創(chuàng)意工坊)
1.1.5 搭建vue開發(fā)環(huán)境
根據(jù)文檔,安裝
我們可以看到,一個是直接scipt引入vue,另外一個是使用npm安裝
咱們先直接用引用
開發(fā)時,最好使用開發(fā)版本
點擊后,自動下載,上面的是開發(fā)版,下面的是生產(chǎn)版,過會會進(jìn)行對比
ok,我們在桌面新建一個文件夾,叫vue_basic
用vs code打開(不會有人前端已經(jīng)學(xué)到vue了還不知道什么是vscode吧,不會吧不會吧)
把兩個文件放在js文件夾中,新建html文件,新建完,?。剀?;html結(jié)構(gòu)就出來了
文件夾結(jié)構(gòu):
引入vue
<script type="text/javascript" src="../js/vue.js"></script>
如何證明我們引入了vue呢?
右鍵,在瀏覽器中打開(記得CTRL+s保存)
f12查看控制臺,可以看到兩個提示,一個說建議用開發(fā)工具開發(fā)vue,另一個說引入的vue有點大,不建議在生產(chǎn)環(huán)境中使用
輸入vue,敲回車,發(fā)現(xiàn)有了構(gòu)造方法,說明引用成功了
說回剛剛的問題,如何下載瀏覽器vue的開發(fā)工具,edge下載擴展
還要點上允許文件訪問
另外一個提示我們?nèi)绾坞[藏呢,這是vue的全局配置中的一個屬性,我們可以在文件中修改默認(rèn)值
1.2 初識vue
1.2.1 vue小案例
首先,我們要添加一個存放頁面的容器
容器,一般在11行,是一切的開始
輸入 div#root 回車 得到:
創(chuàng)建一個Vue對象 在19行
然后我們需要
配置對象
什么叫配置對象:對象中有需要配置的屬性:如anxios中要配置url,這個url你不能寫成ura,因為不存在這個屬性,url對應(yīng)的值寫在’'中,這是有規(guī)范的
好,我們開始寫vue的配置對象
第一個屬性 el
el是element的簡稱,里面的#root類似于css中的id選擇器,沒有第二十行的這個配置的時候,vue對象和id為root的容器是互相看不到的,加上之后,他們就互相匹配了
el用于指定當(dāng)前Vue實例為哪個容器服務(wù),值通常為css選擇器字符串。
第二個屬性 data
我們之前在容器中寫的是hhh,那我們想在我們的實例中動態(tài)的存放那個位置填寫的文字,怎么辦呢
很自然的,第二個屬性:data
data中用于存儲數(shù)據(jù),數(shù)據(jù)供el所指定的容器去使用,值我們暫時先寫成一個對象(以后可能寫成一個函數(shù))
這里用到了雙大括號(插值語法,后面會講到),這個實際上就是分隔符區(qū)分data的數(shù)據(jù)
寫到這我們發(fā)現(xiàn),const x一點用也沒有,我們可以去掉,完全不受影響
總結(jié)
-
想讓Vue工作,就必須創(chuàng)建一個Vue實例,且要傳入一個配置對象:
-
root容器里的代碼依然符html規(guī)范只不過混入了一些特殊的vue語法:
-
root容器里的代碼被稱為【Vue模板】
1.2.2 分析小案例
- 容器和實例之間的關(guān)系是一對一的,一一對應(yīng)
- 以后如果數(shù)據(jù)多了,會有組件功能來分擔(dān)數(shù)據(jù)
- =={{}}==中必須寫成js表達(dá)式
區(qū)分js表達(dá)式和js代碼
- js表達(dá)式:可以生成一個值,可以放在任何一個需要值的地方
- a
- a+b
- Data.now() 生成當(dāng)前時間戳
- demo(1) 函數(shù)調(diào)用表達(dá)式
- x==y ? ‘a(chǎn)’:‘b’ 三元表達(dá)式
- 以上的東西都是可以在左邊用一個const x= 接住的
- js代碼(語句)
- if(){}
- for(){}
- vue開發(fā)者工具
可以直接在這里修改數(shù)據(jù)
- 一旦data中的數(shù)據(jù)發(fā)生改變,那么模板中用到該數(shù)據(jù)的地方也會自動更新
1.3 模板語法
1.3.1 效果
實際上,模板語法有兩大類,一類就是{{}},插值語法
還有一類叫指令語法
比如,我們想在一個<a href=""></a>
標(biāo)簽里,動態(tài)存入href的值,該怎么做呢,第一反應(yīng)肯定是加一個{{}},我們試試看:
我們發(fā)現(xiàn),并沒有幫我轉(zhuǎn)換,看一下控制臺的報錯:
說以前這樣子寫是可以的,但是現(xiàn)在不行了,建議我們用v-bind
或者:
來寫
1.3.2 指令語法
引入 v-bind
:
我們在href前添加v-bind:
<a v-bind:href="url">點我跳轉(zhuǎn)</a>
發(fā)現(xiàn)url動態(tài)的顯示在href中了:
v-bind:
后的屬性值后的雙引號中的也是js表達(dá)式,且可以簡寫為:
簡寫:
<a :href="url">點我跳轉(zhuǎn)</a>
插值模板主要用在標(biāo)簽體中
指令語法主要用來管理標(biāo)簽屬性
總結(jié):
Vue模板語法有2大類:
1.插值語法:
功能:用于解析標(biāo)簽體內(nèi)容。
寫法:{{xxx}}:xx是的s表達(dá)式。且可以直接讀取到data中的所有屬性。
2.指令語法:
功能:用于解析標(biāo)簽(包括:標(biāo)簽屬性、標(biāo)簽體內(nèi)容、綁定事件…)。
舉例:v-bind:href="xxx"
域筒寫為::href="xxx"
,xxx同樣要列js表達(dá)式,且以直接讀取到data中的所有屬性.
備注:Vue中有根多的指令,且形式都是:v-???,此處我們只是拿v-bind舉個例子。
如果一個頁面有多個地方,需要name這個變量怎么辦:
我們可以name1,name2但是可讀性不高,所以我們可以在data中再新建對象,如圖:
使用這樣的方法區(qū)分不同的變量
1.4 數(shù)據(jù)綁定
1.4.1 單向數(shù)據(jù)綁定
v-bind是單向數(shù)據(jù)綁定
<input v-bind:value="name">
在這個input框中填寫數(shù)據(jù),data中name的值不會變,因為數(shù)據(jù)只能從data中到v-bind中
實例1:
容器:
<div id="root">
<input v-bind:value="name" />
<hr/>
{{name}}
</div>
一開始:
input中輸入數(shù)據(jù)后:
1.4.2 雙向數(shù)據(jù)綁定
引出新的指令模板 v-model
<input v-model:value="name" />
v-model可以雙向綁定,即在value中的數(shù)據(jù)也可以同步到data中:
總結(jié):
v-model只能用在表單類元素中(輸入類元素)
也就是說,有一個屬性是value的元素
v-model:value=可以簡寫成v-model=
番外 el和data的兩種寫法
正常說講到組件才要講這個,但是組件內(nèi)容太多了,所以拆到這里說一下
el
之前我們是在data中,通過el屬性來綁定vue實例和容器的。
除此之外,我們可以通過掛載的方式綁定
<script>
//創(chuàng)建Vue實例
const v = new Vue({
data: {
name: "五六七",
},
});
v.$mount("#root");
</script>
v.$mount的這個操作叫掛載
這兩種方式都可以,第二種比較靈活一點
data
原來的方法:
data:{
name:''
}
<script>
const v = new Vue({
data:{
name:''
}
});
v.$mount("#root");
</script>
這是對象式寫法,還有一種寫法,叫函數(shù)式
函數(shù)式:
<script>
const v = new Vue({
data: function(){
return{
name:'尚硅谷'
}
}
});
v.$mount("#root");
</script>
el 兩種方法都可以
但是data,以后用到組件的時候,只可以用函數(shù)式,不然會報錯,我們到時候會講到
由vue管理的函數(shù),不可以用箭頭函數(shù)(es6中的東西),寫了箭頭函數(shù)后,this就不再是vue實例了
1.5 MVVM模型
Vue的設(shè)計受到了MVVM模型的啟發(fā),設(shè)計時參考了這個模型
- M 模型(model) 對應(yīng)data中的數(shù)據(jù)
- V 視圖(View) 模板(頁面結(jié)構(gòu))
- VM 視圖模型(ViewModel) Vue實例對象
其實主流的前端框架都是這樣
所以我們經(jīng)常使用vm這個變量名表示Vue實例
觀察發(fā)現(xiàn):
1.data中所有的屬性,最后都出現(xiàn)在了vm身上.
2.vm身上所有的屬性及Vue原型上所有屬性,在Vue模版中都可以直接使用.
console.log一下vue實例
下面這些v的屬性數(shù)據(jù)都可以寫在模板中
原型中的也可以寫在里面(當(dāng)然,寫也沒什么意義,這些是用來調(diào)用的方法)
1.6 數(shù)據(jù)代理
1.6.1 回顧 Object.defineProperty方法
用于給對象添加屬性
需要三個參數(shù)
第一個是對象 第二個是屬性名 第三個是配置項
<script type="text/javascript">
let person={
age:'18',
name:'桃桃'
}
Object.defineProperty(person,'sex',{
value:'女'
})
console.log(person)
</script>
用這種方法添加的屬性,在遍歷時不會參與遍歷
如果想要這個屬性也可以參與遍歷,在用方法添加時,在配置項中添加一個叫enumerable的屬性
<script>
Object.defineProperty(person,'sex',{
value:'女',
enumerable:true
})
</script>
用這種方法添加的屬性,值也是不可以修改的:
要是想修改,添加屬性writable
同理,也無法刪除,想要刪除,添加屬性configurable
這些是基本的配置項,除此之外,我們可以添加一些高級的配置項 get set
比如我們不想要age的值是固定的,我們想要age的值是取決于一個叫做number的變量,然后number的值變了,age的值就會變,我們怎么寫呢
我們現(xiàn)在想要number值變了,我們的值也變,怎么辦呢,使用Object.defineProperty方法配置項中的get屬性
<script type="text/javascript">
let number = "女";
let person = {
age: "18",
name: "桃桃",
};
Object.defineProperty(person, "sex", {
// enumerable:true,
// writable:true,
// configurable:true
get:function(){
return number
}
});
console.log(person);
</script>
每一次訪問sex,都會觸發(fā)get方法的調(diào)用
set方法:
<script type="text/javascript">
let number = "女";
let person = {
age: "18",
name: "桃桃",
};
Object.defineProperty(person, "sex", {
// enumerable:true,
// writable:true,
// configurable:true
get:function(){
return number
},
set:function(value){
number=value
}
});
console.log(person);
</script>
每次有人修改sex的值,都會調(diào)用set方法
1.6.2 何為數(shù)據(jù)代理
通過一個對象代理對另一個對象中屬性的操作
比如有一個obj1對象,其中一個屬性是x,我們想通過另一個obj2對象來獲取和修改obj1中x屬性的值,應(yīng)該怎么做呢,這就可以用到上面學(xué)的東西
<script type="text/javascript">
let obj1={x:100}
let obj2={y:200}
Object.defineProperty(obj2,'x',{
get(){
return obj1.x;
},
set(value){
obj1.x=value;
}
})
</script>
模板語法中數(shù)據(jù)的值(data屬性中數(shù)據(jù)的值)就是通過數(shù)據(jù)代理存放到vm(vue實例)中的
1.6.3 數(shù)據(jù)代理在vue中的使用
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)的屬性.
options是Vue的配置對象的意思
vm._data實際上就是我們傳給它的data
所以以下這兩種表達(dá)方式都是可 以的
vm.data是用的數(shù)據(jù)代理
數(shù)據(jù)代理圖示:
1.7 事件處理
1.7.1 事件的基本使用:
- 使用v-on:xxx或@xxx綁定事件,其中xxx是事件名:
- 事件的回調(diào)需要配置在methods對象中,最終會在vm上:
- methods中配置的函數(shù),不要用箭頭函數(shù)!否則this就不是vm了:
- methods中配置的函數(shù),都是被Vue所管理的函數(shù),this的指向是vm或組件實例對象:
- @click="demo”和@click="demo($event)"效果一到,但后者可以傳參
在button中,綁定一個v-on指令,在vue實例中添加一個新屬性,methods,在里面添加方法,:
<body>
<div id="root">
<h1>{{name}}
</h1>
<button v-on:click="clickme">別點我</button>
</div>
</body>
<script type="text/javascript">
new Vue(
{
el: '#root',
data: {
name: '桃桃'
},
methods:{
clickme(){
alert('讓你別點,你個小壞蛋')
}
}
}
)
</script>
此時在頁面中點擊按鈕,就會彈出彈框
如果我們在方法中添加一個參數(shù),
click(a){
console.log(a);
}
在頁面中點擊時,發(fā)現(xiàn)打印在控制臺的是點擊事件
這是老師以前講的事件event(建議這部分去視頻里聽一下,因為我以前沒學(xué)過,肯定講不明白這個是什么東西,這個在視頻的p14 事件處理中)
我們把參數(shù)改為event,打印event.target這個是打印出事件觸發(fā)的元素,也就是我們的button標(biāo)簽
注意,所有被vue管理的函數(shù)不可以用箭頭函數(shù)
簡寫 v-on簡寫成@ v-on:click @click
如果想要傳參的話,就在click后雙引號里方法名后加括號,里面寫參數(shù),不傳參可以 不加括號
<button v-on:click="clickme('hello')">別點我</button>
當(dāng)然,也可以直接傳已定義的變量
<button v-on:click="clickme(name)">別點我</button>
這樣的話,就把之前的event搞丟了,可以在括號中添加$event來接受事件
1.7.2 事件修飾符
Vue中的事件修飾符:
- prevent:阻止默認(rèn)事件(常用)
<a href="www.baidu.com" @click="sum">點我</a>
正常點擊這個按鈕的時候,會先觸發(fā)sum方法,然后跳轉(zhuǎn)頁面,如果我們不想a標(biāo)簽觸發(fā)其默認(rèn)事件(訪問鏈接),我們可以在click后添加prevent,就不會訪問了
<a href="www.baidu.com" @click.prevent="sum">點我</a>
2.stop:阻止事件冒泡(常用):
當(dāng)存在標(biāo)簽嵌套,且內(nèi)外的標(biāo)簽都有調(diào)用的事件時,點擊里面的標(biāo)簽,會像冒泡一樣,觸發(fā)外面標(biāo)簽的事件:
<div @click="sum2">
<button @click="sum">點我</button>
</div>
如以上的代碼,點擊按鈕時,會先觸發(fā)sum方法,然后冒泡觸發(fā)sum2方法,如果外面像阻止冒泡,可以在里面的click后添加.stop以阻止事件冒泡
3.once:事件只觸發(fā)一次(常用):
這個就很好理解了,事件只觸發(fā)一次
后面三個不常用,我沒怎么聽懂,有學(xué)習(xí)需要的建議原視頻
4.capture:使用事件的捕獲模式:
5.self:只有event.target是當(dāng)前操作的元素時才觸發(fā)事件:
6.passive:事件的默認(rèn)行為立即執(zhí)行,無需等待事件回調(diào)執(zhí)行完畢:
如果需要多個修飾符,比如既要阻止冒泡,又要阻止默認(rèn)行為,可以@click.prevent.stop這代表先阻止默認(rèn)行為,再阻止冒泡。實際上他們哪個先阻止,效果是一樣的
1.7.3 鍵盤事件
keydown,按下去就觸發(fā)事件
keyup,按下去,抬上來之后才出發(fā)事件
event:當(dāng)前事件
event.target:當(dāng)前事件操作的元素
event.target.value 這是這個例子中input的value
<input @keyup='print'>
print(event){
console.log(event.target.value);
}
效果:
那問題來了,如果我們不想每次按鍵的時候都在控制臺輸出,而是按特定的案件才會輸出,怎么辦呢
我們知道每一個按鍵都有一個keyCode值(沒事,我也是才知道),我們可以先在控制臺輸出一下
可以看到,每次按完按鍵都會輸出按鍵對應(yīng)的鍵碼,
我們輸入回車,發(fā)現(xiàn)對應(yīng)的鍵碼是13,所以我們可以在方法中添加一個校驗,如果觸發(fā)當(dāng)前事件的按鍵鍵碼不是13,就不執(zhí)行,這樣,就只有回車時才會打印了。
實際上,以上操作可以直接在@keyup后加.enter來完成:
<input @keyup.enter='print'>
print(event){
console.log(event.target.value);
}
這里的enter是回車鍵的別名,@keyup.enter='print’的意思是按下enter鍵后會觸發(fā)print方法
鍵盤的每一個按鍵,除了鍵碼外也有自己對應(yīng)的名字,keyu后可以添加每一個按鍵的名字
我們可以這樣獲取當(dāng)前按鍵的名字和鍵碼:
print(event) {
console.log(event.key,event.keyCode);
}
.key就是按鍵的名字
如果要按下ctrl鍵觸發(fā),可以寫@keyup.Control或者@keyup.17
如果要求按下ctrl+y觸發(fā),我們可以寫@keyup.ctrl.y
這里的ctrl是別名
注意項:
-
Vue中常用的按鍵別名:
回車=>enter
刪除=>delete(捕獲“刪除”和“退格”鍵)
退出=>esc
空格=>space
換行=>tab
上=>up
下=>down
左=>1eft
右=>right -
Vue未提供別名的按鍵,可以使用按鍵原始的key值去綁定,但由兩個單詞組成的要注意要轉(zhuǎn)為kebab-case(短橫線命名)
-
系統(tǒng)修飾鍵(用法特殊):ctrl、alt、shift、meta(win)
(I).配合keyup使用:按下修飾鍵的同時,再按下其他鍵,隨后釋放其他鍵,事件才被觸發(fā)。
(2).配合keydown使用:正常觸發(fā)事件。 -
也可以使用keyCode去指定具體的按鍵(不推薦)
-
Vue.config.keyCodes.自定義鍵名=鍵碼,可以去定制按鍵別名
1.8 計算屬性
我們現(xiàn)在要完成一個需求,就是在兩個input框中分別填寫姓和名,要求自動在后面拼寫出完整的姓名
為了橫向?qū)Ρ龋覀兎謩e用{{}},methods,和計算屬性完成這個需求
1.8.1 {{}}
這個就太簡單了
直接上代碼
<body>
<div id="root">
姓:<input v-model="firstName"><br/>
名:<input v-model="lastName"><br/>
全名:<span>{{firstName}}+{{lastName}}</span>
</div>
</body>
<script type="text/javascript">
new Vue(
{
el: '#root',
data: {
firstName: '',
lastName:''
}
}
)
</script>
1.8.2 methods
可以在插值語法中調(diào)用方法,然后在方法中返回
注意,如果在{{}}中的方法不加(),在頁面中顯示的是方法體,加了()之后,返回的才是方法中return的值,這和之前的綁定事件不一樣
<body>
<div id="root">
姓:<input v-model="firstName"><br/>
名:<input v-model="lastName"><br/>
全名:<span>{{fullname()}}</span>
</div>
</body>
<script type="text/javascript">
new Vue(
{
el: '#root',
data: {
firstName: '',
lastName:''
},
methods: {
fullname(){
return this.firstName+this.lastName
}
}
}
)
</script>
1.8.3 computed 計算屬性
計算屬性:
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ā)生改變。
當(dāng)我們需要的數(shù)據(jù)是從兩個已有的屬性中計算得來的,這個計算得來的新屬性就被稱作計算屬性
<script type="text/javascript">
new Vue(
{
el: '#root',
data: {
firstName: '',
lastName: ''
},
computed: {
fullname: {
get() {
return this.firstName + '-' + this.lastName
}
}
}
}
)
</script>
computed中的都是計算屬性,和data很像,但是有g(shù)et和set方法,底層是Objcet.defineproperty實現(xiàn)的,然后插值模板中直接寫屬性名就可以 了: {{fullname}}
1.8.4 計算屬性的簡寫
當(dāng)某一個計算屬性只有g(shù)et,沒有set的時候,可以簡寫成函數(shù)的樣子
<script type="text/javascript">
new Vue(
{
el: '#root',
data: {
firstName: '',
lastName: ''
},
computed: {
fullname: function(){ //這一行也可以寫成 fullname(){
return this.firstName + '-' + this.lastName
}
}
}
)
</script>
當(dāng)然不要看到他長得像函數(shù),就把他當(dāng)成函數(shù)了,在{{}}中使用的時候,還是不能添加括號的。
1.9 監(jiān)視屬性
推薦插件
Vue 3 Snippets 會提示vue代碼
1.9.1 watch 監(jiān)視屬性
就是添加了一個新的配置項,watch,
當(dāng)watch中監(jiān)視的數(shù)據(jù)發(fā)生改變時,就會調(diào)用watch中的方法
直接引出watch中的方法,handler:
<body>
<div id="root">
姓:<input v-model="firstName"><br />
<button @click="firstName++">點我</button>
</div>
</body>
<script type="text/javascript">
new Vue(
{
el: '#root',
data: {
firstName: 1
},
watch: {
firstName: {
handler() {
console.log("firstname被改了")
}
}
}
}
)
</script>
在頁面中點擊按鈕修改firstName的值的時候,就會調(diào)用watch中的handler方法
handler可以接收兩個參數(shù),第一個是修改后的數(shù)據(jù),第二個是修改前的數(shù)據(jù):
handler(newvalue,oldvalue) {
console.log("firstname被改了" +newvalue+" "+oldvalue)
}
watch是在數(shù)據(jù)被修改之后,才會觸發(fā),如果在配置項中添加一個immediate屬性,就會在一開始加載頁面的時候,就觸發(fā)一次:
watch: {
firstName: {
handler() {
immediate:true,
console.log("firstname被改了")
}
}
同時,計算屬性中的數(shù)據(jù)也可以在watch中被監(jiān)視,使用方法相同 。
除了直接在vue()中配置以外,watch還可以在vue實例中手動配置:
<script type="text/javascript">
var vm = new Vue(
{
el: '#root',
data: {
firstName: 1
}
}
)
vm.$watch('firstName', {
handler(newvalue, oldvalue) {
console.log("firstname被改了" + newvalue + " " + oldvalue)
}
})
</script>
記得在vm.$watch()中,firstName要添加單引號,這是因為js中對象(還是變量?我不太清楚)需要用單引號表示,我們在vue中沒有添加單引號是因為我們簡寫了。
1.9.3 深度監(jiān)視
事情是這樣的,當(dāng)我們date中存儲一個對象number,里面有數(shù)據(jù)a和b,我們改變這個a的值時,想要監(jiān)視a的變化,而不是監(jiān)視整個number的變化,該怎么做呢
<div id="root">
{{number.a}}
<button @click="number.a++">點我增加</button>
</div>
<script type="text/javascript">
new Vue({
el:'#root',
data:{
number:{
a:1,
b:1
}
},
watch:{
'number.a':{
handler(a,b){
console.log("我又被改了"+a+b);
}
}
}
}
)
</script>
沒錯,方法就是直接使用number.a,但是注意,我們在number.a邊上添加了單引號,這是為什么呢。
實際上,我們在使用這些變量名時都是引用的key,在語法規(guī)范中,key就是要添加單引號,但當(dāng)只有一個單詞時,在vue框架中可以省略這個單引號,但是當(dāng)不是一個單詞時,就要把單引號重新加上
那如果我們想要當(dāng)number中的a或者b任意一個改變了,就檢測到number,我們該怎么做呢
watch:{
'number':{
handler(a,b){
console.log("我又被改了"+a+b);
}
}
}
我們發(fā)現(xiàn),直接使用number,不起作用。
實際上,number是這個對象的key,number后面的大括號實際上是這個對象的地址值,我們這樣寫,監(jiān)視的就是對象的地址值,a變了,b變了,但是地址值是不會變的。
如何讓watch監(jiān)視number中的值呢,我們在watch的number中添加一個配置項deep:
watch:{
number:{
deep:true,
handler(a,b){
console.log("我又被改了"+a+b);
}
}
}
這樣就會監(jiān)視number中的數(shù)據(jù)的改變
1.9.4 監(jiān)視的簡寫
當(dāng)你的監(jiān)視項只有一個handler時,就可以簡寫,就好像計算屬性,當(dāng)只有g(shù)et方法的時候,就可以簡寫
//原來的
watch:{
number:{
handler(a,b){
console.log("我又被改了"+a+b);
}
}
}
//修改后的:
watch:{
number(a,b){
console.log("我又被改了"+a+b);
}
}
或者,使用$f符添加,和之前的一樣
vm.$watch('number',{
deep:true,
handler(a,b){
console.log("我被修改啦"+a+b)
}
})
或者簡寫模式:
vm.$watch('number',function(a,b){
console.log("我被修改啦"+a+b)
}
)
1.9.5 computed和watch的區(qū)別
總結(jié):
computed和watch之間的區(qū)別:
1 computed能完成的功能,watch都可以完成。
2 watch能完成的功能,computed.不一定能完成,例如:watch可以進(jìn)行異步操作。
兩個重要的小原則:
- 所有被Vue管理的函數(shù),最好寫成普通函數(shù),這樣this的指向才是vm或組件實例對象。
- 所有不被Vue所管理的函數(shù)(定時器的回調(diào)函數(shù)、ajax的回調(diào)函數(shù)等),最好寫成箭頭函數(shù),這樣this的指向才是vm或組件實例對象。
1.8 class和style樣式
1.8.1 class樣式
我們使用:class來綁定動態(tài)的樣式
<div id="root">
<!-- 字符串寫法,適用于:樣式的類名不確定,需要動態(tài)指定 -->
<div class="basic" :class="mood">{{number.a}}</div>
<!-- 數(shù)組寫法,適用于:要綁定的樣式個數(shù)不確定,名字也不能確定 -->
<div class="basic" :class="moodArr">{{number.b}}</div>
<!-- 對象寫法,適用于:要綁定的樣式個數(shù)確定、名字也確定,但要動態(tài)決定用不用 -->
<div class="basic" :class="moodObj">{{number.b}}</div>
</div>
...
data:{
number:{
a:1,
b:2,
},
mood:'happy',
moodArr:['happy'],
moodObj:{
happy:true
}
},
肯定的不需要改變的樣式就放在class中,需要變化的就放在:class中
1.8.2 style樣式
正常的內(nèi)聯(lián)style樣式:
<div class="basic" style="background-color:red">測試</div>
···
使用動態(tài)的style樣式
```html
<div class="basic" :style="styleObj">{{number.b}}</div>
...
data:{
styleObj:{
backgroundColor:'red'
}
},
在style前面添加一個:
就可以了,和class一樣
總結(jié):
綁定樣式:
1 c1ass樣式
寫法:c1ass=“xxx”xxx可以是字符串、對象、數(shù)組。
字符串寫法適用于:類名不確定,要動態(tài)獲取。
對象寫法適用于:要綁定多個樣式,個數(shù)不確定,名字也不確定。
數(shù)組寫法適用于:要綁定多個樣式,個數(shù)確定,名字也確定,但不確定用不用。
2 style樣式
:style=”{fontsize:Xxx)“其中xxx是動態(tài)值。
:style=”[a,b]"其中a、b是樣式對象。
1.9 條件渲染
v-show
<h1 v-show="true"></h1>
當(dāng)v-show后面的雙引號中可以是true,false,1===3(false),或者是一個data中的變量a:
<h1 v-show="a"></h1>
...
data:{
a:true
}
v-if
<h1 v-if="true"></h1>
v-show是節(jié)點還在,只是動態(tài)的控制他的隱藏或者顯示,而v-if是把整個節(jié)點全都弄沒了
v-else-if
v-else
<h1 v-if="n===1">1</h1>
<h1 v-else-if="n===2">2</h1>
<h1 v-else-if="n===3">3</h1>
<h1 v-else>4</h1>
這四個需要連在一起,不可以被打斷
后面的用的比較多
當(dāng)我有三個相同判斷條件的想簡寫:
<h1 v-if="n===1">1</h1>
<h1 v-if="n===1">2</h1>
<h1 v-if="n===1">3</h1>
如上,三個的判斷條件都是一樣的,該如何簡化呢,第一反應(yīng)肯定是在外面包上一個div:
<div v-if="n===1">
<h1>1</h1>
<h1>2</h1>
<h1>3</h1>
</div>
但是這樣會破壞我們頁面的結(jié)構(gòu),比如我們要找body下的h1,就找不到了,所以我們可以使用另外一個標(biāo)簽:template
<template v-if="n===1">
<h1>1</h1>
<h1>2</h1>
<h1>3</h1>
</template>
這個標(biāo)簽不會破壞頁面的結(jié)構(gòu),但是template只能和v-if配合使用,不能和v-show配合使用
1.10 列表渲染
1.10.1 基本列表
v-for 類似于for循環(huán),
當(dāng)我們想要實現(xiàn)類似于下圖的效果時,肯定是不能寫死數(shù)據(jù)的,這就要我們通過遍歷的方式顯示數(shù)據(jù)
<!-- 遍歷數(shù)組 -->
在遍歷數(shù)組時,數(shù)組元素后面的一個參數(shù),是遍歷時的key值,因為我們這里沒有自定義key,所以默認(rèn)是012
<ul>
<li v-for="(person,b) in persons">
{}--{{person.name}}--{{person.age}}
</li>
</ul>
<!-- 遍歷對象 -->
遍歷對象時,括號中第一個參數(shù)是對象中鍵值對的值,第二個參數(shù)是鍵值對的鍵,第三個參數(shù)是這個這條遍歷的數(shù)據(jù)的key
<ul>
<li v-for="(value,key,b) in car">{}--{{key}}--{{value}}</li>
</ul>
遍歷字符串時,括號中第一個參數(shù)是字符串這個位置的值,第二個參數(shù)是這個這條遍歷的數(shù)據(jù)的key
<!-- 遍歷字符串 -->
<ul>
<li v-for="(value,key) in str">{{key}}--{{value}}</li>
</ul>
...
data: {
persons: [
{ id: "001", name: "ice", age: "13" },
{ id: "002", name: "peach", age: "12" },
],
car: {
speed: "20km/h",
year: "2014",
},
str: "i am a word",
},
展示效果:
我們要求,每一個遍歷的數(shù)據(jù)都需要一個獨有的key,在第一個例子中,可以這樣寫
<ul>
<li v-for="(person,index) in persons" :key="person.id">
{{index}}--{{person.name}}--{{person.age}}
</li>
</ul>
也可以直接寫:key=“index”,這就代表默認(rèn)的索引就是我們要的key
具體關(guān)于key的下一節(jié)講
遍歷指定次數(shù):
<ul>
<li v-for="(number,index) in 5" :key="index">
{{number}}--{{index}}
</li>
</ul>
1.10.2 key的原理和使用
面試題:react、vue中的key有什么作用?(key的內(nèi)部原理)
- 虛擬D0M中key的作用:
key是虛擬DoM對象的標(biāo)識,當(dāng)數(shù)據(jù)發(fā)生變化時,Vue會根據(jù)【新數(shù)據(jù)】生成【新的虛擬DoM】,
隨后Vue進(jìn)行【新虛擬DoM】與【舊虛擬DoM】的差異比較,比較規(guī)則如下: - 對比規(guī)則:
(1).舊虛擬DoM中找到了與新虛擬DoM相同的key:
a.若虛擬D0M中內(nèi)容沒變,直接使用之前的真實D0M!
b.若虛擬D0M中內(nèi)容變了,則生成新的真實D0M,隨后替換掉頁面中之前的真實D0M。
(2).舊虛擬DoM中未找到與新虛擬DoM相同的key
創(chuàng)建新的真實DOM,隨后渲染到到頁面。 - 用index作為key可能會引發(fā)的問題:
1,若對數(shù)據(jù)進(jìn)行:逆序添加、逆序刪除等破壞順序操作:
會產(chǎn)生沒有必要的真實D0M更新==>界面效果沒問題,但效率低。
2.如果結(jié)構(gòu)中還包含輸入類的D0M:
會產(chǎn)生錯誤D0M更新=>界面有問題。 - 開發(fā)中如何選擇key?:
1.最好使用每條數(shù)據(jù)的唯一標(biāo)識作為key,比如id、手機號、身份證號、學(xué)號等唯一值。
2.如果不存在對數(shù)據(jù)的逆序添加、逆序剛除等破壞順序操作,僅用于渲染列表用于展示,使用index作為key是沒有問題的。
1.10.3 列表過濾(查詢效果)
實現(xiàn)如下效果:
兩種方法:
1watch監(jiān)視:
注意點:
- 使用一個數(shù)組persnsOfSearch來接受過濾后返回的值
- 在watch中添加一個immediate,已確保一開始的時候就運行一次watch來顯示數(shù)據(jù)
- indexOf顯示方法參數(shù)在字符串中第一次出現(xiàn)的索引,不存在的返回-1,如果方法參數(shù)是
''
空字符串,返回0
<body>
<div id="root">
<label>姓名:</label><input v-model="name">
<ul>
<li v-for="(person) in persnsOfSearch">
{{person.name}}--{{person.age}}
</li>
</ul>
</div>
</body>
<script type="text/javascript">
var vm = new Vue(
{
el: '#root',
data: {
name: '',
persnsOfSearch: [],
persons: [{ id: '001', name: 'ice', age: '17' }, { id: '002', name: 'ipeach', age: '18' }, { id: '003', name: 'icepeach', age: '19' }]
},
watch: {
name: {
immediate: true,
handler(newValue, oldValue) {
this.persnsOfSearch= this.persons.filter((p) => {
return p.name.indexOf(newValue) != -1
})
},
}
}
}
)
</script>
使用計算屬性實現(xiàn):
<body>
<div id="root">
<label>姓名:</label><input v-model="name">
<ul>
<li v-for="(person) in persnsOfSearch">
{{person.name}}--{{person.age}}
</li>
</ul>
</div>
</body>
<script type="text/javascript">
var vm = new Vue(
{
el: '#root',
data: {
name:'',
persons: [{ id: '001', name: 'ice', age: '17' }, { id: '002', name: 'ipeach', age: '18' }, { id: '003', name: 'icepeach', age: '19' }]
},
computed:{
persnsOfSearch(){
return this.persons.filter((p) => {
return p.name.indexOf(this.name) != -1
})
}
}
}
)
</script>
可以看到,使用computes明顯要更簡單一些,所以當(dāng)computed和watch都可以實現(xiàn)某個功能時,使用computed更好一些
1.10.4 排序
還是在computed中排序
注意點:
- 在計算屬性中,先過濾,后排序,把過濾好的數(shù)據(jù)暫時存到一個數(shù)組中,然后排序,再返回
- 使用sort(a,b)的方法來排序:
若 a 小于 b,在排序后的數(shù)組中 a 應(yīng)該出現(xiàn)在 b 之前,則返回一個小于 0 的值。
若 a 等于b,則返回 0。
若 a 大于 b,則返回一個大于 0 的值。
簡單點就是:比較函數(shù)兩個參數(shù)a和b,返回a-b 升序,返回b-a 降序
效果:
<body>
<div id="root">
<label>姓名:</label><input v-model="name">
<button @click="sortType = 0">原順序</button>
<button @click="sortType = 1">降序</button>
<button @click="sortType = 2">升序</button>
<ul>
<li v-for="(person) in persnsOfSearch">
{{person.name}}--{{person.age}}
</li>
</ul>
</div>
</body>
<script type="text/javascript">
var vm = new Vue(
{
el: '#root',
data: {
name: '',
sortType: 0,//0 原順序 1 降序 2 升序
persons: [{ id: '001', name: 'ice', age: '17' }, { id: '002', name: 'ipeach', age: '18' }, { id: '003', name: 'icepeach', age: '19' }]
},
computed: {
persnsOfSearch() {
const arr = this.persons.filter((p) => {
return p.name.indexOf(this.name) != -1
})
if (this.sortType) {
arr.sort((p1, p2) => {
return this.sortType === 1 ? p2.age - p1.age : p1.age - p2.age
})
}
return arr;
}
}
}
)
</script>
1.10.5 監(jiān)視數(shù)據(jù)改變的原理
Vue監(jiān)視數(shù)據(jù)的原理:
- vue會監(jiān)視data中所有層次的數(shù)據(jù)。
- 如何監(jiān)測對象中的數(shù)據(jù)
通過setter實現(xiàn)監(jiān)視,且要在new Vue時就要傳入要檢測的數(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ù)組更新元素的方法實現(xiàn),本質(zhì)就是做了兩件事:
(1).調(diào)用原生對應(yīng)的方法對數(shù)組進(jìn)行更新。
(2).重新解析模板,進(jìn)而更新頁面。 - 在Vue修改數(shù)組中的某個元素一定要用如下方法:
1.使用這些API:push()、pop()、shift()、unshift()、splice()、sort()、reverse()
2.Vue.set()或者vm. s e t ( ) 特別注意: V u e . s e t ( ) 和 v m . set() 特別注意:Vue.set()和vm. set()特別注意:Vue.set()和vm.set()不能給vm或vm的根數(shù)據(jù)對象添加屬性?。?/li>
1.11 獲取表單數(shù)據(jù)
朋友們,這個很簡單,我直接上總結(jié)了
還可以參考官方這部分教程,例子要全一些:
表單輸入綁定
收集表單數(shù)據(jù):
- ,則v-model收集的是value值,用戶輸入的就是value值。
- ,則v-model收集的是value值,且要給標(biāo)簽配置value值。
1.沒有配置input的value屬性,那么收集的就是checked(勾選or未勾選,是布爾值)
2.配置input的value屬性:
(1)v-model的初始值是非數(shù)組,那么收集的就是checked(勾選or未勾選,是布爾值)
(2)v-mode1的初始值是數(shù)組,那么收集的的就是va1ue組成的數(shù)組
備注:v-mode1的三個修飾符:
1azy:失去焦點再收集數(shù)據(jù)
number:輸入字符串轉(zhuǎn)為有效的數(shù)字
trim:輸入首尾空格過濾
1.12 過濾器
過濾器在vue3中已經(jīng)被取消了,而且過濾器能實現(xiàn)的功能,computed,methods之類的基本都能實現(xiàn),所以簡單概括
過濾器:
定義:對要顯示的數(shù)據(jù)進(jìn)行特定格式化后再顯示(適用于一些簡單邏輯的處理)。
語法:
- 注冊過濾器:Vue.filter(name,callback)或new Vue{filters:({}】
- 使用過濾器:{{xxx|過濾器名}}或v-bind:屬性=“xxx | 過濾器名”
備注 - 過濾器也可以接收額外參數(shù)、多個過濾器也可以串聯(lián)
- 并沒有改變原本的數(shù)據(jù),是產(chǎn)生新的對應(yīng)的數(shù)據(jù)
1.13 內(nèi)置指令
1.13.1 v-text
我們學(xué)過的指令:
v-bind:單向綁定解析表達(dá)式,可簡寫為:xxx
v-mode:雙向數(shù)據(jù)綁定
v-for:遍歷數(shù)組/對象/字符串
v-on:綁定事件監(jiān)聽,可簡寫為
v-if:條件渲染(動態(tài)控制節(jié)點是否存存在)
v-else:條件渲染(動態(tài)控制節(jié)點是否存存在)
v-show:條件渲染(動態(tài)控制節(jié)點是否展示)
v-text指令:
1.作用:向其所在的節(jié)點中誼染文本內(nèi)容。
2.與插值語法的區(qū)別:V-text會替換掉節(jié)點中的內(nèi)容,{{xx}}則不會。
1.13.2 v-html指令
1.作用:向指定節(jié)點中誼染包含html結(jié)構(gòu)的內(nèi)容。
2.與插值語法的區(qū)別
(1).v-html會替換掉節(jié)點中所有的內(nèi)容,{{xx}}則不會.
(2).v-html可以識別html結(jié)構(gòu).
3.嚴(yán)重注意:v-htm1有安全性問題?。。?!
(1).在網(wǎng)站上動態(tài)渲染任意HTML是常危險的,容易導(dǎo)致XSS政擊。
(2).一定要在可信的內(nèi)容上使用v-html,永不要用在用戶提交的內(nèi)容上!
1.13.3 v-cloak指令
v-cloak指令(沒有值):
- 本質(zhì)是一個特殊屬性,Vue實例創(chuàng)建完畢并接管容器后,會刪掉v-cloak屬性.
- 使用css配合v-cloak可以解決網(wǎng)速慢時頁面展示出{{xx}}的問題。
<style>
[v-cloak]{
dispaly:none
}
</style>
...
<h2 v-cloak>{{}}</h2>
1.13.4 v-once
需求:如果我們想要展示某一個數(shù)據(jù)的初識值,即使數(shù)據(jù)被改變也只展示初識值,就可以使用v-once
<h1 v-once>{{time}}</h1>
- v-once所在節(jié)點在初次動態(tài)渲染后,就視為靜態(tài)內(nèi)容了。
- 以后數(shù)據(jù)的改變不會引起v-once所在結(jié)構(gòu)的更新,可以用于優(yōu)化性能。
1.13.5 v-pre指令
1.跳過其所在節(jié)點的編譯過程。
2.可利用它跳過過沒有使用指令語法、沒有使用插值語法的節(jié)點,會加快編譯。
就是說標(biāo)簽上加了這個之后,就不會再編譯這一個標(biāo)簽了,所以只要我們用到了插值,指令就不要用這個
<h2 v-pre>你好</h2>
<h2 v-pre>當(dāng)前的值是:{{n}}</h2>
1.13.6 自定義指令
各位好啊,自定義指令的教程較為復(fù)雜,我有些犯懶了,這里就直接貼上老師的筆記了:
1.14 生命周期
分開的截圖(為了讓您看的更清晰一些):
完整圖:
首先生命周期說的是Vue的生命周期而不是vm的生命周期
vm的一生(vm的生命周期):
將要創(chuàng)建===>
調(diào)用beforeCreatei函數(shù)。
創(chuàng)建完畢===>
調(diào)用created函數(shù)。
將要掛載===>
調(diào)用beforeMount函數(shù)。
(重要)掛載完畢===>
調(diào)用mountedi函數(shù)。=======>
【重要的鉤子】
將要更新===>
調(diào)用beforeUpdatei函數(shù)。
更新完畢===>
調(diào)用updated函數(shù)。
(重要)將要銷毀===>
調(diào)用beforeDestroyi函數(shù)。=====>【重要的鉤子】
銷毀完畢==>
調(diào)用destroyed函數(shù)。
人生最重要的時刻:出生(mounted時候,我們一上來要做的事情都放在這)和將要離開的時候(beforeDestory 關(guān)閉你以前訂閱的消息,關(guān)閉定時器,刪除瀏覽記錄之類的)
2 組件
好耶,我們終于進(jìn)入第二章了!前面學(xué)了那么久,竟然還只是第一張,我真的栓Q,還好堅持到現(xiàn)在。
學(xué)完組件,就開始學(xué)腳手架了,激動的嘞~
我們要搞懂,什么是組件,為什么要用組件
2.1 模塊和組件,模塊化和組件化
傳統(tǒng)的寫頁面的方式:
寫html,寫css,寫js,然后寫新的頁面時,復(fù)制相同的css,js代碼,再加上自己的代碼
2023了,誰還用傳統(tǒng)方式編程?。╩d,我就是)
模塊:
- 理解:向外提供特定功能的js程序,一般就是一個js文件
- 為什么:js文件很多很復(fù)雜
- 作用:復(fù)用js,簡化js的編寫,提高js運行效率
組件:
- 理解:用來實現(xiàn)局部特定)功能效果的代碼集合(html/css/js/image.)
- 為什么:一個界面的功能很復(fù)雜
- 作用:復(fù)用編碼,簡化項目編碼,提高運行效率
模塊化:當(dāng)應(yīng)用中的js都以模塊來編寫的,那這個應(yīng)用就是一個模塊化的應(yīng)用。
組件化:當(dāng)應(yīng)用中的功能都以組件的方式來編寫,那這個應(yīng)用就是一個組件化的應(yīng)用。
2.2 非單文件組件
2.2.1 基本使用
創(chuàng)建組件的api:Vue.extend({})
大括號里面,幾乎和我們之前寫vm一樣,該data就data,該methods就methods
但是不能用el哦
Vue中使用組件的三大步驟:
一、 定義組件(創(chuàng)建組件)
二、 注冊組件
三、 使用組件(寫組件標(biāo)簽)
一、如何定義一個組件?
使用Vue.extend(options)創(chuàng)建,其中options和new Vue(options)時傳入的那個options幾乎一樣,但也有點區(qū)別:
區(qū)別如下:
- el不要寫,為什么?
最終所有的組件都要經(jīng)過一個vm的管理,由vm中的el決定服務(wù)哪個容器。 - data必須寫成函數(shù),為什么?
避免組件被復(fù)用時,數(shù)據(jù)存在引用關(guān)系。
備注:使用template可以配置組件結(jié)構(gòu)。
二、如何注冊組件?
1.局部注冊:靠new Vue的時候傳入components選項(只在這一個實例里生效)
2.全局注冊:靠Vue.component(‘組件名’,組件)
三、
編寫組件標(biāo)簽:
<body>
<div id="root">
<hello></hello>
<hr>
<h1>{{msg}}</h1>
<hr>
<!-- 第三步:編寫組件標(biāo)簽 -->
<school></school>
<hr>
<!-- 第三步:編寫組件標(biāo)簽 -->
<student></student>
</div>
<div id="root2">
<hello></hello>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false
//第一步:創(chuàng)建school組件
const school = Vue.extend({
template:`
<div class="demo">
<h2>學(xué)校名稱:{{schoolName}}</h2>
<h2>學(xué)校地址:{{address}}</h2>
<button @click="showName">點我提示學(xué)校名</button>
</div>
`,
// el:'#root', //組件定義時,一定不要寫el配置項,因為最終所有的組件都要被一個vm管理,由vm決定服務(wù)于哪個容器。
data(){
return {
schoolName:'江南大學(xué)',
address:'無錫'
}
},
methods: {
showName(){
alert(this.schoolName)
}
},
})
//第一步:創(chuàng)建student組件
const student = Vue.extend({
template:`
<div>
<h2>學(xué)生姓名:{{studentName}}</h2>
<h2>學(xué)生年齡:{{age}}</h2>
</div>
`,
data(){
return {
studentName:'桃桃',
age:18
}
}
})
//第一步:創(chuàng)建hello組件
const hello = Vue.extend({
template:`
<div>
<h2>你好??!{{name}}</h2>
</div>
`,
data(){
return {
name:'Tom'
}
}
})
//第二步:全局注冊組件
Vue.component('hello',hello)
//創(chuàng)建vm
new Vue({
el:'#root',
data:{
msg:'你好??!'
},
//第二步:注冊組件(局部注冊)
components:{
school,
student
}
})
new Vue({
el:'#root2',
})
</script>
2.2.2 注意項
幾個注意點:
- 關(guān)于組件名:
一個單詞組成:
第一種寫法(首字母小寫):school
第二種寫法(首字母大寫):School
多個單詞組成:
第一種寫法(kebab-case命名):my-school
第二種寫法(CamelCase命名):MySchool (需要Vue腳手架支持)
備注:
(1).組件名盡可能回避HTML中已有的元素名稱,例如:h2、H2都不行。
(2).可以使用name配置項指定組件在開發(fā)者工具中呈現(xiàn)的名字。
//定義組件
const s = Vue.extend({
name:'peach',
template:`
<div>
<h2>學(xué)校名稱:{{name}}</h2>
<h2>學(xué)校地址:{{address}}</h2>
</div>
`,
data(){
return {
name:'尚硅谷',
address:'北京'
}
}
})
之后,開發(fā)者工具中顯示的名字就是peach了
2. 關(guān)于組件標(biāo)簽:
第一種寫法:<school></school>
第二種寫法:<school/>
備注:不用使用腳手架時,會導(dǎo)致后續(xù)組件不能渲染。
- 一個簡寫方式:
const school = Vue.extend(options) 可簡寫為:const school = options
2.2.3 嵌套組件
實際上,嵌套組件就是前兩節(jié)的使用,只不過是在創(chuàng)建一個組件時,本身再添加之前創(chuàng)建的組件,沒有什么其他的東西,很多同學(xué)覺得困難,是因為前兩節(jié)沒學(xué)好
<body>
<!-- 準(zhǔn)備好一個容器-->
<div id="root">
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false //阻止 vue 在啟動時生成生產(chǎn)提示。
//定義student組件
const student = Vue.extend({
name:'student',
template:`
<div>
<h2>學(xué)生姓名:{{name}}</h2>
<h2>學(xué)生年齡:{{age}}</h2>
</div>
`,
data(){
return {
name:'尚硅谷',
age:18
}
}
})
//定義school組件
const school = Vue.extend({
name:'school',
template:`
<div>
<h2>學(xué)校名稱:{{name}}</h2>
<h2>學(xué)校地址:{{address}}</h2>
<student></student>
</div>
`,
data(){
return {
name:'尚硅谷',
address:'北京'
}
},
//注冊組件(局部)
components:{
student
}
})
//定義hello組件
const hello = Vue.extend({
template:`<h1>{{msg}}</h1>`,
data(){
return {
msg:'歡迎來到尚硅谷學(xué)習(xí)!'
}
}
})
//定義app組件
const app = Vue.extend({
template:`
<div>
<hello></hello>
<school></school>
</div>
`,
components:{
school,
hello
}
})
//創(chuàng)建vm
new Vue({
template:'<app></app>',
el:'#root',
//注冊組件(局部)
components:{app}
})
</script>
2.2.4 關(guān)于VueComponent
- school組件本質(zhì)是一個名為VueComponent的構(gòu)造函數(shù),且不是程序員定義的,是Vue.extend生成的。
- 我們只需要寫或,Vue解析時會幫我們創(chuàng)建school組件的實例對象,
即Vue幫我們執(zhí)行的:new VueComponent(options)。 - 特別注意:每次調(diào)用Vue.extend,返回的都是一個全新的VueComponent!?。?!
- 關(guān)于this指向:
(1).組件配置中:
data函數(shù)、methods中的函數(shù)、watch中的函數(shù)、computed中的函數(shù) 它們的this均是【VueComponent實例對象】。
(2).new Vue(options)配置中:
data函數(shù)、methods中的函數(shù)、watch中的函數(shù)、computed中的函數(shù) 它們的this均是【Vue實例對象】。 - VueComponent的實例對象,以后簡稱vc(也可稱之為:組件實例對象)。
Vue的實例對象,以后簡稱vm。
實際上 vc和vm是很像的雙胞胎
2.2.5
首先我們要知道一個前置知識:
這段看不懂的,需要去學(xué)一下es6中的高級js知識
<script>
//定義一個構(gòu)造函數(shù)
function Demo(){
this.a = 1
this.b = 2
}
//創(chuàng)建一個Demo的實例對象
const d = new Demo()
console.log(Demo.prototype) //顯示原型屬性
console.log(d.__proto__) //隱式原型屬性
console.log(Demo.prototype === d.__proto__)
//程序員通過顯示原型屬性操作原型對象,追加一個x屬性,值為99
Demo.prototype.x = 99
console.log('@',d)
</script>
各位好,為了速成(做項目),我先不看視頻了找個筆記去學(xué)一下
看的這個筆記:
筆記地址
組件的自定義事件總結(jié):
全局事件總線
消息訂閱
axios
上圖中2,3都是封裝的1,如果1不能用了,2,3就都不能用了。
然后jQuery的80%內(nèi)容都在封裝dom,剩下的才是封裝一些周邊的東西,比如$.get
,$.post
然后fetch和xhr是平級的,但是有兩個問題,就是它封裝了兩次promise,所以要then兩次才能拿到數(shù)據(jù),然后它存在兼容性問題,比如ie瀏覽器就不可以使用fetch
綜上,我們使用axios
首先,我們寫一個axios的get
運行的時候我們發(fā)現(xiàn),哎呀媽呀跨域了,為什么會跨域呢,原因是我們違背了同源原則
同源原則:協(xié)議名,主機名,端口號
如下圖,端口號對不上
實際上,我們請求之后,服務(wù)器是收到了請求,而且把數(shù)據(jù)返回了,但是瀏覽器一看,哎不同源,就把數(shù)據(jù)藏起來了
解決方法
1cors:
在服務(wù)器里,返回數(shù)據(jù)的時候,添加了一些請求頭,然后瀏覽器一看,你都這么表態(tài)了,那我就把數(shù)據(jù)給你吧。所以在服務(wù)器解決跨域問題才是真正的解決跨域
2 jsonp
只能解決get請求的
3 配置代理服務(wù)器
使用方法:1 nginx(有點麻煩) 2 vue-cli
vue-cli:
添加配置的第一種方法:
vue-cli添加配置的第er二種方法
加上·pathRewrite:{'/atguigu':''
的意思是,在把請求中的atguigu去掉
總結(jié):
vuex
文章來源:http://www.zghlxwxcb.cn/news/detail-423824.html
我們現(xiàn)在用的是vue2,所以要安裝vuex3文章來源地址http://www.zghlxwxcb.cn/news/detail-423824.html
到了這里,關(guān)于尚硅谷vue筆記 詳細(xì)講解版(尚硅谷 天禹老師)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!