組件(Component)是 Vue.js 最強大的功能之一,組件能夠擴展 HTML 元素,封裝可重用的代碼。javascript
組件系統讓咱們能夠用獨立可複用的小組件來構建大型應用,幾乎任意類型的應用的界面均可以抽象爲一個組件樹,以下圖所示:css
var com1 = Vue.extend({ template: '<h3>這是使用 Vue.extend 建立的組件</h3>' // 經過template屬性,指定了組件要展現的HTML結構 })
Vue.component('myCom1', com1)
<div id="app"> <!-- 若是要使用組件,直接把組件的名稱以HTML標籤的形式,引入到頁面中便可 --> <my-com1></my-com1> </div>
Vue.component('myCom1', Vue.extend({ template: '<h3>這是使用Vue.extend建立的組件</h3>' }))
Vue.component('mycom2', { template: '<div><h3>這是直接使用Vue.component建立出來的組件</h3><span>123</span></div>' })
<template id="tmpl"> <div> <h1>這是經過 template 元素,在外部定義的組件結構,這個方式,有代碼的智能提示和語法高亮</h1> </div> </template>
Vue.component('mycom3', {
template: '#tmpl' //引用template的id屬性
})
<template id="tmpl2"> <h1>這是私有的 login 組件</h1> </template>
var vm2 = new Vue({
el: '#app2',
components: { // 定義實例內部私有組件的
login: {
template: '#tmpl2'
}
},
})
Vue.component('mycom1', { template: '<h1>這是全局組件 --- {{msg}}</h1>', data: function () { return { msg: '這是組件的中data定義的數據' } } })
Html代碼:html
<div id="app"> <counter></counter> <hr> <counter></counter> <hr> <counter></counter> </div> <template id="tmpl"> <div> <input type="button" value="+1" @click="increment"> <h3>{{count}}</h3> </div> </template>
javascript代碼:vue
var dataObj = { count: 0 } //這是一個計數器的組件, 身上有個按鈕,每當點擊按鈕,讓data中的count值+1 Vue.component('counter', { template: '#tmpl', data: function () { // return dataObj return { count: 0 } }, methods: { increment() { this.count++ } } }) // 建立 Vue 實例,獲得 ViewModel var vm = new Vue({ el: '#app', data: {}, methods: {} });
調用測試結果以下 :java
每一個計數器的count是獨立的,如將將返回的值改成:
app
return dataObj //return { count: 0 }
結果爲:模塊化
每一個組件的count是共享的,組件的data必須是一個方法,且必須返回一個對象。要解決的問題就是提升組件的複用性,防止組件與組件之間成員干擾。組件化
<body> <div id="app"> <a href="" @click.prevent="flag=true">登陸</a> <a href="" @click.prevent="flag=false">註冊</a> <login v-if="flag"></login> <register v-else="flag"></register> </div> <script> Vue.component('login', { template: '<h3>登陸組件</h3>' }) Vue.component('register', { template: '<h3>註冊組件</h3>' }) var vm = new Vue({ el: '#app', data: { flag: true }, methods: {} }); </script> </body>
演示結果以下,默認顯示登陸組件,點擊註冊切換到註冊組件,點擊登陸切換的登陸組件。測試
缺點分析:若是在一個需求中須要切換更多的組件,這種方式不利於擴展。動畫
<div id="app"> <a href="" @click.prevent="comName='login'">登陸</a> <a href="" @click.prevent="comName='register'">註冊</a> <component :is="comName"></component> </div> <script> // 組件名稱是字符串 Vue.component('login', { template: '<h3>登陸組件</h3>' }) Vue.component('register', { template: '<h3>註冊組件</h3>' }) // 建立 Vue 實例,獲得 ViewModel var vm = new Vue({ el: '#app', data: { comName: 'login' //當前component中的 :is 綁定的組件的名稱 }, }); </script>
html代碼:
<div id="app"> <a href="" @click.prevent="comName='login'">登陸</a> <a href="" @click.prevent="comName='register'">註冊</a> <!-- 經過 mode 屬性,設置組件切換時候的模式爲先出後進--> <transition mode="out-in"> <component :is="comName"></component> </transition> </div> <script> // 組件名稱是 字符串 Vue.component('login', { template: '<h3>登陸組件</h3>' }) Vue.component('register', { template: '<h3>註冊組件</h3>' }) var vm = new Vue({ el: '#app', data: { comName: 'login' // 當前 component 中的 :is 綁定的組件的名稱 }, }); </script>
css代碼:
<style> .v-enter, .v-leave-to { opacity: 0; transform: translateX(150px); } .v-enter-active, .v-leave-active { transition: all 0.5s ease; } </style>
1 <div id="app">
2 <com1></com1>
3 </div>
4 <script>
5
6 Vue.component
7 var vm = new Vue({ 8 el:'#app', 9 data:{ 10 msg:"heelo !" 11 }, 12 methods:{ 13 }, 14 components:{ 15 com1:{ 16 template:'<h1>這是子組件---{{msg}}</h1>' 17 } 18 } 19 }) 20 </script>
執行結果:
默認狀況下子組件是不能引用父組件的屬性和對象的,咱們能夠在引用子組件的時候,經過屬性綁定的形式(v-bind)的形式,把須要傳遞給子組件的數據,以屬性綁定的形式傳遞到子組件內部,供子組件使用,而且在props中聲明該屬性(props中的數據都是經過父組傳遞過來的,這裏的數據是隻讀的),代碼以下:
1 <div id="app">
2 <com1 v-bind:parentmsg="msg"></com1>
3 </div>
4 <script>
5 Vue.component
6 var vm = new Vue({ 7 el: '#app', 8 data: { 9 msg: "heelo !" 10 }, 11 methods: { 12 }, 13 components: { 14 data() { 15 return { 16 title: '123', 17 content: 'pppp' 18 } 19 }, 20 com1: { 21 props: ['parentmsg'], 22 template: '<h1>這是子組件---{{parentmsg}}</h1>' 23 } 24 } 25 }) 26 </script>
請詳細看下面代碼中的註釋
1 <div id="app"> 2
3 <com2 @func="show"></com2> 4 </div> 5 <template id="tmpl"> 6 <div> 7 <h1>這是子組件</h1> 8 <input type="button" value="這是子組件中的點擊按鈕" @click="myclick"> 9 </div> 10 </template> 11 <script> 12 //定義了一個字面量類型的組件模板對象 13 var com2 = { 14 template: '#tmpl', 15 data() { 16 return { 17 sonmsg: { name: 'wjl', age: 16 } 18 } 19 }, 20 methods: { 21 myclick() { 22 //當點擊子組件的按鈕時,經過$emit拿到父組件傳遞過來的func 23 //emit的英文願意爲觸發、調用、發射的意思 24 this.$emit('func', this.sonmsg, 123, 456) 25 } 26 } 27 } 28 var vm = new Vue({ 29 el: '#app', 30 data: { 31 datamsg: null 32 }, 33 methods: { 34 show(data, data1, data2) { 35 console.log('調用了父組件的show方法:' + data.name + data1 + data2); 36 } 37 }, 38 components: { 39 com2 40 } 41 }) 42 </script>
個人博客即將搬運同步至騰訊雲+社區,邀請你們一同入駐:https://cloud.tencent.com/developer/support-plan?invite_code=2lv2gsiubr6sw