![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5CO1UGNlVGO4YmM0gDZxkjZ4IjYhFjZiNTYkBDM5QjNk9CX0JXZ252bj91Ztl2Lc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
元件
vue中元件的注冊方式分為兩種
1.全局注冊
import Vue from 'vue';
Vue.component('gl-nav',{//第一個參數是元件的名字
template:'<button>{{name}}</button>',//指向元件對應的模闆
data:()=>{
return {
name:'cmy',
i:0
}//用來定義資料
},
props:{
//接受對應的傳參
},
computed:{
//計算屬性
},
watch:{
//監聽屬性發生變化
name(newdata,olddata){
//接受兩個參數,第一個是改變後的值,第二個是之前的值
}
}
methods:{//相應的方法
add(){
this.name+=this.i+1;
}
}
...
})
全局注冊的元件在任意元件中都可以調用的到,但是很多時候我們注冊元件隻需要他在父元件裡面調用就可以了,是以全局元件适合注冊一些基礎的,通用的,可重複利用的元件全局注冊元件必須在根vue執行個體化之前發生
2.局部注冊 在vue裡面最常見的方式就是建立單檔案元件
<template>
//主要用來渲染模闆
</template>
<script>
//寫元件的結構,通過export default 抛出一個對象
export default {
data () {
return {
}//定義資料
},
props:{
//接受對應的傳參
},
computed:{
//計算屬性 需要有傳回值
},
watch:{
//監聽屬性發生變化 可以監聽到data,props,$route路由的變化
name(newdata,olddata){
//接受兩個參數,第一個是改變後的值,第二個是之前的值
}
//如果要監聽的是一個對象的話隻能挨個監聽他們的屬性
'opt.name'(newsata,olddata){
}
}//可以通過let key = this.$watch('key',(n,o)=>{
...//要做的事情
})
key()//取消監聽
methods:{//相應的方法
add(){
}
}
}
</script>
<style scoped>//這個屬性可以對元件的樣式做子產品化處理
//用來寫元件的樣式
</style>
單檔案元件裡面有一個
- <template> 主要用來做模闆
- <script> 元件的結構
- <style> 元件的樣式上面的scoped可以對元件的樣式做子產品化處理,還可以根據lang屬性去選擇使用的語言
除了全局元件,每一個元件的使用都需要通過import 将元件引入,然後通過components注冊,之後才可以使用這個元件。 局部注冊的元件隻能哪裡引入哪裡用。
元件的生命周期
vue中元件的生命周期分為
- 初始化階段(主要做資料初始化)
- beforeCreate data和watch還沒有被調用
- created 主要做了data,$watch,props,methods,$event方法的執行個體
- DOM挂載階段
- beforeMount 主要做元件的渲染,在挂載之前被調用
- mounted 可以做元件的dom操作,也就是可以擷取到$el屬性(挂載到的dom元素)
- 更新階段(當元件中修改了某一資料去重新觸發渲染的時候觸發)
- beforeUpdate 資料更新的時候調用,這時候dom還沒有重新渲染
- updated dom重新渲染之後會調用,是以現在可以執行依賴dom的操作了,但不應該在這個生命周期更改狀态,會觸發死循環,如果要改變狀态可以使用計算屬性或者watch監聽來實作 updated生命周期的時候子元素有可能還沒有被重新渲染,如果希望視圖重繪完畢之後可以使用this.$nextTick this.$nextTick().then(//DOM更新之後執行)//傳回值是一個promise 如果浏覽器不支援promise自行解決
- 解除安裝階段
- beforeDestroy 元件解除安裝之前被調用 執行個體銷毀之前調用一次,這時候執行個體還是可用的
- destroyed 元件解除安裝的時候會被執行,元件的指令包括事件進行解綁,資料,包括dom挂載的那些事件都會被銷毀,但不會移除咱們用原生dom方法添加的事件,也不會移除setTimeout,setInterval這種定時器,如果有類似的操作就需要在這個生命周期中進行手動銷毀
- 如果緩存啟用的時候會有
- activated keep-alive元件激活時調用
- deactivated keep-alive元件停用時調用 元件的銷毀階段永遠不會執行 模拟了一個元件銷毀 但并不是真正的元件銷毀
- 新增了錯誤處理生命周期
- errorCaptured 當捕獲到一個來自子孫元件的錯誤的時候被調用錯誤對象、發生錯誤的元件執行個體以及一個包含錯誤來源資訊的字元串。此鈎子可以傳回 false 以阻止該錯誤繼續向上傳播。
單頁面路由
單頁面路由指的是隻有一個頁面,但是有多個路由的應用,不向伺服器發起請求,所有的路由跳轉都是通過前端來控制,通過前端擷取url的改變擷取對應的路由進行頁面的重新渲染。
優點
1. 頁面跳轉是異步加載的,不需要重新重新整理頁面,是以浏覽器響應比較快一些
2. 頁面進行跳轉的時候還可以加一些動畫的效果
3. 單頁面路由改變的時候會存留曆史記錄,而且不會向背景發送請求
單頁面路由需要具備的條件
- 路由會發生改變
- 不會向背景請求資料
- 浏覽器存留曆史記錄
單頁面路由一般分為兩種模式
hash
hash利用的是url#的原理,就像咱們說的錨點連結,點選會觸發url的改變,而且會存留曆史記錄,但是不會向背景發起請求。可以通過hashChange事件監聽到路由的變化,擷取到路由改變的位址,通過位址查找到對應的元件,進行渲染。
history
history利用的是浏覽器新增的historyAPI中的pushState和replaceState方法做路由的改變并且存留曆史記錄,通過window.onpopstate監聽路由的改變,根據對應的路由取到對應的元件進行頁面的渲染
Bug
重新整理頁面的時候走的時候後端的路由,是以在後端進行一個配置,将前端所有的單頁面路由指向index.html路由,這樣就不會造成404的問題了。
vue元件中methods,watch,computed的差別
methods
主要用來做方法的定義 都是一個對象,調用一次就會執行一次,當依賴的值發生改變的時候會重新觸發一遍。方法需要調用
watch屬性監聽
不需要傳回值 監聽的是data裡面的資料(包括props,$route路由變化)裡面的資料,定義的屬性接受兩個參數,第一個參數是新值,第二個參數是舊值,沒有傳回值 隻要值發生變化 肯定會執行
computed 計算屬性
通過某些屬性的計算得到一個傳回值,計算屬性會對值進行緩存,隻有當依賴的值發生改變的時候才重新觸發一遍 主要用他代替了過濾器的功能,可以将一個值轉換為另一個值 必須有傳回值
應用場景
當我們要對某些屬性進行一些複雜邏輯的時候,直接作用在template模闆上會顯的很亂,這時候就要考慮使用計算屬性了。 計算屬性設定的時候是以key和value的方式進行設定的,value的類型可以分為兩種
- 預設為getter方法(function)
必須要有傳回值,相當于函數作用在了這個計算屬性的getter方法上
- 但是也可以設定setter(Object)
set方法沒有傳回值,設定set的時候隻需要寫this.comp='cmy'就會觸發
如何使用computed : {
add : function () {
return this.i*10
},
comp : {
get : function () {
return this.i+10
},
set : function (v) {
this.i =v;
}
}
}
計算屬性隻有當他們依賴的值發生改變的時候才會再次觸發,否則讀取的就是緩存裡面的值,如果不想有緩存的話可以通過在methods裡面定義方法,每一次調用都會重新觸發改變。
元件群組件之間的通訊
vue中元件群組件之間的通訊指的是一個元件和多個元件之間的資料傳遞
- 主要有幾個場景
-
子父通訊: 指的是父元件使用子元件的資料
有好多種方法可以實作,但最常用的是使用自定義事件,
- 自定義事件 在元件上面通過v-on去綁定一個事件,事件的值是一個回調函數,回調函數裡面接受參數,接受的參數是通過子元件傳遞過來的。通過子元件當中的$emit去觸發自定義事件的名稱,之後傳遞值,把屬性傳遞到父元件上,父元件就可以擷取到子元件的資料
- 擷取執行個體的方式 父元件裡面擷取子元件的執行個體有兩種方式
- 通過ref來擷取 在元件中通過this.$refs.屬性名就可以擷取到子元件執行個體
- 通過$child來擷取到目前元件裡面所有的子元件,但$child是一個數組,沒有辦法擷取到某一個指定的子元件,是以一般用ref來擷取子元件執行個體
-
最推薦使用的就是自定義事件
- 父子通訊: 指的是子元件使用父元件的資料
- props 常用的是props 屬性的形式傳遞給子元件資料,子元件
- 子元件裡面利用$parents擷取父元件執行個體
之後拿到父元件裡面的資料,但這裡面有一個約定俗成的規定,vue是單向資料流,預設是子元件不可以改變父元件的資料,盡量保持vue中單向資料流的概念,隻能在原元件中改變資料
- 同級 就是兩個同級之間的通訊 A元件使用B元件的資料。
- 代理 最明确的方式就是通過共同的父元件做一個代理,傳遞到另一個子元件中去,通過代理的形式,
- 自定義事件的形式 咱們可以寫一個空的vue執行個體,在vue中有$on,$emit可以做自定義事件的處理,在a元件中使用$on定義事件,在b元件中通過$emit去觸發,當然定義事件和觸發事件要綁定在同一執行個體上,也就是咱們常說的釋出訂閱模式 eventbush 跨級 可能abc元件是一個層級關系,如果層級少的話咱們可以逐層傳遞,但是層級傳遞過多的話就會太麻煩了,我們就可以使用自定義事件的形式,也就是使用eventbush
如果涉及到更加複雜的資料通訊,或者很多元件都使用到這個資料,咱們可以将元件中的資料綁定在元件的根執行個體上,然後在元件中通過$router去通路,也可以使用vuex,因為vuex是全局的資料存儲,在任何元件中都可以通路的到
$router和$route的差別
$router是路由執行個體
$route是目前頁面的路由資訊對象,包括路由的名稱,路由的path,路由的參數,params,hash
$router是路由的執行個體,有一些操作路由的方法,$route是$router的一個屬性的一個指針相當于,是$router.currentRoute
常用的執行個體屬性
this.$el vue執行個體使用的根元素
this.$root 目前元件樹的根執行個體,如果沒有根執行個體 指向自己
執行個體方法
this.$set
this.$watch
用來進行監聽,再調用一次是取消監聽
this.$delete 删除某個不被監測到的屬性
執行個體方法
this.$nextTick 當所有的元件更新完成之後延時調用 this.$nextTick().then(//dom更新後執行的動作)
常用指令
v-text 輸出文本 v-html 輸出标簽 v-show 切換display屬性 v-if 如果為真就渲染 是惰性的 如果初始化的時候條件為假就什麼都不做
如果和v-for一起使用的話,v-for擁有更高的優先級
v-else 前面必須有v-if或者v-else-if v-for 循環 v-on @監聽事件
修飾符
.stop - 調用 event.stopPropagation()。 阻止冒泡
.prevent - 調用 event.preventDefault()。阻止預設事件
.capture - 添加事件偵聽器時使用 capture 模式。事件捕獲
.self - 隻當事件是從偵聽器綁定的元素本身觸發時才觸發回調。
.native - 監聽元件根元素的原生事件。給元件添加事件的時候
.once - 隻觸發一次回調。
.left - (2.2.0) 隻當點選滑鼠左鍵時觸發。
.right - (2.2.0) 隻當點選滑鼠右鍵時觸發。
.middle - (2.2.0) 隻當點選滑鼠中鍵時觸發。
v-bind 動态監聽變化
修飾符
.sync 子父通訊的時候需要
v-model 受控元件 有三個修飾符 .lazy 取代input監聽change事件 .number 把字元串轉為數字 .trim 去除首尾空格 v-once 隻渲染元素群組件一次。随後的重新渲染,元素/元件及其所有的子節點将被視為靜态内容并跳過。這可以用于優化更新性能。
特殊特性
is 元件上的is屬性發生改變的時候,元件也會跟着改變
ref
用來給元素或者元件添加引用資訊,分為兩種情況
- 作用在元件上 擷取到的是這個元件執行個體
- 作用在dom元素上 擷取到的是對應的dom元素
vue中的資料監測原理
vue中的資料如果想實作響應式更新渲染視圖的話,必須将資料定義在data裡面才可以實作,因為vue會給data裡面定義的資料自動注入getter和setter方法,監聽他們的變化,随時更新視圖,利用的是ES5的Object.defineProperty方法來完成的 其中需要注意的是如果this.data中的資料沒有出現在模闆中,那麼資料的改變将不會觸發update生命周期,還有如果直接通過下标或者屬性來改變this.data裡面的資料的話通常會監聽不到變化,這時候可以利用深拷貝或者$set方式改變資料,觸發vue去監聽到資料的變化 訂閱釋出加 資料劫持
如果向子元件綁定自定義屬性 如果不被子元件props接受 就會成為這個元件的自定義屬性
說一下vuex吧
vuex是适合于vue的狀态管理工具,可以對vue中的狀态進行統一的管理,避免了元件通訊層級過多的問題,vuex主要分為
- state 裡面用來定義vue中的資料結構,在這裡設定資料的初始值
- mutations 這裡是唯一允許改變state的地方
- active 異步的操作需要放在這裡面,否則監聽不到變化
- getter 這裡面用來進行過濾,不修改原數組
優點:
- 對于資料的管理是有固定規則的
- 可以同步視圖進行更新
缺點:
- 對于狀态操作的時候,讀取對象層級過多
- 不能存儲大量的資料
vue中的路由如何傳遞參數
- paramse 動态路由(必傳)
- query參數傳遞(選傳) 傳遞方式有兩種
- router-link :to
- 通過vue執行個體的$router方法進行傳參
vue路由的鈎子函數
beforeEach 接受三個參數 to,from,next
afterEach 不能對路由做出改變
如何配置路由
new 一個vueRouter,之後裡面傳入配置參數,mode:'history/hash',routes:[{ path:'/',name:'dd',children:[],component:模闆,meta }] 如果想要一個路由渲染不同的頁面,可以将components設定為{default:comA,a:first,b:secend} <router-views name='a'/> 如果渲染default的話就什麼都不用寫
重定向
可以設定為字元串/bar ,也可以設定為name{name:'bar'},也可以設定為函數,傳回值為字元串和對象
路由别名
alias 可以為路由設定别名 字元串,當通路别名的時候通路的也是目前路由
###vue中設定反向代理是在config下的index.jsdev下的proxyTable中配置的
設定别名通路路徑 @ webpack中的reslove裡面的alias屬性可以用來配置路徑别名