繼續1的學習,咱們知道使用:css
能夠把.vue文件的內容解析成組件對象的形式:vue
解析相似以下:webpack
咱們使用es6的語法,把render的回調處理參數使用這種處理:es6
import Vue from 'vue' import App from './App.vue' var app = new Vue({ render:h=>h(App) }).$mount("#app")
顯示正常:web
咱們已經學習瞭如何定義組件,組件一樣提供了嵌套功能,也就是組件能夠嵌套組件:vue-router
main.js定義一個組件,註冊:npm
import Vue from 'vue' import App from './App.vue' // 註冊 Vue.component('my-component', { template: '<div>A custom component!</div>' }) var app = new Vue({ render:h=>h(App) }).$mount("#app")
App.vue在組件中嵌套使用:json
<template> <div id="app"> helloworld <my-component></my-component> </div> </template> <script> export default { name: 'app' } </script>
顯示正常:babel
對於註冊組件的第一個參數,是組件名字,第二個參數也就是組件類型對象,咱們知道能夠解析.vue文件爲這樣的對象,咱們建立:app
myComponent.vue:
<template> <div>A custom component!</div> </template> <script> export default { name: 'myComponent' } </script>
main.js使用es6導入註冊:
import Vue from 'vue' import App from './App.vue' import myComponent from './myComponent.vue' Vue.component('my-component', myComponent) var app = new Vue({ render:h=>h(App) }).$mount("#app")
除了使用Vue.component註冊一個組件,還能夠局部註冊,註冊在vue新建的實例中:
咱們在註冊一個組件,是my-component組件的子組件:
weComponent.vue:
<template> <div> 我是myComponent的兒子 </div> </template> <script> export default { name: 'weComponent' } </script>
main.js註冊:
import Vue from 'vue' import App from './App.vue' import myComponent from './myComponent.vue' import weComponent from './weComponent.vue' Vue.component('my-component', myComponent) Vue.component('we-component', weComponent) var app = new Vue({ render:h=>h(App) }).$mount("#app")
myComponent.vue使用:
<template> <div> <div>我是myComponent組件</div> <we-component></we-component> </div> </template> <script> export default { name: 'myComponent' } </script>
vue組件的傳值方式就是使用屬性的方式,而後在子組件中用props屬性接收,不過在組件中data數據的設置必須使用函數的形式,在調用位置使用v-bind:xx綁定屬性便可:
myComponent.vue:
<template> <div> <div>我是myComponent組件</div> <we-component v-bind:val1="val1"></we-component> </div> </template> <script> export default { name: 'myComponent', data:function(){ return { val1:"我是小李子" } } } </script>
weComponent.vue子組件接收使用props:
<template> <div> 我是myComponent的兒子 <h3>{{val1}}</h3> </div> </template> <script> export default { name: 'weComponent', props:["val1"] } </script>
一樣的子組件接收到父組件的值,父組件中這個值變化時,子組件會自動更新到,咱們能夠給父組件加一個方法,修改這個傳入子組件的值,在vue中綁定事件使用的是v-on:xx(事件名字)=方法,方法要寫在methods屬性中,在組件內部,獲取data的值只須要this.xx便可!
myComponent.vue:
<template> <div> <div>我是myComponent組件</div> <we-component v-bind:val1="val1"></we-component> <button v-on:click="clickVal">點擊修改val1的值</button> </div> </template> <script> export default { name: 'myComponent', data:function(){ return { val1:"我是小李子" } }, methods:{ clickVal:function(){ this.val1=this.val1+"1" } } } </script>
點擊一次按鈕:
是上一種操做的逆處理,vue爲咱們提供了這樣的接口,在子組件的this會有一個$emit方法,他的參數就是綁定在調用這個組件位置上定義的事件:
weComponent.vue:
<template> <div> 我是myComponent的兒子 <h3>{{val1}}</h3> <button v-on:click="clickPar">告訴父組件值+2</button> </div> </template> <script> export default { name: 'weComponent', props:["val1"], methods:{ clickPar:function(){ this.$emit("parAdd2") } } } </script>
在父組件自定義這個事件,調用一個對應的方法+2:
myComponent.vue:
<template> <div> <div>我是myComponent組件</div> <we-component v-bind:val1="val1" v-on:parAdd2="clickVal2"></we-component> <button v-on:click="clickVal">點擊修改val1的值</button> </div> </template> <script> export default { name: 'myComponent', data:function(){ return { val1:"我是小李子" } }, methods:{ clickVal:function(){ this.val1=this.val1+"1" }, clickVal2:function(){ this.val1=this.val1+"2" } } } </script>
咱們這時候會定義多個組件,分別是:
myComponent.vue
youComponent.vue
loveComponent.vue
myComponent.vue:
<template> <div> {{info}} </div> </template> <script> export default { name: 'myComponent', data:function(){ return { info:"myComponent" } } } </script>
youComponent.vue:
<template> <div> {{info}} </div> </template> <script> export default { name: 'youComponent', data:function(){ return { info:"youComponent" } } } </script>
loveComponent.vue:
<template> <div> {{info}} </div> </template> <script> export default { name: 'loveComponent', data:function(){ return { info:"loveComponent" } } } </script>
main.js註冊:
import Vue from 'vue' import App from './App.vue' import myComponent from './myComponent.vue' import youComponent from './youComponent.vue' import loveComponent from './loveComponent.vue' Vue.component('my-component', myComponent) Vue.component('you-component', youComponent) Vue.component('love-component', loveComponent) var app = new Vue({ render:h=>h(App) }).$mount("#app")
App.vue應用:
<template> <div id="app"> <h3>tab切換顯示:</h3> <my-component></my-component> <you-component></you-component> <love-component></love-component> </div> </template> <script> export default { name: 'app' } </script>
對於顯示隱藏vue爲咱們提供了v-if和v-show指令,咱們在data設置對應的值,控制便可:
<template> <div id="app"> <h3>tab切換顯示:</h3> <my-component v-if="isshowmy"></my-component> <you-component v-if="isshowyou"></you-component> <love-component v-if="isshowlove"></love-component> </div> </template> <script> export default { name: 'app', data:function(){ return { isshowmy:true, isshowyou:false, isshowlove:false } } } </script>
既然是tab切換,只有內容是不對的,還得有對應的三個菜單,咱們寫好他們:
<template> <div id="app"> <h3>tab切換顯示:</h3> <ul> <li>my-component</li> <li>you-component</li> <li>love-component</li> </ul> <div> <my-component v-if="isshowmy"></my-component> <you-component v-if="isshowyou"></you-component> <love-component v-if="isshowlove"></love-component> </div> </div> </template> <script> export default { name: 'app', data:function(){ return { isshowmy:true, isshowyou:false, isshowlove:false } } } </script>
咱們要給li加入事件,控制對應顯示,咱們最簡單就是把data的key作參數傳遞給定義的方法,修改成true,其餘是false:
<template> <div id="app"> <h3>tab切換顯示:</h3> <ul> <li v-on:click="tab('isshowmy')">my-component</li> <li v-on:click="tab('isshowyou')">you-component</li> <li v-on:click="tab('isshowlove')">love-component</li> </ul> <div> <my-component v-if="isshowmy"></my-component> <you-component v-if="isshowyou"></you-component> <love-component v-if="isshowlove"></love-component> </div> </div> </template> <script> export default { name: 'app', data:function(){ return { isshowmy:true, isshowyou:false, isshowlove:false } }, methods:{ tab:function(key){ this.isshowmy=false; this.isshowyou=false; this.isshowlove=false; this[key]=true; } } } </script>
其實咱們還有一個小操做,就是但願地址也對應變化,咱們獲取key以後,操做window.location.href=#/xx便可!
看地址變化:
咱們仍是基於上面的例子,咱們此次點擊li只是修改地址而已:
咱們知道vue提供了一個watch屬性,能夠監聽某個屬性變化,而後作出處理,咱們能夠把地址放在data的一個屬性中,監聽他是否修改,而後在修改顯示元素對應的布爾值:
<template> <div id="app"> <h3>tab切換顯示:</h3> <ul> <li v-on:click="tab('isshowmy')">my-component</li> <li v-on:click="tab('isshowyou')">you-component</li> <li v-on:click="tab('isshowlove')">love-component</li> </ul> <div> <my-component v-if="isshowmy"></my-component> <you-component v-if="isshowyou"></you-component> <love-component v-if="isshowlove"></love-component> </div> </div> </template> <script> export default { name: 'app', data:function(){ return { url:"", isshowmy:true, isshowyou:false, isshowlove:false } }, watch:{ url:function(newurl){ this.isshowmy=false; this.isshowyou=false; this.isshowlove=false; this[newurl]=true; } }, methods:{ tab:function(key){ window.location.href="#/"+key; this.url=key; } } } </script>
這時候咱們的流程就是點擊修改了地址,而後根據地址在去控制對應結構的顯示。
在咱們單頁開發中,路由是很是重要的,就像上面的例子,咱們若是有不少控制顯示隱藏的處理,是很是麻煩的,
修改地址,而後顯示對應的結構,就變得清晰明瞭。
vue-router能夠幫助咱們很是出色的解決問題,仍是如上例子的處理,咱們使用vue-router完成咱們的實現,
用vue-router就要有這個依賴,咱們安裝vue-router有兩種方式:
package.json配置好,
{ "name": "stydy-vue", "description": "study-vue", "version": "1.0.0", "author": "tbd", "private": true, "scripts": { "dev": "cross-env NODE_ENV=development webpack-dev-server --open --hot", "build": "cross-env NODE_ENV=production webpack --progress --hide-modules" }, "dependencies": { "vue": "^2.4.4" }, "devDependencies": { "babel-core": "^6.26.0", "babel-loader": "^7.1.2", "babel-preset-env": "^1.6.0", "cross-env": "^5.0.5", "css-loader": "^0.28.7", "file-loader": "^1.1.4", "vue-loader": "^13.0.5", "vue-template-compiler": "^2.4.4", "webpack": "^3.6.0", "webpack-dev-server": "^2.9.1", "vue-router": "^*" } }
而後執行:
npm install
npm手動安裝
npm install vue-router
等待完成便可!
如何終止啓動的項目:ctrl+c
路由的引入很是簡單:
而後就是簡單的配置:
import Vue from 'vue' import App from './App.vue' import VueRouter from 'vue-router' import myComponent from './myComponent.vue' import youComponent from './youComponent.vue' import loveComponent from './loveComponent.vue' //路由配置 Vue.use(VueRouter); var routes = [ { path: '/', component: myComponent}, { path: '/youComponent', component: youComponent}, { path: '/loveComponent', component: loveComponent} ] var router = new VueRouter({ routes: routes // (縮寫)至關於 routes: routes }) var app = new Vue({ render:h=>h(App) }).$mount("#app")
這時候在對應的地址下,配置了使用的對應組件,而後使用VueRouter幫助生成這個實例,而後應用到vue實例中:
import Vue from 'vue' import App from './App.vue' import VueRouter from 'vue-router' import myComponent from './myComponent.vue' import youComponent from './youComponent.vue' import loveComponent from './loveComponent.vue' //路由配置 Vue.use(VueRouter); var routes = [ { path: '/', component: myComponent}, { path: '/youComponent', component: youComponent}, { path: '/loveComponent', component: loveComponent} ] var router = new VueRouter({ routes: routes // (縮寫)至關於 routes: routes }) var app = new Vue({ router, render:h=>h(App) }).$mount("#app")
路由爲咱們提供了它寫好的組件,咱們只要直接使用便可!
<router-link to="/isshowmy">my-component</router-link>
最終會被解析成a標籤,href就是to的設置,地址點擊以後就會變爲#/isshowmy的形式
<router-view></router-view>
會根據的路由配置,匹配好,而後顯示對應組件。
App.js:
<template> <div id="app"> <h3>tab切換顯示:</h3> <ul> <li><router-link to="/">my-component</router-link></li> <li><router-link to="/youComponent">you-component</router-link></li> <li><router-link to="/loveComponent">love-component</router-link></li> </ul> <div> <router-view></router-view> </div> </div> </template> <script> export default { name: 'app' } </script>
咱們修改咱們的myComponent.vue,加入一個列表,而後跳到詳情頁面,一會咱們在建立詳情頁的組件和配置對應路由:
myComponent.vue咱們使用vue提供的v-for指令作循環處理:
<template> <div> {{info}} <ul> <li v-for="(item, index) in list"><a v-bind:href="'#/myDetail?id='+item.id">{{item.title}}</a></li> </ul> </div> </template> <script> export default { name: 'myComponent', data:function(){ return { info:"myComponent", list:[ {id:1,title:"c1111111"}, {id:2,title:"c2222222222"}, {id:3,title:"c33333333"}, {id:4,title:"c4444444"}, {id:5,title:"c55555555"} ] } } } </script>
建立myDetail.vue:
<template> <div> 我是詳情頁面 </div> </template> <script> export default { name: 'myDetail' } </script>
main.js加入路由配置:
import Vue from 'vue' import App from './App.vue' import VueRouter from 'vue-router' import myComponent from './myComponent.vue' import youComponent from './youComponent.vue' import loveComponent from './loveComponent.vue' import myDetail from './myDetail.vue' //路由配置 Vue.use(VueRouter); var routes = [ { path: '/', component: myComponent}, { path: '/youComponent', component: youComponent}, { path: '/loveComponent', component: loveComponent}, { path: '/myDetail', component: myDetail} ] var router = new VueRouter({ routes: routes // (縮寫)至關於 routes: routes }) var app = new Vue({ router, render:h=>h(App) }).$mount("#app")
咱們看那一下效果:
點擊列表進入詳情頁面:
咱們在new vue實例的時候使用了路由對象,
那麼在任何組件中咱們的this都會有一個$route屬性,裏面會包含全部路由相關的信息和方法處理,
咱們在詳情組件的生命週期函數中打印出這個屬性的內容:
myDetail.vue,對於生命週期函數,就是組件渲染的階段:
<template> <div> 我是詳情頁面 </div> </template> <script> export default { name: 'myDetail', created: function () { console.log(this.$route) } } </script>
看到打印入下:
在如見中顯示這個id很是簡單,在組件內獲取的話就是this.$route. query .id便可!
<template> <div> 我是詳情頁面id{{this.$route.query.id}} </div> </template> <script> export default { name: 'myDetail', created: function () { console.log(this.$route) } } </script>
這種處理,咱們要在路由配置進行處理:
import Vue from 'vue' import App from './App.vue' import VueRouter from 'vue-router' import myComponent from './myComponent.vue' import youComponent from './youComponent.vue' import loveComponent from './loveComponent.vue' import myDetail from './myDetail.vue' //路由配置 Vue.use(VueRouter); var routes = [ { path: '/', component: myComponent}, { path: '/youComponent', component: youComponent}, { path: '/loveComponent', component: loveComponent}, { path: '/myDetail/:id', component: myDetail} ] var router = new VueRouter({ routes: routes // (縮寫)至關於 routes: routes }) var app = new Vue({ router, render:h=>h(App) }).$mount("#app")
在傳遞位置,咱們就能夠用地址的形式了:
myComponent.vue:
<template> <div> {{info}} <ul> <li v-for="(item, index) in list"><a v-bind:href="'#/myDetail/'+item.id">{{item.title}}</a></li> </ul> </div> </template> <script> export default { name: 'myComponent', data:function(){ return { info:"myComponent", list:[ {id:1,title:"c1111111"}, {id:2,title:"c2222222222"}, {id:3,title:"c33333333"}, {id:4,title:"c4444444"}, {id:5,title:"c55555555"} ] } } } </script>
在接收端,咱們看console的結果:
咱們只須要把query改爲params便可!
myDetail.vue:
<template> <div> 我是詳情頁面id{{this.$route.params.id}} </div> </template> <script> export default { name: 'myDetail', created: function () { console.log(this.$route) } } </script>
咱們的
會被解析成a,不過有的時候咱們須要在一個事件裏面去跳轉,好比登陸操做:
youComponent.vue:
<template> <div> {{info}} <button v-on:click="skip">登陸</button> </div> </template> <script> export default { name: 'youComponent', data:function(){ return { info:"youComponent" } }, methods:{ skip:function(){ this.$router.push("loveComponent") } } } </script>
路由除了提供$route以外,還提供了$router,這裏面有對應的跳轉方法,咱們調用便可!
這個其實也是很是經常使用的,一個簡單的例子,關於咱們頁面,這個關於咱們地址是:
#/about
他的下面還有三個頁面:
聯繫方式#/about/phone
信息#/about/info
地址#/about/address
這樣就出現了嵌套關係,在關於咱們有一部份內容是公用的,一樣點擊對於的a會顯示不一樣的內容,當時你是用tab切換也能夠。
嵌套路由的配置和路由配置同樣,不過是多一級的設置:
main.js:
import Vue from 'vue' import App from './App.vue' import VueRouter from 'vue-router' import myComponent from './myComponent.vue' import youComponent from './youComponent.vue' import loveComponent from './loveComponent.vue' import myDetail from './myDetail.vue' import lovePhone from './lovePhone.vue' import loveInfo from './loveInfo.vue' import loveAddress from './loveAddress.vue' //路由配置 Vue.use(VueRouter); var routes = [ { path: '/', component: myComponent}, { path: '/youComponent', component: youComponent}, { path: '/loveComponent', component: loveComponent, children: [ { path: 'lovePhone', component: lovePhone }, { path: 'loveInfo', component: loveInfo }, { path: 'loveAddress', component: loveAddress } ] }, { path: '/myDetail/:id', component: myDetail} ] var router = new VueRouter({ routes: routes // (縮寫)至關於 routes: routes }) var app = new Vue({ router, render:h=>h(App) }).$mount("#app")
loveComponent.vue使用嵌套處理,router-link不用多說,重要的是這裏面的<router-view></router-view>,根據配置關係,看到這個二級地址以後會找到他一級的結構,而後找到router-view去渲染:
<template> <div> {{info}} <ul> <li><router-link to="/loveComponent/lovePhone">lovePhone</router-link></li> <li><router-link to="/loveComponent/loveInfo">loveInfo</router-link></li> <li><router-link to="/loveComponent/loveAddress">loveAddress</router-link></li> </ul> <div> <router-view></router-view> </div> </div> </template> <script> export default { name: 'loveComponent', data:function(){ return { info:"loveComponent" } } } </script>
咱們一次建立這三個組件,
lovePhone.vue:
<template> <div> {{info}} </div> </template> <script> export default { name: 'lovePhone', data:function(){ return { info:"lovePhone" } } } </script>
loveInfo:
<template> <div> {{info}} </div> </template> <script> export default { name: 'loveInfo', data:function(){ return { info:"loveInfo" } } } </script>
loveAddress:
<template> <div> {{info}} </div> </template> <script> export default { name: 'loveAddress', data:function(){ return { info:"loveAddress" } } } </script>
咱們進入是沒有內容的,其實咱們打算顯示出:
咱們在路由配置能夠加入重定向處理:
main.js:
import Vue from 'vue' import App from './App.vue' import VueRouter from 'vue-router' import myComponent from './myComponent.vue' import youComponent from './youComponent.vue' import loveComponent from './loveComponent.vue' import myDetail from './myDetail.vue' import lovePhone from './lovePhone.vue' import loveInfo from './loveInfo.vue' import loveAddress from './loveAddress.vue' //路由配置 Vue.use(VueRouter); var routes = [ { path: '/', component: myComponent}, { path: '/youComponent', component: youComponent}, { path: '/loveComponent', component: loveComponent, redirect: '/loveComponent/lovePhone', children: [ { path: 'lovePhone', component: lovePhone }, { path: 'loveInfo', component: loveInfo }, { path: 'loveAddress', component: loveAddress } ] }, { path: '/myDetail/:id', component: myDetail} ] var router = new VueRouter({ routes: routes // (縮寫)至關於 routes: routes }) var app = new Vue({ router, render:h=>h(App) }).$mount("#app")
咱們也許有這樣的需求,好比用戶的帳戶長時間未操做過時了,咱們在進入目的頁面會給用戶返回到登陸頁面,路由爲咱們提供了這樣的全局的路由變化監聽函數:
main.js:
import Vue from 'vue' import App from './App.vue' import VueRouter from 'vue-router' import myComponent from './myComponent.vue' import youComponent from './youComponent.vue' import loveComponent from './loveComponent.vue' import myDetail from './myDetail.vue' import lovePhone from './lovePhone.vue' import loveInfo from './loveInfo.vue' import loveAddress from './loveAddress.vue' //路由配置 Vue.use(VueRouter); var routes = [ { path: '/', component: myComponent}, { path: '/youComponent', component: youComponent}, { path: '/loveComponent', component: loveComponent, redirect: '/loveComponent/lovePhone', children: [ { path: 'lovePhone', component: lovePhone }, { path: 'loveInfo', component: loveInfo }, { path: 'loveAddress', component: loveAddress } ] }, { path: '/myDetail/:id', component: myDetail} ] var router = new VueRouter({ routes: routes // (縮寫)至關於 routes: routes }) router.beforeEach(function (to, from, next){ console.log(to,"即將要進入的目標 路由對象"); console.log(from,"當前導航正要離開的路由"); next(); }) var app = new Vue({ router, render:h=>h(App) }).$mount("#app")
在這個函數裏咱們必須執行一次next函數,不設置參數就是成功跳轉到目的頁面,也能夠設置參數,這個參數就是要跳轉的新位置。