1.組件機制
組件 (Component) 是 Vue.js 最強大的功能之一。組件可以擴展HTML元素,封裝可重用的代碼。在較高層面上,組件是自定義元素,Vue的編譯器為它添加特殊功能。在有些情況下,組件也可以表現為用is特性進行了擴展的原生 HTML 元素。組件注冊的時候需要為該組件指定各種參數。
因為組件是可復用的 Vue 實例,所以它們與 new Vue 接收相同的選項,例如 data、computed、watch、methods 以及生命周期鉤子等。僅有的例外是像 el 這樣根實例特有的選項。
### 組件的特點* 組件可以進行任意次數的復用。* 組件的data必須是一個函數,確保每個實例可以維護一份被返回對象的獨立的拷貝,也就是任何一個組件的改變不會影響到其他組件。
let component = { data () { return { count: 0 } },template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>'
}
一個組件的 data 選項必須是一個函數,因此每個實例可以維護一份被返回對象的獨立的拷貝
2.組件注冊
要想進行組件使用得先進行組件注冊
全局注冊
可以使用Vue.component(tagName, options) 注冊一個全局組件, 注冊之后可以用在任何新創建的 Vue 根實例的模板中
Vue.component(‘my-component-name’,component)局部注冊
全局注冊往往是不夠理想的。比如,如果你使用一個像 webpack 這樣的構建系統,全局注冊所有的組件意味著即便你已經不再使用一個組件了,它仍然會被包含在你最終的構建結果中。這造成了用戶下載的 JavaScript 的無謂的增加。局部注冊的組件只能在當前組件中使用
全局組件–>全局變量
局部組件–>局部變量
全局注冊
### js代碼// 1.創建組件let mycom = {data() {return {Commsg: '組件數據'}},methods:{changeObj(){if(this.Commsg==='組件數據'){this.Commsg='修改后的組件數據'}else{this.Commsg='組件數據'}}},// 模板template: `<div><br>組件使用<br>-------------------------<br><span>{{Commsg}}</span><span>{{Commsg}}</span><button @click='changeObj'>更改數據模型中的數據</button></div>`};// 全局注冊Vue.component('my-com',mycom)new Vue({el: '#app',data: {}})
### html代碼<div id="app"><my-com></my-com><my-com></my-com><my-com></my-com></div>
### 局部注冊
### html代碼<div id="app"><my-com-b></my-com-b>--------------------<my-com-a></my-com-a></div>
### js代碼// 創建組件let myComA={// 模板template:`<div>A組件</div>`};let myComB={components:{'my-com-a':myComA},// 模板template:`<div>B組件<my-com-a></my-com-a></div>`};//全局注冊// Vue.component('my-com-a',myComA)Vue.component('my-com-b',myComB)new Vue({components:{'my-com-a':myComA}, el:'#app',data:{}})
3.組件交互/通信/傳值
組件 A 在它的模板中使用了組件 B。它們之間必然需要相互通信:父組件可能要給子組件下發數據,子組件則可能要將它內部發生的事情告知父組件。在 Vue 中,父子組件的關系可以總結為 prop 向下傳遞,事件向上傳遞。父組件通過 prop 給子組件下發數據,子組件通過事件給父組件發送消息。
1.子組件內使用父組件數據 父-子
? 1.父組件傳遞數據給子組件 (可以傳遞靜態屬性 動態屬性 )
?
? 2.子組件接收并處理數據
? {
? props:[‘title’,‘msg’,'attrA],
? template:``
? }
? 2.父組件內使用子組件的數據
? 事件發射 自定義事件
? 在子組件內發射 在父組件內接受
? 子組件發射時機
? 1.手動按鈕發送
? 2.監聽子組件內數據變化,然后發射
在子組件內監聽comMsg的變化,this.$emit('',this.comMsg)
父組件的事件處理程序調用,可以更改父組件數據模型中的數據,同步反映到父組件視圖中
### 父組件傳遞數據給子組件
### html代碼<div id="app"><!-- 父組件給子組件傳遞數據 --><my-com :msg='msg' title='父組件向子組件傳值' attr-a='父組件給自組件的靜態數據'></my-com></div>
### js代碼// 創建組件let myCom={// 接受父組件傳遞的數據props:['title','msg','attrA'],data(){return {}},template:`<div>組件通信<br><span>{{msg}}--{{title}}--{{attrA}}</span></div>`}new Vue({components:{"my-com":myCom},el:"#app",data:{msg:'我是父組件'}})
### 子組件向父組件傳遞數據
### html代碼<div id="app">{{msg}}<my-a title='父組件靜態數據' :msg='msg' data-attr='父組件靜態數據' @my-event='handler'> </my-a></div></div>### js代碼<script>// 創建組件let myA={props:['title','msg','dataAttr'],data(){return {subMsg:'子組件數據'}},methods:{toSend(){// 參數 第一個參數自定義事件名稱 第二個參數傳遞的數據this.$emit('my-event',this.subMsg,100)}},template:`<div>{{subMsg}}--{{msg}}--{{dataAttr}}--<button @click='toSend'>發射數據</button></div>};// 全局注冊Vue.component('my-a',myA)new Vue({el:"#app",data:{msg:'父組件數據'},methods: {handler(a,b){console.log(a,b)}},})
4.組件傳值
父組件通過屬性綁定的方式將參數傳遞給子組件,子組件通過props聲明期望從父組件那里獲取的參數。camelCase (駝峰命名法) 的 prop 名需要使用其等價的 kebab-case (短橫線分隔命名) 命名:
希望每個prop都有指定的值類型。這時,你可以以對象形式列出prop,這些property的名稱和值分別是prop各自的名稱和類型
父組件給子組件數據的時候,子組件可以定義數據類型
靜態傳參:不加冒號,傳字符串
動態傳參:加冒號,傳number、boolean、object、數組類型的值,變量
props: {
title: String,
likes: Number,
isPublished: Boolean,
commentIds: Array,
author: Object,
callback: Function,
contactsPromise: Promise // or any other constructor
}prop驗證
? 我們可以為組件的 prop 指定驗證要求,例如你知道的這些類型。如果有一個需求沒有被滿足,則 Vue 會在瀏覽器控制臺中警告你。這在開發一個會被別人用到的組件時尤其有幫助。
Vue.component(‘my-component’, {
props: {
// 基礎的類型檢查 (null
和undefined
會通過任何類型驗證)
propA: Number,
// 多個可能的類型
propB: [String, Number],
// 必填的字符串
propC: { type: String, required: true },
// 帶有默認值的數字
propD: { type: Number, default: 100 }
})
### js代碼// 創建組件let myA={props:['title','msg'],data(){return {subMsg:'子組件' }},template:`<div>{{title}}-{{msg}}</div>`}Vue.component('my-a',myA)new Vue({el:'#app',data:{msg:'父組件'}})
### html代碼<div id="app">{{msg}}<my-a title='hello' :msg='msg' ></my-a></div>
### html代碼
<div id="app">{{msg}}<!-- <my-a sub-msg="父給子" :stus="[1,2,3]" :is-active="undefined"></my-a> --><!-- <my-a sub-msg="父給子" :stus="[1,2,3]" :is-active="true"></my-a> --><my-a :msg="msg" sub-msg="父給子" :is-active="true" :age="80"></my-a></div>
### js代碼
let myA = {props: {msg: String,subMsg: String,// stus: Array,stus: {type: Array,// 錯誤// default: [6, 7, 8]// 正確 Object/Array要一個工廠函數返回默認值default() {return [6, 7, 8];}},// isActive: BooleanisActive: [String, Boolean],name: {type: String,// 必填項// required: truedefault: "lisi"},// 自定義校驗規則age: {type: Number,// 校驗器 // value 是形參,實參是將來父組件給子組件傳遞的數據validator(value) {/* if(value>50){return true;}else{return false;} */return value > 50;}}},template: `<div>{{subMsg}}{{stus}}{{isActive}} {{name}}{{age}}{{msg}}</div>`};Vue.component('my-a', myA);let vm = new Vue({el: '#app',data: {msg: 'hello'},methods: {}})
單向數據流(數據更改的方向)
父組件可以改給子組件的數據
父改子可以
子組件不可以改父組件的數據
子改父不行修改父組件的msg 子組件的msg跟著修改但是反過來不行
vm.msg=‘hello vue’ 觀察子組件的變化