人类沟通需要技巧,程序语言靠的是方法。
我们除了可以透过 Props 来让父元件传值给子元件外,也可以透过子元件向父元件传递讯息,并可以直接在子元件中操控父元件里的资料。
在父元件传值给子元件所使用的 Props ,在传递资料时是单向资料流(One-Way Data Flow),也就是说,只允许子元件向父元件传递资料,而不允许子元件直接操控 Props 里的资料。有这个原则的原因是因为如果直接让子元件直接操控 Props 里的资料,资料的控制逻辑会变的很复杂与杂乱。单向资料流还是比较容易理解,Vue 也较推荐单向资料流的用法。虽然可以做到双向但 Vue 不建议使用双向。
那麽在 Vue 如何透过自定义事件向父元件传递讯息呢?即是使用 Vue 的内建$emit()
方法。
子元件透过自定义事件向父元件传递讯息
语法:<button v-on:click="$emit('enlarge-text')>Enlarge Text</button>
说明:一个子元件里的按钮,点击时会触发一个特定的方法$emit()
,并带上一个参数,此参数为自定义的事件名称enlarge-text
,这个事件会传递给父元件,所以父元件会去监听这个事件。
父元件中监听子元件的事件
语法:<menu-item v-on:enlarge-text="fontSize += 0.1"></menu-item>
说明:v-on:enlarge-text
为绑定事件名称,fontSize += 0.1
则为事件对应的处理逻辑。
透过实作的情境会比较清楚传递的运作原理:
实作范例效果:在子元件中点击Enlarge Text
按钮之後,会控制父元件中的parentsMsg
使文字有大小变化。
template
插入我们在data
的属性parentsMsg
内容为'Hello, is parentsMsg'
,为控制目标。template
里加上按钮绑定监听事件,并以$emit()
方法,带上指定的自定义事件参数。template
绑定刚刚的自定义事件参数methods
增加方法handleSize
,每按一次按钮增加字体大小 5px,并在 data 里增加属性fontSize: 12,
预设值。template
的插入值parentsMsg
元素上绑定元素的字体大小,记得要加入字体单位px
<!-- 父元件的HTML -->
<div id="app">
<menu-item @enlarge-text="handleBiggerSize"></menu-item>
</div>
<script>
// 子元件 使用$emit()传递
Vue.component('menu-item',{
template: `
<div>
<div >{{parentsMsg}}</div>
<button @click="$emit('enlarge-text')">放大父元件中元素的字体大小</button>
</div>
`
})
// 父元件
const vm= new Vue({
el:'#app',
data:{
parentsMsg: 'Hello, is parentsMsg',
fontSize: 16,
},
methods:{
handleBiggerSize: function(){
// 字体变大
this.fontSize += 5
},
}
})
</script>
我们也可以直接在$emit()
里以第二个参数带值进去,就不需要每次去父元件的方法里修改。
子元件透过自定义事件向父元件传递讯息+带值
语法:<button v-on:click="$emit('enlarge-text',0.1)>Enlarge Text</button>
说明:一个子元件里的按钮,点击时会触发一个特定的方法$emit()
,并带上两个参数,第一参数为自定义的事件名称enlarge-text
,第二参数是值,个事件和值会直接传给父元件,所以父元件会去监听这个事件。
父元件中监听子元件的事件
接收语法:<menu-item v-on:enlarge-text+= $event"></menu-item>
说明:v-on:enlarge-text
为绑定事件名称,fontSize += $event
则为事件对应的处理逻辑会对应到子主件的绑定方法的第二参数值,$event
是固定的写法。
当按下子元件的模版template
里的按钮,会直接取到第二参数作为放大字体的增加单位。
实作范例效果:
<!-- 父元件的HTML -->
<div id="app">
<menu-item @minify-text="handleMinifySize($event)"></menu-item>
</div>
<script>
// 子元件 使用$emit()传递
Vue.component('menu-item',{
template: `
<div>
<div >{{parentsMsg}}</div>
<button @click="$emit('minify-text',5)">缩小父元件中元素的字体大小</button>
</div>
`
})
// 父元件
const vm= new Vue({
el:'#app',
data:{
parentsMsg: 'Hello, is parentsMsg',
fontSize: 16,
},
methods:{
handleMinifySize: function(value){
// 字体变大
this.fontSize -= value
}
}
})
</script>
每日一句法文有益身心:Je suis fatigué ! --> 者.虽.发踢给! --> 我好累啊!
<<: Processing - Day 27 数学好棒棒 第二篇章
>>: [Day 28] LeetCode - 387 First Unique Character in a String
正规化 缩小资料的呈现比例 可使数值呈现在一定的范围内 使我们在训练模型时,增加梯度下降的容易度并提...
目前设定的 Navbar 路由架构还算单纯,并且只有单层路径,但是当专案规模愈来愈大、功能类别拆分的...
create table usebool ( id int unsigned auto_increm...
上午:Python程序设计 延续上次的tkinter,制作Menu有下拉式选单的功能 import ...
String类提供了1.equals() 2. equalsIgnoreCase()方法来比较两个字...