元件通訊
自定義事件
Vue有一套與JS觀察者模式類似的設計,子元件用$emit()來觸發事件,父元件用$on()來監聽子元件的事件。
<div id='app'>
<son-component @change='handleTotal'></son-component>
<!--change就是自定義事件-->
</div>
複製程式碼
Vue.component('son-component',{
template:
'<div>\
<button @click='handleIncrease'>+1</button>\
<button @click='handleReduce'>-1</button>\
</div>',
data:function(){
return {
count: 0
}
},
methods:{
handleIncrease:function(){
this.count += 1;
this.$emit('change',this.count)
},
handleReduce:function(){
this.count -= 1;
this.$emit('change',this.count)
}
}
})
var app = new Vue({
el:'#app',
data:{
total: 0
},
methods:{
handleTotal:function(value){
this.total = value
}
}
})
複製程式碼
在元件中使用v-model
<div id="app">
<son-component v-model='total'></son-component>
</div>
複製程式碼
Vue.component('son-component',{
template:'<div>\
<button @click="handleIncrease">+1</button>\
</div>',
methods:{
handleIncrease:function(){
this.count +=1
this.$emit('input',this.count)
}
},
data:function(){
return {
count:1
}
}
})
var app = new Vue({
el:'#app',
data:{
total: 1
}
})
複製程式碼
非父元件的通訊
<div id="app">
<component-a ref='a'></component-a>
<component-b ref='b'></component-b>
<hr style="background-color:cyan;height:4px;">
<component-c ref='c'></component-c>{{msg}}
<button @click='getChildData'>我是父元件的按鈕,我要拿到子元件的內容</button>
{{formChild}}
</div>
複製程式碼
Vue.component('component-a', {
template: '<div><button @click="handle">我是a元件的按鈕</button></div>',
data: function () {
return {
a: '其實我是a元件的data定義的內容,我通過b中的函式顯示出來。',
msg: '我是a中的msg'
}
},
methods: {
handle: function () {
this.$root.bus.$emit('eve', this.a) //eve為自定義的事件名,this.a是要傳送的資料
}
}
})
Vue.component('component-b', {
template: '<div>其實我是B元件</div>',
data: function () {
return {
msg: '我是b中的msg'
}
},
created: function () {
this.$root.bus.$on('eve', function (value) {
alert(value)
})
}
})
Vue.component('component-c', {
template: '<button @click="amend">點我修改父元件的內容</button>',
data: function () {
return {
msg: '我是c中的msg'
}
},
methods: {
amend: function () {
this.$parent.msg = '豬突猛進'
}
}
})
var app = new Vue({
el: '#app',
data: {
bus: new Vue(),
msg: '我是未修改過的父元件的內容',
formChild: '還未拿到'
},
methods: {
//用來拿子元件中的內容
getChildData: function () {
this.formChild = this.$refs.b.msg;
}
}
})
複製程式碼
插槽
單個slot
<div id="app">
<part-component>
{{msg}}
</part-component>
</div>
複製程式碼
var app = new Vue({
el:"#app",
data:{
msg:'我愛你'
},
components:{
"part-component":{
template:'\
<div>你愛我嗎?\
<slot>你要是不愛我我就出來再問你一遍。</slot>\
</div>'
}
}
})
複製程式碼
使用{{msg}}渲染時:
不渲染內容則預設顯示<slot>
標籤中的內容:
具名插槽
<div id="app">
<part-component>
<h1 slot='head'>1</h1>
<h2>2</h2>
<h3>3</h3>
</part-component>
</div>
複製程式碼
var app = new Vue({
el: "#app",
data: {
},
components: {
"part-component": {
template: '\
<div>\
<div class="head">\
<slot name="head"></slot>\
</div>\
<div class="container">\
<slot></slot>\
</div>\
</div>',
}
}
})
複製程式碼
template中<slot>
標籤中定義的name值會自動匹配html標籤中slot屬性值相同的屬性;template中未定義name值的<slot>
標籤會去匹配沒有設定slot屬性的標籤,從而改變其dom結構。從而更新資料變得方便。
作用域插槽
作用是通過slot從子元件獲取資料。
<div id="app">
<my-component>
<template slot='name' slot-scope="variable">
<!-- variable是一個臨時變數名 -->
{{variable}}
<!--渲染出的標籤屬性可以以{{variable.xx}}方式渲染到html-->
</template>
</my-component>
</div>
複製程式碼
Vue.component('my-component',{
template:'\
<div>\
<slot class="hh" id="qq" qwe="123" text="我是要被拿到的資料" name="name"></slot>\
</div>'
})
var app = new Vue({
el:'#app',
data:{
}
})
複製程式碼
訪問slot插槽
Vue.component('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>',
mounted: function () {
var head = this.$slots.header;
console.log(head[0].elm.innerHTML) //這樣便能獲取到插槽類名為header的內容
}
})
複製程式碼
動態元件
<div id="app">
<component :is='thisView'></component>
<button @click="dispose('a')">1</button>
<button @click="dispose('b')">2</button>
<button @click="dispose('c')">3</button>
<button @click="dispose('d')">4</button>
</div>
複製程式碼
Vue.component('component-a',{
template:'<div>哈哈</div>'
})
Vue.component('component-b',{
template:'<div>嘿嘿</div>'
})
Vue.component('component-c',{
template:'<div>嗯嗯</div>'
})
Vue.component('component-d',{
template:'<div>啵啵</div>'
})
var app = new Vue({
el:'#app',
data:{
thisView:'component-a'
},
methods:{
dispose:function(tag){
this.thisView = 'component-' + tag;
}
}
})
複製程式碼