這是一系列文章,此係列全部的練習都存在了個人github倉庫中vue-webpack,在本人有了新的理解與認識以後,會對文章有不定時的更正與更新。下面是目前完成的列表:javascript
webpack入坑之旅(四)揚帆起航html5
在上面的練習當中咱們已經成功的加載了一個.vue
格式的單文件組件,而且實現了在使用vue狀況下的自動刷新。git
可是咱們最終的目的仍是要實現單頁面應用程序,這個時候咱們就必不可少的須要使用到路由管理器來進行SPA的開發,vue官方爲咱們提供了一個官方庫vue-router,而且配有對應的中文文檔。關於裏面的內容你們自行前去觀看。在這裏,只會把咱們須要的東西拿出來說。es6
官網對於組件講解github
在Vue
中定義一個組件很是簡單,只須要一對自定義標籤,在其中填入內容就能夠進行咱們的組件編寫了,而後使用Vue.component()
去註冊咱們的組件下面來看一個例子,來直觀的看看vue的組件。
<script src="js/vue.js"></script> <body> <div id="app"> <my-component></my-component> <!-- 自定義標籤做爲組件名稱 --> <my-component></my-component> <!-- 複用 --> </div> <script> // 定義而且註冊組件 // 在官方的示例中使用 Vue.extend({})先註冊了一個定義模板,再引用,看我的喜愛吧 Vue.component("my-component", { template:"<h2>hello Vue component</h2>" }) // 建立根實例 // 在這裏 定義而且註冊組件 必須建立根實例前,否則會報錯,由於解析順序的問題? new Vue({ el:"#app" }); </script> </body>
上面就是最簡單的定義組件的方式,template
屬性中寫的東西:就是<my-component>
這個自定義標籤渲染後展示出來的樣式,這裏渲染爲:
<div id="app"> <h2>hello Vue component</h2> <h2>hello Vue component</h2> </div>
在上面這段代碼中組件內的內容都被寫在template
屬性中,若是組件中的內容繼續增長,一堆的引號和加號來拼接這些字符串簡直就是噩夢。因此Vue 引入了template
標籤(html5定義的,瀏覽器默認不去解析裏面的內容)。<template> 不能用在 <table> 內
下面來看看它的使用方法:
<script src="js/vue.js"></script> <body> <!-- 使用 template 而且添加選擇器(只能使用id)--> <template id="myTemp"> <h2>This is Template </h2> <p>add ...</p> </template> <div id="app"> <my-component></my-component> <my-component></my-component> </div> <script> Vue.component("my-component", { template:"#myTemp"//對應上面定義的template標籤中的選擇器 }) new Vue({ el:"#app" }); </script> </body>
能夠看到在註冊組件中,能夠template
可使用選擇器來獲取到上面咱們<template>
標籤中的內容。因此這裏應該會被渲染爲:
<div id="app"> <h2>This is Template </h2> <p>add ...</p> <h2>This is Template </h2> <p>add ...</p> </div>
組件的基礎介紹就到這,更多詳細內容請移步官網
剛剛已經對於vue的組件有了必定的瞭解。如今來結合vue-router,來進行一下動態的切換。
首先是安裝,若是使用npm的形式的話,直接運行npm install vue-router --save
,就能夠看到vue-router
,已經被添加到了項目依賴中。直接上ES6
的語法來進行引入
import Vue from "vue"; import VueRouter from "vue-router"; Vue.use(VueRouter);
其實這一部分vue-router
的中文文檔中已經講的很是詳細了。。在這裏與它不一樣的是它用的CommonJS
的規範來進行模塊安裝,而我使用ES6的import,有興趣本身去看- -。其餘的內容我就直接扒下來了。
html:
<div id="app"> <h1>Hello App!</h1> <p> <!-- 使用指令 v-link 進行導航。 --> <a v-link="{ path: '/foo' }">Go to Foo</a> <a v-link="{ path: '/bar' }">Go to Bar</a> </p> <!-- 路由外鏈 --> <router-view></router-view> </div>
javascript:
// 定義組件 var Foo = Vue.extend({ template: '<p>This is foo!</p>' }) var Bar = Vue.extend({ template: '<p>This is bar!</p>' }) // 路由器須要一個根組件。 // 出於演示的目的,這裏使用一個空的組件,直接使用 HTML 做爲應用的模板 var App = Vue.extend({}) // 建立一個路由器實例 // 建立實例時能夠傳入配置參數進行定製,爲保持簡單,這裏使用默認配置 var router = new VueRouter() // 定義路由規則 // 每條路由規則應該映射到一個組件。這裏的「組件」能夠是一個使用 Vue.extend // 建立的組件構造函數,也能夠是一個組件選項對象。 // 稍後咱們會講解嵌套路由 router.map({ '/foo': { component: Foo }, '/bar': { component: Bar } }) // 如今咱們能夠啓動應用了! // 路由器會建立一個 App 實例,而且掛載到選擇符 #app 匹配的元素上。 router.start(App, '#app')
我我的感受這部分仍是很好理解的,官方也給了一個在線示例應用。很好的展示了它的路由切換。
簡單的介紹到這,下面最重要的部分到了,看看如何結合咱們定義的.vue
單文件組件。
首先來看咱們的文件目錄結構:
最主要是main.js
的變化,直接在文件中講解了:
// 引入vue以及vue-router import Vue from "vue"; import VueRouter from "vue-router"; Vue.use(VueRouter); // 引入組件!直接使用es6的語法 import index from './components/app.vue'; import list from './components/list.vue'; import hello from './components/hello.vue'; //開啓debug模式 Vue.config.debug = true; // new Vue(app);//這是上一篇用到的,新建一個vue實例,如今使用vue-router就不須要了。 // 路由器須要一個根組件。 var App = Vue.extend({}); // 建立一個路由器實例 var router = new VueRouter(); // 每條路由規則應該映射到一個組件。這裏的「組件」能夠是一個使用 Vue.extend建立的組件構造函數,也能夠是一個組件選項對象。 // 稍後咱們會講解嵌套路由 router.map({//定義路由映射 '/index':{//訪問地址 name:'index',//定義路由的名字。方便使用。 component:index,//引用的組件名稱,對應上面使用`import`導入的組件 //component:require("components/app.vue")//還能夠直接使用這樣的方式也是沒問題的。不過會沒有import集中引入那麼直觀 }, '/list': { name:'list', component: list }, }); router.redirect({//定義全局的重定向規則。全局的重定向會在匹配當前路徑以前執行。 '*':"/index"//重定向任意未匹配路徑到/index }); // 如今咱們能夠啓動應用了! // 路由器會建立一個 App 實例,而且掛載到選擇符 #app 匹配的元素上。 router.start(App, '#app');
在index.html須要有用於渲染匹配的組件,以下
<div id="app"> <router-view></router-view> </div>
如今當咱們運行 npm start
進入http://localhost:8080/
就會自動跳轉到http://localhost:8080/#!/index
,而且讀取裏面的內容。
主要抽出app.vue
中的內容來說解,的內容是:(list.vue
裏面的內容自行設置查看吧)
<template> <div> <h1>姓名:{{name}}</h1> <h2>{{age}}</h2> <button @click="golist">$route.router.go查看</button> <a v-link="{ name: 'list' }">v-link查看列表</a> <a v-link="{ name: 'index' }">回去主頁</a> </div> </template> <script> export default {//這裏是官方的寫法,默認導出,ES6 data () { //ES6,等同於data:function(){} return { //必須使用這樣的形式,才能建立出單一的做用域 name:"guowenfh", age:"21" } }, methods :{ golist () {//方法,定義路由跳轉,注意這裏必須使用this,否則報錯 this.$route.router.go({name:"list"}); } } } </script> <style></style> <!-- 樣式自行設置,或者直接看源碼就好 -->
由於自刷新的緣故,直接切換到瀏覽器。
點擊上面使用的v-link
,與router.go
的方式均可以跳轉到list
定義的路由。(觀察瀏覽器地址欄的變化)在這裏咱們使用的{name:"list"}
,使用{ path: '/list' }
會有一樣的效果。
在第一小點裏面咱們看到了在頁面內的組件的使用方法,第二小點中學習到了vue-router
的制定路由規則。
看過這兩個地方以後,咱們把思惟發散開來,應該就能舉一反三的想到如何在頁面中嵌套加載別的組件了。
咱們建立一個hello.vue
,裏面內容隨意。如今咱們若是要在app.vue
中加載它,那麼只須要在app.vue
中使用import hello from "./hello.vue"
(其實這個達到了使用require兩步的效果。引入賦值)。
引入以後,只須要以下注冊:
export default { //其它的就 components:{ hello//若還有更多的組件,只須要在import的狀況下,以逗號分割,繼續註冊就好 } }
最後在app.vue
中添加<hello></hello>
這一對自定義標籤,就能夠實現加載hello.vue
中的內容。
組件的嵌套也就是這樣,很簡單的描述完了,可是怎麼樣去抽離組件,在工做中積累能夠複用的組件纔是咱們真正須要去思考的。
那麼先到這,關於組件之間通訊的問題,留到之後慢慢了解。
仍是剛剛的代碼與目錄結構,咱們已經實現了組件之間的嵌套,可是有時並不但願組件直接就加載進來,而是在用戶點擊後才展示在頁面中,這是就須要使用到路由嵌套。
爲了偷懶,這裏就直接使用hello.vue
。實現嵌套路由主要有如下幾步:
第一步:制定嵌套路由規則:
看main.js
下面這部分的代碼:
router.map({ '/index':{ name:'index', component:index, // 在/index下設置一個子路由 subRoutes:{ // 當匹配到/index/hello時,會在index的<router-view>內渲染 '/hello':{ name:'hello',//無關緊要,主要是爲了方便使用 // 一個hello組件 component:hello } } }, });
第二步:在組件中添加<router-view>
來自官網的解釋:
<router-view>
用於渲染匹配的組件,它基於Vue的動態組件系統,因此它繼承了一個正常動態組件的不少特性。
將<router-view>
寫在app.vue
的<template></template>
標籤中。
第三步:寫入跳轉路徑
仍是在app.vue
中:
<a v-link="{ name: 'index' }">回去主頁</a> <!-- 點擊這兩個標籤就會實現頁面內的切換效果 --> <a v-link="{ name: 'hello' }">嵌套的路由</a>
,切換到瀏覽器,點擊該嵌套的路由
便可讓hello.vue
中的展示出來,在這裏直接使用了v-link
來實現跳轉(知道爲何要寫name了吧。。若是使用path會是這樣的{ path: '/index/hello' }
- -。 ) ,固然router.go
同理。(注意在點擊兩個不一樣的文字時,地址欄的變化,以及展示內容的切換)
注意:
在個人源碼中是在<style scoped></style>
標籤中定義樣式的,請注意scoped
的使用,它表示在該style
中定義的樣式只會在當前的組件中起到效果,而不會去影響全局的css樣式。
最簡單的理解應該就是:
未寫該scoped
屬性的全部組件中的樣式,在通過vue-loader
編譯以後擁有全局做用域。至關於共用一份css
樣式表。
而寫了該屬性的的組件中定義的樣式,擁有獨立做用域。至關於除去引入了公用的一份css
樣式表外,但單獨擁有一份css
的樣式表。
好了,先到這。講的有些凌亂,下次見