組件就是能夠擴展HTML元素,封裝可重用的HTML代碼,能夠將組件看做自定義的HTML元素html
全局註冊:vue
組件註冊時,須要給他一個名字,以下:python
Vue.component('my-component-name', { /* ... */ })
# 組件名使用kebab-case (短橫線分隔命名)定義時,引用這個元素時使用 <my-component-name>ajax
# 組件名使用 PascalCase (駝峯式命名) 定義時,引用這個元素時使用<my-component-name>
和 <MyComponentName>均可以
vue-router
局部註冊:數組
經過一個普通的 JavaScript 對象來定義組件app
var ComponentA = { /* ... */ }
var ComponentB = { /* ... */ }
而後在component選項中定義想要的組件異步
new Vue({
el: '#app'
components: {
'component-a': ComponentA,
'component-b': ComponentB
}
})
# 局部註冊的組件在其子組件中不可用ide
全局註冊實例:函數
組件的複用(主體代碼):
<body> <div id="app"> <buttons></buttons> <buttons></buttons> <buttons></buttons> </div> <hr> <div id="app2"> <buttons></buttons> </div> </body> <script> // 組件中data必須是一個函數,第一個參數是咱們的定義標籤 Vue.component('buttons',{ data:function(){ return{ count:0 } }, template:`<button v-on:click='count++'>biubiubiu{{ count }}</button>` }) var app = new Vue({ el:"#app" }) var app2 = new Vue({ el:"#app2" }) </script>
效果:
局部註冊實例:
(父組件往子組件傳值)
<body> <div id="app"> <bts v-bind:name='fir'></bts> <bts v-bind:name='sec'></bts> <bts v-bind:name='thi'></bts> <hr> <bts v-for='nums in list' v-bind:name='nums'></bts> </div> </body> <script> // 這裏的buttons屬於咱們的自定義標籤,經過props向子組件傳遞數據 var myComponent = { template:`<button v-on:click="cli">{{name}}+{{count}}</button>`, // 使用props聲明,組件須要外邊從data給傳一個字符串格式的name變量 props:{ name:String }, data:function(){ return{ count:0, } }, methods:{ cli:function(){ this.count += 1 } } } // 自定義局部組件 new Vue({ el:'#app', data:{ list:[ '1', '2', '3', ], fir:'first', sec:'second', thi:'third', }, components:{ bts:myComponent } }) </script>
效果:
該圖很好的代表了組件的組織關係對應圖,或者說是層級關係
Vue.js經過組件,把一個單頁應用中的各類模塊拆分到一個一個單獨的組件(component)中,只要先在父級應用中寫好各類組件標籤,而且在組件標籤中寫好要傳入組件的參數(就像給函數傳入參數同樣,這個參數叫作組件的屬性),而後再分別寫好各類組件的實現,而後整個應用就算作完了
<body> <div id="app"> <!-- 寫死了 --> <buttons title="My journey with Vue"></buttons> <buttons title="Blogging with Vue"></buttons> </div> <hr> <!-- 動態傳遞 --> <div id="app2"> <buttons v-for="post in posts" v-bind:key="post.id" v-bind:title="post.title" ></buttons> </div> </body> <script> Vue.component('buttons', { props: ['title'], template: '<h3>{{ title }}</h3>' }) var app = new Vue({ el:"#app", }) var app2 = new Vue({ el:"#app2", // 動態傳遞一個數組 data: { posts: [ { id: 1, title: 'My journey with Vue' }, { id: 2, title: 'Blogging with Vue' }, ] } }) </script>
子組件往父組件傳值:
<body> <div id="app"> <p>總數:{{total}}</p> <bts v-for='nums in list' v-bind:name='nums' v-on:zhi="add"></bts> </div> </body> <script> // 這裏的bts屬於咱們的自定義標籤,經過props向子組件傳遞數據 var myComponent = { template:` <div> <button v-on:click="cli">{{count}}{{name}}</button> </div> `, // 使用props聲明,組件須要外邊從data給傳一個字符串格式的name變量 props:{ name:String }, data:function(){ return{ count:0, } }, methods:{ cli:function(){ this.count += 1; // 在組件中經過觸發自定義事件向外傳遞信息 this.$emit('zhi') } } } // 自定義局部組件 new Vue({ el:'#app', data:{ total:0, list:[ '只豬','只狗','只兔子', ] }, components:{ bts:myComponent }, methods:{ add:function(){ this.total += 1 } } }) </script>
效果:
組件間傳值(生成一個空vue對象bus):
各個組件內部要傳輸的數據或者要執行的命令信息,靠bus來通訊。
<body> <div id="app"> <bt></bt> <hr> <nums></nums> </div> </body> <script> var bus = new Vue(); var app = new Vue({ el:'#app', data:{ name:'bt' }, components:{ bt:{ template:`<button v-on:click='check'>點我</button>`, methods:{ check(){ bus.$emit('things') } } }, nums:{ template:`<div>{{num}}</div>`, data:function(){ return { num: 0 } }, mounted:function(){ // 該組件中this指num實例 var _this = this; console.log(_this); // 監聽bus bus.$on('things', function(){ // 在這個做用域中 this 指的是 bus console.log(this.num) // undefined // 修改num組件中的num值 // 此時this是誰? // this.num += 1; // 有問題 _this.num += 1; }) } } } }) </script>
在第一個組件中的methods方法裏,經過bus.$emit()方法發射事務
在第二個組件實例化的鉤子中(mounted)中,經過bus.$on監聽自家$emit觸發的事件
插槽是佔位置的!!!
插槽多了能夠起名字,進行區分! --> <span slot='heihei'>嘿嘿!</span>
<body> <div id="app"> <alert-box> Something bad happened. </alert-box> </div> </body> <script> Vue.component('alert-box', { template: ` <div class="demo-alert-box"> <strong>Error!</strong> <slot></slot> </div> ` }) new Vue({ el:"#app" }) </script>
效果:
若是想在一個組件的根元素上直接監聽一個原生事件,這時候就可使用v-on的.naive修飾符
實例0(不推薦使用):
<body> <div id="app"> <ztzsb v-on:click='hehe'></ztzsb> </div> </body> <script> var app = new Vue({ el: '#app', data: { name: 'ztz', age: 24 }, components: { ztzsb: { template: `<button v-on:click='shangkele'>趙天柱 逃課!</button>`, methods:{ shangkele:function(){ this.$emit('click') } } } }, methods:{ hehe:function(){ alert(123); } } }) </script> </html>
實例1:
<body> <div id="app"> <ztz v-on:click.native='hehe'></ztz> </div> </body> <script> var app = new Vue({ el:"#app", data:{}, components:{ ztz:{ template:`<button>趙天柱 逃課!</button>` }, }, methods:{ hehe:function(){ alert(123); } } }) </script> </html>
再看看下面的實例2:
<body> <div id="app"> <ztz></ztz> </div> </body> <script> var app = new Vue({ el:"#app", data:{}, components:{ ztz:{ template:`<button v-on:click='hehe'>趙天柱 逃課!</button>`, methods:{ hehe(){ alert(123); } } }, } }) </script>
## 實例1和2二者效果如出一轍,一個是在根元素上進行事件綁定,一個是在局部組件上進行綁定
1. Vue組件 0. 組件注意事項!!! data屬性必須是一個函數! 1. 註冊全局組件 Vue.component('組件名',{ template: `` }) var app = new Vue({ el: '#app' }) 2. 註冊局部組件 var app = new Vue({ el: '#app', components:{ 局部組件名:{ template: `...` } } }) 3. 傳值 1. 父組件 --> 子組件 1. 父組件經過 v-bind:變量='值' 2. 子組件須要經過props 聲明我須要的變量 2. 子組件 --> 父組件 子組件經過觸發自定義事件的方式向外傳遞信息 1. 子組件: this.$emit('自定義事件') 2. 父組件: v-on:自定義事件='方法名' 3. 組件間傳值 1. 補充:Vue實例的生命週期鉤子函數(共8個) 1. beforeCreate --> 數據屬性聲明但沒有賦值 2. created --> 數據屬性賦值 3. beforeMount --> 頁面上的 {{name}} 尚未被渲染 4. mounted --> 頁面上的 {{name}} 被替換成真正的內容 ... 2. 基於bus對象實現 4. 插槽(slot) 插槽是佔位置的!!! 插槽多了能夠起名字,進行區分! --> <span slot='heihei'>嘿嘿!</span> <alert>根本不顯示</alert> 5. 組件的注意事項: 1. 特殊的組件須要使用is語法聲明一下 好比 table、select、ul等內部使用的組件 2. 捕獲子組件的原生事件
Vue Router 是 Vue.js 官方的路由管理器
將組件 (components) 映射到路由 (routes),而後告訴 Vue Router 在哪裏渲染它們,實現異步ajax界面切換效果(頁面不刷新)
# 例,注意vue-router.js的引入方式
<script src="https://unpkg.com/vue/dist/vue.js"></script> <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script> <body> <div id="app"> <!-- 路由入口 --> <router-link to='/index'>index頁面</router-link> <router-link to='/home'>home頁面</router-link> <hr> <!-- 路由出口 --> <router-view></router-view> </div> </body> <script> // 路由,數組包含兩個路由 const routess = [ {path:'/index',component:{template:`<div><h2>index頁面</h2></div>`}}, {path:'/home',component:{template:`<div><h2>home頁面</h2></div>`}}, ] // 生成實例,routes是關鍵字,它的值必須是一個數組 const routerObj = new VueRouter({ routes:routess }) new Vue({ el:'#app', // 路由實例掛載到vue實例中,router是關鍵字 router:routerObj }) </script> </body> </html>
效果:
咱們有一個 User
組件,對於 ID 各不相同的用戶,都要使用這個組件來渲染。那麼,咱們能夠在 vue-router
的路由路徑中使用「動態路徑參數」(dynamic segment) 來達到這個目的
一個「路徑參數」使用冒號 :
標記。當匹配到一個路由時,參數值會被設置到 this.$route.params,以下
實例:
<body> <div id="app"> <!--路由的入口--> <!-- 使用 router-link 組件來導航. --> <!-- 經過傳入 `to` 屬性指定連接. --> <!-- <router-link> 默認會被渲染成一個 `<a>` 標籤 --> <router-link to="/user/index">index頁面</router-link> <router-link to="/user/home">home頁面</router-link> <hr> <p>666</p> <!--路由的出口--> <!-- 路由匹配到的組件將渲染在這裏 --> <router-view></router-view> <p>999</p> </div> <script> //寫路由 const routeArray = [ { path: '/user/:name', component: {template: `<h3>這是{{$route.params.name}}的主頁頁面!</h3>`} } ] //生成路由實例 const routerObj = new VueRouter({ routes: routeArray }) var app = new Vue({ el:'#app', //router是關鍵字,它的值必須是數組 router:routerObj //將路由實例掛載到vue實例中 }) </script>
效果:
URL 中各段動態路徑按某種結構對應嵌套的各層組件,以下:
實例(關鍵點在於使用append拼接路由):
<div id="app"> <router-link to="/user/index">index</router-link> <router-link to="/user/home">home</router-link> <hr> <router-view></router-view> </div> <script> // 生成路由數組 const routeArray = [ { path: '/user/:name', component: { //append表示當前路由拼接url,好比/user/home/info //router-view對應子路由的template的內容 template: `<div> <h3>這是{{$route.params.name}}的主頁頁面!</h3> <hr> <router-link to='info' append>用戶詳細信息</router-link> <router-view></router-view> </div>` }, // 定義子路由 children:[ { path: 'info', component:{ template: ` <div> <h1>大傻逼</h1> </div> ` } }, ] } ] //生成VueRouter實例 const routerObj = new VueRouter({ //routes是關鍵字參數,它必須對應一個數組 routes: routeArray }) var app = new Vue({ el:'#app', data:{}, //router是關鍵字,它的值必須是數組 router:routerObj //將路由實例掛載到vue實例中 }) </script>
效果:
總結:
1. Vue全家桶 Vue + VueRouter + VueX 2. VueRouter https://router.vuejs.org/zh/ 1. 基本使用 1. 必須導入vue-router.js文件 2. 要有VueRouter()實例 3. 要把VueRouter實例掛載到Vue實例中 4. 路由的入口 <router-link to='/index'>index頁面</router-link> 5. 路由的出口 <router-view></router-view> 2. 路由的參數 1. path: '/user/:name' --> 匹配路由 $route.params.name --> 取值 2. /user/alex?age=9000 --> url中攜帶參數 $route.query.age --> 取出url的參數 3. 子路由 children:[ { path: '', component: { template: `...` } } ] <router-link to='info' append></router-link>