1、組件的兩種使用方法html
3、單向數據流git
4、組件中的命名方式github
5、數據驗證數組
6、組件通訊app
8、動態組件ui
<my-component></my-component>
Vue.component('my-component',{ template: '<div>組件內容</div>' })
var app = new Vue({ el:'#app', components:{ ''my-components:{ template:'<div>組件內容</div>' } } })
這邊的props採用數組方式this
父組件向子組件傳遞數據spa
v-bin動態綁定父組件傳的內容
<div id="app" style="width:300px;height:200px;border:2px solid skyblue"> <child-component msg="我是父組件的內容"></child-component> <hr> <!-- v-bind進行動態數據動態綁定 將input中的sth傳給子組件 --> <input type="text" v-model="dadmsg"> <bind-component :sth="dadmsg"></bind-component> </div>
var app = new Vue({ el: '#app', data: { dadmsg: 'happy' }, components: { 'child-component': { props: ['msg'], template: '<div>{{msg}}</div>' }, 'bind-component': { props: ['sth'], template: '<div>{{sth}}</div>' } } })
在組件中使用props來從父組件接收參數,在props中的屬性,均可以在組件中直接使用。
概念理解:經過props傳遞數據是單向的,父組件變化時數據會傳給子組件,可是反過來不行。
目的:是將父子組件解稿,避免子組件修改無心間修改了父組件的狀態。
<div id='app'> <child-component msg='今天也要努力啊'></child-component> </div>
let app = new Vue({ el: '#app', components: { 'child-component': { props: ['msg'], template: '<div>{{count}}</div>', data() { return { count: this.msg } } } } })
<div id="app"> <input type="text" v-model="width"> <width-component :width='width'></width-component> </div>
let app = new Vue({ el: "#app", data: { width: 0 }, components: { 'width-component': { props: ['width'], template: '<div :style="style"></div>', computed: { style() { return { width: this.width + 'px', background: 'red', height: '30px' } } } } } })
camelCased (駝峯式)
kebabcase(短橫線命名)
這邊的props採用對象方式
可驗證的類型:Number String Boolean Array Object Function 自定義
<div id="app"> <style-component :a='a' :b='b' :c='c' :d='d' :e='e' :g='g'></style-component> </div>
let app = new Vue({ el: '#app', data: { a: 1, b: '2', c: '', //空字符串,就取默認的true d: [111, 222, 333], e: console.log(), g: 3 }, components: { 'styleComponent': { props: { //數字類型 a: { type: Number, required: true //必傳 }, //字符串類型 b: { type: [String, Number] }, //布爾類型 c: { type: Boolean, default: true //默認值 }, //數組或對象 默認值是函數形式返回 d: { type: Array, default: function() { return [] } }, //函數類型 e: { type: Function }, //自定義一個函數 g: { validator: function(value) { return value < 10 } } }, template: '<div>{{a}}--{{b}}--{{c}}--{{d}}--{{g}}</div>' } } })
——給父組件添加自定義事件
——子組件經過$emit觸發事件
<div id="app"> <p>您的帳戶餘額爲{{num}}</p> <btn-component @change='change'></btn-component> </div>
new Vue({ el: '#app', data: { num: 3000 }, methods: { change(value) { this.num = value } }, components: { 'btn-component': { template: '<div>\ <button @click="hangle_ad">+1000</button> \ <button @click="hangle_re">-1000</button> \ </div>', data() { return { count: 3000 } }, methods: { hangle_ad() { this.count += 1000 this.$emit('change', this.count) }, hangle_re() { this.count -= 1000 this.$emit('change', this.count) } } } } })
——v-model代替自定義事件
v-model實質背後作了兩個操做
因此上面那個銀行存款的demo能夠改成
<div id="app"> <p>您的帳戶餘額爲{{num}}</p> <btn-component v-model='num'></btn-component> 這邊改啦!! </div>
new Vue({ el: '#app', data: { num: 3000 }, //父組件沒有自定義函數啦!! components: { 'btn-component': { template: '<div>\ <button @click="hangle_ad">+1000</button> \ <button @click="hangle_re">-1000</button> \ </div>', data() { return { count: 3000 } }, methods: { hangle_ad() { this.count += 1000 this.$emit('input', this.count) //這邊改啦!! }, hangle_re() { this.count -= 1000 this.$emit('input', this.count) //這邊改啦!! } } } } })
兩個非父子關係的組件進行通訊,可使用一個空的Vue實例做爲中央事件總線(中介)
<div id="app"> <ahandle></ahandle> <bhandle></bhandle> </div>
var app = new Vue({ el: '#app', data: { bus: new Vue() //bus中介 }, components: { 'ahandle': { template: '<div><button @click="aclick">點擊向b組件傳遞數據</button></div>', data() { return { aaa: '我是來自a組件的內容' } }, methods: { aclick() { //a組件建立事件,供b組件監聽 由bus中介$emit提交 this.$root.bus.$emit('givetob', this.aaa) } } }, 'bhandle': { template: '<div>我是b組件</div>', created() { //b組件監聽a組件建立的事件 由bus中介$on監聽 this.$root.bus.$on('givetob', function(value) { //這裏的value就是a組件傳進來的this.aaa alert(value) }) } } } })
<div id="app"> <btn-component></btn-component>--{{msg}} </div>
let app = new Vue({ el: '#app', data: { msg: '我是父組件,我如今沒有內容' }, components: { 'btn-component': { template: '<button @click="changeFather">點擊修改父組件中的內容</button>', methods: { changeFather() { this.$parent.msg = '我如今有內容啦' } } } } })
vue提供索引:$ref
<div id="app"> <button @click='getchild'>點擊父組件按鈕獲取a組件內容</button> <a-component ref='a'></a-component> 添加索引ref <b-component ref='b'></b-component> {{msg}} </div>
let app = new Vue({ el: '#app', data: { msg: '子組件數據未得到' }, methods: { getchild() { this.msg = this.$refs.a.msg //獲取a組件的內容 ---refs } }, components: { 'a-component': { template: '<span></span>', data() { return { msg: '我是a組件中的內容' } } }, 'b-component': { template: '<span></span>', data() { return { msg: '我是b組件中的內容' } } } } })
使用slot進行分發內容
父組件模板的內容在父組件做用域中編譯;
子組件模板的內容在子組件做用域內編譯。
混合父組件的內容與子組件本身的模板
<div id="app"> <slotcomponent> <p>父組件插入到子組件的內容——我把子組件的slot替換掉啦</p> </slotcomponent> </div>
new Vue({ el: '#app', components: { 'slotcomponent': { template: '<slot>父組件沒有插入內容沒有內容就顯示這個</slot>' } } })
<div id="app"> <name-component> <h2 slot="header">標題</h2> <p>內容1</p> <p>內容2</p> <p slot="footer">底部</p> </name-component> </div>
let app = new Vue({ el: '#app', components: { 'name-component': { template: '<div> \ <div class="header"> \ <slot name="header"></slot> \ </div> \ <div class="container"> \ <slot></slot> \ </div> \ <div class="footer"> \ <slot name="footer"></slot> \ </div> \ </div>' } } })
<div id="app"> <mycomponent> <p slot='aaa' slot-scope='child'> {{child.text}} name拿不到 </p> </mycomponent> </div>
let app = new Vue({ el: '#app', components: { 'mycomponent': { template: '<div>\ <slot text="我是子組件插槽的內容" name="aaa"></slot>\ </div>' } } })
*2.5.0以前都是用template中寫,渲染的是template中的內容
<div id="app"> <mycomponent> <template slot='aaa' slot-scope='child'> {{child.text}} name拿不到 </template> </mycomponent> </div>
this.$slot.插槽名稱
在具名插槽的例子前提下添加代碼
...... components:{ ...... mounted(){ var header = this.$slots.header console.log(header) //此處拿到的是虛擬節點 var headerin = this.$slots.header[0].elm.innerText console.log(headerin) } }
使用Vue提供的component元素,動態掛載不一樣的組件
使用is特性來實現
待補充待補充待補充......