vue--組件
vue的組件
什麽是組件:說白了,就是自定義標簽。
vue為什麽有組件的概念:不止是vue,目前流行的框架都有組件這個概念,比如angular中的自定義指令,其實就是組件。
怎麽使用組件:使用組件之前,先要創建一個組件
var MyComponent = Vue.extend({ // 選項... })
然後是註冊組件
需要用Vue.component(tag,constructor) 註冊
// 全局註冊組件,tag 為 my-component Vue.component(‘my-component‘, MyComponent)
組件在註冊之後,便可以在父實例的模塊中以自定義元素 <my-component>
的形式使用。要確保在初始化根實例之前註冊了組件:
<div id="example"> <my-component></my-component> </div>
// 定義 var MyComponent = Vue.extend({ template: ‘<div>A custom component!</div>‘ }) // 註冊 Vue.component(‘my-component‘, MyComponent)// 創建根實例 new Vue({ el: ‘#example‘ })
當然,這樣寫還是有些累,好在Vue給我們提供了註冊組件的“語法糖”
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <div id="app"> <explane></explane> </div> </body> <script src="../js/vue.js"></script> <script> Vue.component(‘explane‘,{ template:‘<p>this is firest component</p>‘ }); new Vue({ el:‘#app‘ }) </script> </html>
在chrome中顯示:
這種寫法Vue.component()
的第1個參數是標簽名稱,第2個參數是一個選項對象,使用選項對象的template屬性定義組件模板。
使用這種方式,Vue在背後會自動地調用Vue.extend()
。
調用Vue.component()註冊組件時[實際上是在vue的prototype對象裏添加component()],註冊的組件是全局的。這意味著該組件在任意Vue實例都可以使用,如果不需要全局註冊,或者是讓組件使用在其它組件[組件的嵌套]內,可以用選項對象的components屬性實現局部註冊。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <div id="app"> <first-comp></first-comp> <explane></explane> </div> </body> <script src="../js/vue.js"></script> <script> var cpt = Vue.extend({ template:"<p>第一個組件</p>" }); new Vue({ el:"#app", components: { "firstComp":cpt, "explane":{ template:"<p>第二個組件</p>" } } }) </script> </html>
在chrome中顯示:
盡管語法糖簡化了組件註冊,但在template選項中拼接HTML元素比較麻煩,這也導致了HTML和JavaScript的高耦合性。
慶幸的是,Vue.js提供了兩種方式將定義在JavaScript中的HTML模板分離出來。
第一種:使用script標簽
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <div id="app"> <first-cpt></first-cpt> </div> <script type="text/x-template" id="myCpt"> <p>script標簽引入模版</p> </script> </body> <script src="../js/vue.js"></script> <script> Vue.component("firstCpt",{ template:"#myCpt" }); new Vue({ el:"#app" }) </script> </html>
在chrome中顯示:
template選項現在不再是HTML元素,而是一個id,Vue.js根據這個id查找對應的元素,然後將這個元素內的HTML作為模板進行編譯。
註意:使用<script>標簽時,type指定為text/x-template,意在告訴瀏覽器這不是一段js腳本,瀏覽器在解析HTML文檔時會忽略<script>標簽內定義的內容。
第二種:使用template標簽
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <div id="app"> <first-cpt></first-cpt> </div> <template id="myCpt"> <p>script標簽引入模版</p> </template> </body> <script src="../js/vue.js"></script> <script> Vue.component("firstCpt",{ template:"#myCpt" }); new Vue({ el:"#app" }) </script> </html>
在chrome中顯示:
跟script標簽用法一樣。推薦使用這種方法。
組件的選項
傳入Vue構造器的多數選項也可以用在 Vue.extend()
或Vue.component()
中,不過有兩個特例:data
和el
。
Vue.js規定:在定義組件的選項時,data和el選項必須使用函數,否則會報錯。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <div id="app"> <first-cpt></first-cpt> <second-cpt></second-cpt> </div> <template id="myCpt"> <p>姓名:{{name}}</p> </template> </body> <script src="../js/vue.js"></script> <script> Vue.component("firstCpt",{ template:"#myCpt", data:function(){ return { name:"hk" } } }); new Vue({ el:"#app", data:{ name:"jjk" }, components: { "secondCpt":{ template:"<p>姓名:{{name}}</p>", data:function(){ return { name:"dk" } } } } }) </script> </html>
在chrome中顯示:
可以看出每個組件都有自己的作用域,互不幹擾。Vue實例的中data選項也不會影響組件。
有時候,組件之間需要通信。這時就需要用到props選項了。
在·chrome中顯示:
為了便於理解,你可以將這個Vue實例看作my-component的父組件。如果想要獲取父組件的數據,必須在子組件中設置props選項([email protected])
註意:方法是不能通過props選項獲取的。
props默認是單向綁定:修改了子組件的數據,沒有影響父組件的數據。修改了父組件的數據,會影響子組件的數據
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <div id="app"> <input v-model="name"> <first-cpt :my-name="name" my-send="send"></first-cpt> </div> <template id="myComponent"> <p>{{myName}}</p> <input v-model="myName"> </template> </body> <script src="../js/vue.js"></script> <script> var vm = new Vue({ el: ‘#app‘, data: { name: ‘jjk‘ }, methods: { send:function(){ alert(‘666‘) } }, components: { ‘firstCpt‘: { template: ‘#myComponent‘, props: [‘myName‘,"mySend"] } } }) </script> </html>
一開始:
當修改了父組件時:
當修改了子組件時:
可以使用.sync顯式 指定雙向綁定,可以使子組件的數據修改可以傳回給父組件
<first-cpt :my-name.sync="name" my-send="send"></first-cpt>
修改子組件數據時,父組件的數據也相應改變
vue--組件