上次咱們學習了Vue.js的基礎,而且經過綜合的小實例進一步的熟悉了Vue.js的基礎應用。今天咱們就繼續講講Vue.js的組件,更加深刻的瞭解Vue,js的使用。首先咱們先了解一下什麼是Vue.js的組件,組件其實就是頁面組成的一部分,它是一個具備獨立的邏輯和功能或頁面,組件能夠擴展 HTML 元素,封裝可重用的代碼。組件系統讓咱們能夠用獨立可複用的小組件來構建大型應用,幾乎任意類型的應用的界面均可以抽象爲一個組件樹,以下圖:javascript
接下來咱們就仔細講講組件的使用吧。html
1 全局組件 |
如下就是咱們註冊的第一個簡單的全局組件my-Com。全部實例都能用全局組件,組件在註冊以後,即可以做爲自定義元素 <my-Com></my-Com> 在一個實例的模板中使用。可是要注意全局組件必須寫在vue實例以前,纔會在跟元素 下面生效,模板裏面第一級只能有一個標籤,不能並行。前端
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title></title> 6 </head> 7 <body> 8 <div id="app"> 9 <my-Com></my-Com> 10 </div> 11 </body> 12 <script type="text/javascript" src="js/vue.js" ></script> 13 <script type="text/javascript"> 14 // 註冊 15 Vue.component('myCom', { 16 template: '<h1>自定義組件!</h1>' 17 }) 18 // 建立根實例 19 new Vue({ 20 el: '#app' 21 }) 22 </script> 23 </html>
2 局部組件 |
如下就是咱們註冊的第一個簡單的局部組件。其實能夠沒必要把每一個組件都註冊到全局的,局部組件能夠直接在vue實例裏,使用components註冊,這種封裝也適用於其它可註冊的 Vue 功能,好比指令。咱們建議將模板定義在全局變量。vue
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title></title> 6 </head> 7 <body> 8 <div id="app"> 9 <mycom></mycom> 10 </div> 11 </body> 12 <script type="text/javascript" src="js/vue.js" ></script> 13 <script type="text/javascript"> 14 var Child = { 15 template: '<h1>自定義組件!</h1>' 16 } 17 18 // 建立根實例 19 new Vue({ 20 el: '#app', 21 components: { 22 // mycom 將只在父模板可用 23 'mycom': Child 24 } 25 }) 26 </script> 27 </html>
3 使用Prop傳遞數據 |
組件設計初衷就是要配合使用的,最多見的就是造成父子組件的關係:組件 A 在它的模板中使用了組件 B。在 Vue 中,父子組件的關係能夠總結爲 prop 向下傳遞,事件向上傳遞。父組件經過 prop 給子組件下發數據,子組件經過事件給父組件發送消息。組件實例的做用域是孤立的。這意味着不能夠 在子組件的模板內直接引用父組件的數據。prop 是父組件用來傳遞數據的一個自定義屬性。父組件的數據須要經過 props 把數據傳給子組件,子組件須要顯式地用 props 選項聲明 "prop"。java
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title></title> 6 </head> 7 <body> 8 <div id="app"> 9 <com message="hello!"></com> 10 </div> 11 </body> 12 <script type="text/javascript" src="js/vue.js" ></script> 13 <script type="text/javascript"> 14 // 註冊 15 Vue.component('com', { 16 // 聲明 props 17 props: ['message'], 18 template: '<span>{{ message }}</span>' 19 }) 20 // 建立根實例 21 new Vue({ 22 el: '#app' 23 }) 24 </script> 25 </html>
4 動態Prop |
動態Prop 相似於用 v-bind 綁定 HTML 特性到一個表達式,也能夠用 v-bind 動態綁定 props 的值到父組件的數據中。每當父組件的數據變化時,該變化也會傳導給子組件。vue-router
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title></title> 6 </head> 7 <body> 8 <div id="app"> 9 <div> 10 <input v-model="parent"> 11 <br> 12 <child v-bind:message="parent"></child> 13 </div> 14 </div> 15 </body> 16 <script type="text/javascript" src="js/vue.js" ></script> 17 <script type="text/javascript"> 18 // 註冊 19 Vue.component('child', { 20 // 聲明 props 21 props: ['message'], 22 template: '<span>{{ message }}</span>' 23 }) 24 // 建立根實例 25 new Vue({ 26 el: '#app', 27 data: { 28 parent: '父組件內容' 29 } 30 }) 31 </script> 32 </html>
固然咱們也能可使用 v-bind
的縮寫語法:app
1 <child :my-message="parentMsg"></child>
如下實例中將 v-bind 指令將com傳到每個重複的組件中。框架
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title></title> 6 </head> 7 <body> 8 <div id="app"> 9 <ol> 10 <item v-for="item in sites" v-bind:com="item"></item> 11 </ol> 12 </div> 13 </body> 14 <script type="text/javascript" src="js/vue.js" ></script> 15 <script type="text/javascript"> 16 Vue.component('item', { 17 props: ['com'], 18 template: '<li>{{ com.text }}</li>' 19 }) 20 new Vue({ 21 el: '#app', 22 data: { 23 sites: [ 24 { text: 'Vue.js' }, 25 { text: 'BootStrap' }, 26 { text: 'JQuery' } 27 ] 28 } 29 }) 30 </script> 31 </html>
注意: prop 是單向綁定的:當父組件的屬性變化時,將傳導給子組件,可是不會反過來。這是爲了防止子組件無心間修改了父組件的狀態,來避免應用的數據流變得難以理解。可是,每次父組件更新時,子組件的全部 prop 都會更新爲最新值。這意味着不能夠在子組件內部改變 prop。若是這麼作了的話,Vue 會在控制檯出現警告。學習
5 使用 v-on 綁定自定義事件 |
父組件是使用 props 傳遞數據給子組件,但若是子組件要把數據傳遞回去,就須要使用自定義事件,父組件能夠在使用子組件的地方直接用 v-on 來監聽子組件觸發的事件。this
咱們可使用 v-on 綁定自定義事件, 每一個 Vue 實例都實現了事件接口,即:
$on(eventName)
監聽事件$emit(eventName)
觸發事件1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title></title> 6 </head> 7 <body> 8 <div id="app"> 9 <div id="example"> 10 <p>{{ num }}</p> 11 <button-counter v-on:vue="com"></button-counter> 12 </div> 13 </div> 14 </body> 15 <script type="text/javascript" src="js/vue.js" ></script> 16 <script type="text/javascript"> 17 Vue.component('button-counter', { 18 template: '<button v-on:click="vue">{{ counter }}</button>', 19 data: function () { 20 return { 21 counter: 0 22 } 23 }, 24 methods: { 25 vue: function () { 26 this.counter += 1 27 this.$emit('vue') 28 } 29 }, 30 }) 31 new Vue({ 32 el: '#example', 33 data: { 34 num: 0 35 }, 36 methods: { 37 com: function () { 38 this.num += 1 39 } 40 } 41 }) 42 </script> 43 </html>
6 給組件綁定原生事件 |
若是想在某個組件的根元素上監聽一個原生事件。可使用 v-on
的修飾符 .native
。
1 <comv-on:click.native="something"></com>
7 自定義指令 |
默認狀況下,一個組件的 v-model
會使用 value
prop 和 input
事件。Vue 也容許註冊自定義指令。
如下例子就是咱們註冊的一個全局指令 v-focus, 該指令的功能就是在頁面加載時,元素會自動得到焦點。
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title></title> 6 </head> 7 <body> 8 <div id="app"> 9 <p>頁面載入時,input 元素會自動獲取焦點:</p> 10 <input v-focus> 11 </div> 12 </body> 13 <script type="text/javascript" src="js/vue.js" ></script> 14 <script type="text/javascript"> 15 Vue.directive('focus', { 16 inserted: function (el) { 17 // 聚焦元素 18 el.focus() 19 } 20 }) 21 // 建立根實例 22 new Vue({ 23 el: '#app' 24 }) 25 </script> 26 </html>
8 Vue 路由實例應用 |
Vue框架的兼容性很是好,能夠很好的跟其餘第三方的路由框架進行結合。Vue官方給出了路由的方案 --- vue-router。下面咱們就使用Vue的路由實現簡單的單頁應用。
1 <script type="text/javascript" src="js/vue.js" ></script> 2 <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
使用 router-link 組件來導航.,經過傳入 `to` 屬性指定連接,<router-link> 默認會被渲染成一個 `<a>` 標籤。
1 <router-link to="/Vue">路由</router-link> 2 <router-link to="/BootStrap">柵格</router-link>
定義(路由)組件,能夠從其餘文件 import 進來。
1 const Foo = { 2 template: '<div>Vue</div>' 3 } 4 const Bar = { 5 template: '<div>BootStrap</div>' 6 }
定義路由,每一個路由應該映射一個組件。 其中"component" 能夠是經過 Vue.extend() 建立的組件構造器,或者只是一個組件配置對象。
1 const routes = [{ 2 path: '/Vue', 3 component: Foo 4 }, 5 { 6 path: '/BootStrap', 7 component: Bar 8 } 9 ]
1 const router = new VueRouter({ 2 routes 3 })
要經過 router 配置參數注入路由,從而讓整個應用都有路由功能。
1 const app = new Vue({ 2 router 3 }).$mount('#app')
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title></title> 6 </head> 7 <body> 8 <div id="app"> 9 <h1>Vue 路由實例</h1> 10 11 <p> 12 <router-link to="/Vue">路由</router-link> 13 <router-link to="/BootStrap">柵格</router-link> 14 </p> 15 <!-- 路由出口 --> 16 <!-- 路由匹配到的組件將渲染在這裏 --> 17 <router-view></router-view> 18 </div> 19 </body> 20 <script type="text/javascript" src="js/vue.js" ></script> 21 <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script> 22 <script type="text/javascript"> 23 24 const Foo = { 25 template: '<div>Vue</div>' 26 } 27 const Bar = { 28 template: '<div>BootStrap</div>' 29 } 30 31 const routes = [{ 32 path: '/Vue', 33 component: Foo 34 }, 35 { 36 path: '/BootStrap', 37 component: Bar 38 } 39 ] 40 41 const router = new VueRouter({ 42 routes 43 }) 44 45 const app = new Vue({ 46 router 47 }).$mount('#app') 48 49 50 </script> 51 </html>
9 綜合實例應用 |
上邊已經瞭解了Vue路由,下邊就是一個小小的綜合實例,經過點擊按鈕,在當前頁面切換不一樣的組件。
1 <!DOCTYPE html> 2 <html lang="en"> 3 4 <head> 5 <meta charset="UTF-8"> 6 <title>綜合實例</title> 7 <script src="https://unpkg.com/vue/dist/vue.js"></script> 8 <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script> 9 <style> 10 ul, 11 li { 12 list-style: none; 13 } 14 15 ul { 16 overflow: hidden; 17 } 18 19 li { 20 float: left; 21 width: 100px; 22 } 23 24 h1 { 25 background-color: #98D361; 26 } 27 28 h2 { 29 background-color: #FF9209; 30 } 31 32 h3 { 33 background-color: #D84C29; 34 } 35 </style> 36 </head> 37 38 <body> 39 <div id="app"> 40 <bar> </bar> 41 <hr> 42 <p>buttons: {{ buttons }}</p> 43 <router-view class="items"></router-view> 44 <footer-bar></footer-bar> 45 </div> 46 <script> 47 var topbarTemp = ` 48 <nav> 49 <ul> 50 <li v-for="item in list"> 51 <router-link :to="item.url">{{ item.name }}</router-link> 52 </li> 53 </ul> 54 </nav> 55 `; 56 // 定義組件:topbar 57 Vue.component('bar', { 58 template: topbarTemp, 59 data: function() { 60 return { 61 list: [{ 62 name: '小說', 63 url: '/story' 64 }, 65 { 66 name: '動漫', 67 url: '/carton' 68 }, 69 { 70 name: '繪畫', 71 url: '/draw' 72 }, 73 ] 74 } 75 } 76 }); 77 78 Vue.component('footer-bar', { 79 template: ` 80 <footer> 81 <p>Vue 路由<p> 82 </footer> 83 ` 84 }); 85 86 var story = { 87 template: `<div> <h1>{{ msg }}<h1></div>`, 88 data: function() { 89 return { 90 msg: 'Vue 基礎' 91 } 92 } 93 }; 94 95 var carton = { 96 template: `<div> <h2>{{ msg }}<h2></div>`, 97 data: function() { 98 return { 99 msg: 'Vue 組件' 100 } 101 } 102 } 103 104 var draw = { 105 template: `<div> <h3>{{ msg }}<h3></div>`, 106 data: function() { 107 return { 108 msg: 'Vue 路由實例' 109 } 110 } 111 } 112 113 // 定義路由對象 114 var router = new VueRouter({ 115 routes: [{ 116 path: '/story', 117 component: story 118 }, 119 { 120 path: '/carton', 121 component: carton 122 }, 123 { 124 path: '/draw', 125 component: draw 126 } 127 ] 128 }); 129 130 // 初始化一個Vue實例 131 var app = new Vue({ 132 el: '#app', 133 data: { 134 buttons: '點擊按鈕,切換不一樣組件' 135 }, 136 router: router 137 }); 138 </script> 139 </body> 140 141 </html>
Vue知識還有不少,但願經過對Vue一些基礎知識的學習,對於正在學習前端的知識的你能夠有所幫助。