Vue.js提供了插件機制,可以在全局添加一些功能。它們可以簡單到幾個方法、屬性,也可以很複雜,比如一整套元件庫。
注冊插件需要一個公開的方法install,它的第一個參數是Vue構造器,第二個參數是一個可選的對象。例如:
MyPlugin.install = function (Vue, options) {
//全局注冊元件(指令等功能資源類似)
Vue.component('component-name',{
//元件内容
})
//添加執行個體方法
Vue.prototype.$Notice = function () {
//邏輯...
}
//添加全局方法或屬性
Vue.globalMethod = function () {
//邏輯...
}
//添加全局混合
Vue.minin({
mounted:function () {
//邏輯...
}
})
}
通過Vue.use()來使用插件:
Vue.use(MyPlugin)
//或
Vue.use(MyPlugin,{
//參數
})
1.1 前端路由與vue-router
1.1.1 什麼是前端路由
webpack的主要使用場景是單頁面富應用(SPA),而SPA的核心就是前端路由。那什麼是路由呢?通俗地講,就是網址。再專業一點,就是每次GET或者POST等請求在服務端有一個專門的正則配置清單,然後比對到具體的一條路徑後,分發到不同的Controller,進行各種操作,最終将html或資料傳回給前端,這就完成了一次IO。
目前絕大多數的網站都是這種後端路由,也就是多頁面的,這樣的好處有很多,比如頁面可以在服務端渲染好直接傳回給伺服器,不用等待前端加載任何js和css就可以直接顯示網頁内容,再比如對SEO的友好等。後端路由的缺點也是很明顯的,就是模闆是由後端來維護或改寫的。前端開發者需要安裝整套的後端服務,必要時還得學習像PHP或Java這些非前端語言來改寫html結構,是以html和資料、邏輯混為一談,維護起來既臃腫有麻煩。
然後就有了前後端分離的開發模式,後端隻提供API來傳回資料,前端通過Ajax擷取資料後,再用一定的方式渲染到頁面裡,這麼做的優點就是前後端的事情分得很清楚,後端專注在資料上,前端專注在互動和可視化上,如果今後再開發移動APP,那就正好能使用一套API。當然,缺點也很明顯,就是首屏渲染需要時間來加載css和js。這種開發模式被很多公司認同,也出現了很多前端技術棧。在Node.js出現後,這種現象有了改善,就是所謂的大前端,得益于Node.js和JavaScript的語言特性,html模闆可以完全由前端來控制,同步或異步渲染完全由前端自由決定,并且由前端維護一套模闆,這就是為什麼在服務端使用artTemplate、React以及Vue2的原因。什麼是SPA呢?其實就是在前後端分離的基礎上,加一層前端路由。
前端路由,即由前端來維護一個路由規則。實作有兩種,一種是利用url的hash,就是常說的毛點(#),JavaScript通過hashChange事件來監聽url的改變,IE7及以下需要使用輪詢;另一種就是好HTML5的History模式,它使url看起來像普通網站那樣,以“/”分割,沒有#,但頁面并沒有跳轉,不過使用這種模式需要服務端支援,服務端接收到所有的請求後,都指向同一個html文,不然會出現404。是以,SPA隻有一個html,整個網站所有的内容都在這一個html裡,通過JavaScript來處理。
前端路由的優點有很多,比如頁面的持久性,像大部分音樂網站,你都可以在播放歌曲的同時跳轉到别的頁面,而音樂沒有中斷。再比如前後端的徹底分離。前端路由的架構通用的有Director,不過更多的還是結合具體架構來用,比如Angular的ngRouter,React的ReactRouter,以及Vue的vue-router。
如果要獨立開發一個前端路由,需要考慮到頁面的可插拔、頁面的生命周期、記憶體管理等問題。
1.1.2 vue-router基本用法
路由不同的頁面事實上就是動态加載不同的元件。
建立一個目錄router,再通過NPM安裝vue-router:
npm install --save vue-router
在main.js裡使用Vue.ues()加載插件:
import Vue from 'vue';
import VueRouter from 'vue-router';
import App from './app.vue';
Vue.use(VueRouter);
每個頁面對應一個元件,也就是對應一個.vue檔案。在router目錄下建立views目錄,用于存放所有的頁面,然後在views裡建立index.vue和about.vue兩個檔案:
//index.vue
<template>
<div>首頁</div>
</template>
<script>
export default {
}
</script>
//about.vue
<template>
<div>介紹頁</div>
</template>
<script>
export default {
}
</script>
再在main.js裡完成路由剩餘配置。建立一個數組來制定路由比對清單,每一個路由映射一個元件:
const Routers = [
{
path: '/index',
component: (resolve) => require(['./views/index.vue'], resolve)
},
{
path: '/about',
component: (resolve) => require(['./views/about.vue'], resolve)
}
];
Router裡每一項的path屬性就是指定目前比對的路徑,component是映射的元件。上例的寫法,webpack會把每一個路由都打包為一個js檔案,在請求到該頁面時,才去加載這個頁面的js,也就是異步實作的懶加載(按需加載)。這樣做的好處是不需要在打開首頁的時候就把所有的頁面内容全部加載進來,隻在通路時才加載。
使用了異步路由後,編譯出的每個頁面的js都叫做chunk(塊),它們的命名預設是0.main.js、1.main.js......可以在webpack配置的出口output裡通過設定chunkFilename字段修改chunk命名,例如:
output: {
publicPath: '/dist/',
filename: '[name].js',
chunkFilename: '[name].chunk.js'
}
有了chunk後,在每個頁面(.vue)檔案裡寫的樣式也需要配置後才會打包進main.css,否則仍然會通過JavaScript動态建立<style>标簽的形式寫入。
1.1.3 跳轉
vue-router有兩種跳轉頁面的辦法,第一種是使用内置的<router-link>元件,它會被渲染為一個<a>标簽:
//index.vue
<template>
<div>
<h1>首頁</h1>
<router-link to="/about">跳轉到about</router-link>
</div>
</template>
它的用法與一般的元件一樣,to是一個prop,指定需要跳轉的路徑,當然也可以用v-bind動态設定。使用<router-link>,在HTML5的History模式下會攔截點選,避免浏覽器重新加載頁面。
<router-link>還有其他的一些prop,常有的有:
· tag 可以指定渲染成什麼标簽,比如<router-link to="/about" tag="li">渲染的結果就是<li>而不是<a>
· replace 使用replace不會留下History記錄,是以導航後不能用後退鍵傳回上一個頁面,如<router-link to="/about" replace>
· active-class 當<router-link>對應的路由比對成功時,會自動給目前元素設定一個命名為router-link-active的class,設定prop: active-class可以修改預設的名稱。在做類似導航欄時,可以使用該功能高亮顯示目前頁面對應的導航菜單項,但是一般不會修改active-class,直接使用預設值router-link-active就可以。
有時候,跳轉頁面可能需要在JavaScript裡進行類似于window.location.href。這時可以用第二種跳轉方法,使用router執行個體的方法。比如在about.vue裡,通過點選事件跳轉:
//about.vue
<template>
<div>
<h1>介紹頁</h1>
<button @click="handleRouter">跳轉到user</button>
</div>
</template>
<script>
export default {
methods: {
handleRouter(){
this.$router.push('/user/123');
}
}
}
</script>
$router還有其他一些方法:
· replace 類似于<router-link>的replace功能,它不會向history添加新紀錄,而是替換掉目前的history記錄,如this.$router.replace('/user/123')。
· go 類似于window.history,go(),在history記錄中向前或者後退多少步,參數是整數。