深入解析vue元件與複用
元件 (Component) 是 Vue.js 最強大的功能之一。元件可以擴充套件 HTML 元素,封裝可重用的程式碼。這篇文章主要介紹了vue元件與複用,需要的朋友可以參考下

一、什麼是元件
元件 (Component) 是 Vue.js 最強大的功能之一。元件可以擴充套件 HTML 元素,封裝可重用的程式碼。
二、元件用法
元件需要註冊後才可以使用,註冊有全域性註冊和區域性註冊兩種方式。
2.1 全域性註冊後,任何V ue 例項都可以使用。如:
<div id="app1"> <my-component></my-component> </div> Vue.component('my-component',{ template: '<div>這裡是元件的內容</div>' }); var app1 = new Vue({ el: '#app1' });
要在父例項中使用這個元件,必須要在例項建立前註冊,之後就可以用<my-component></my- component> 的形式來使用元件了
template的DOM結構必須被一個元素包含, 如果直接寫成“這裡是元件的內容”, 不帶“<div></ div >”是無法渲染的。(而且最外層只能有一個根的<div>標籤)
2.2 在Vue 例項中,使用component選項可以區域性註冊元件,註冊後的元件只有在該例項作用域下有效。如:
<div id="app2"> <my-component1></my-component1> </div> var app2 = new Vue({ el: '#app2', components:{ 'my-component1': { template: '<div>這裡是區域性註冊元件的內容</div>' } } });
2.3 data必須是函式
除了template選項外,元件中還可以像Vue例項那樣使用其他的選項,比如data 、computed 、methods等。但是在使用data時,和例項稍有區別, data 必須是函式,然後將資料return 出去。
<div id="app3"> <my-component3></my-component3> </div> Vue.component('my-component3',{ template: '<div>{{message}}</div>', data: function(){ return { message: '元件內容' } } }); var app3 = new Vue({ el: '#app3' });
一般return的物件不要引用外部的物件,因為如果return 出的物件引用了外部的一個物件, 那這個物件就是共享的, 任何一方修改都會同步。
所以一般給元件返回一個新的獨立的data物件。
vue-router 元件複用問題
元件系統是Vue的一個重要組成部分,它可以將一個複雜的頁面抽象分解成許多小型、獨立、可複用的元件,通過組合元件來組成應用程式,結合vue-router的路由功能將各個元件對映到相應的路由上,通過路由的變化來告訴Vue要在哪裡渲染他們,實現各個元件、各個頁面之間的跳轉導航。
使用vue-router切換路由時會觸發元件樹的更新,根據定義的路由渲染一個新的元件樹,大致的切換過程是這樣的:
- 停用並移除不需要的元件
- 驗證切換的可行性
- 複用沒有進行更新的元件
- 啟用並激活新的元件
具體路由切換控制流程請參考官方文件:切換控制流水線
那vue-router是怎麼判斷某一個元件可以複用的呢? 我們看一下下面這條路由配置:
{ path: 'post/:postId', name: 'post', component: resolve => require(['./components/Post.vue'],resolve) }
看到的還是之前的文章,雖然路由引數已發生更改,但是vue-router會以為你訪問的是Post.vue這個元件,由於之前已經渲染過該元件,所以會直接複用之前的元件,並且不會執行元件中的任何操作包括mounted之類的生命週期函式。
所以我們最終看到的還是原來元件的內容。
解決方法
我們可以使用watch偵聽器來監聽路由的變化情況,根據路由引數的變化來響應相應的資料,具體實現過程是這樣的:
定義資料獲取方法
首先定義一個獲取文章的方法,根據文章ID從後臺獲取對應的文章資訊。
methods: { getPost(postId) { this.$http.get(`/post/get_post/${postId}`).then((response) => { if(response.data.code === 0){ this.post = response.data.post; }//歡迎加入全棧開發交流圈一起學習交流:864305860 });//面向1-3年前端人員 }//幫助突破技術瓶頸,提升思維能力 }
監聽路由
接著是在路由切換的時候判斷目標元件是否是Post.vue元件,這裡可以根據定義的路由名稱name實現,如果是,我們就可以從路由資訊中獲取目標文章ID來更新元件內容。
watch: { '$route' (to, from) { if(to.name === 'post'){ this.getPost(to.params.postId); }//歡迎加入全棧開發交流圈一起學習交流:864305860 }//面向1-3年前端人員 }//幫助突破技術瓶頸,提升思維能力
元件初始化
這裡需要注意的是,當元件首次被掛載到元件樹上時,對路由的監聽是無效的,這時我們需要在生命週期鉤子mounted對元件進行初始化工作:
mounted() { this.getPost(this.$route.params.postId); }
通過上面的方法就可以實現元件內容隨路由引數的變化而更新了,有效解決了vue-router元件複用導致路由引數失效的問題。
本次給大家推薦一個免費的學習群,裡面概括移動應用網站開發,css,html,webpack,vue node angular以及面試資源等。
對web開發技術感興趣的同學,歡迎加入Q群:864305860,不管你是小白還是大牛我都歡迎,還有大牛整理的一套高效率學習路線和教程與您免費分享,同時每天更新視訊資料。
最後,祝大家早日學有所成,拿到滿意offer,快速升職加薪,走上人生巔峰。