Vue 元件通信
- 前言
- 一、父元件與子元件通信
- 二、子元件與父元件通信
- 三、其他元件通信
前言
Vue 是單頁面應用,頁面與頁面之間,功能與功能之間,都是一個個的元件構成。元件也有層級結構,父與子關系,子與父關系,兄弟關系等。那麼有關系的元件之間如何通信?将是本文探讨的主題。
一、父元件與子元件通信
父元件向子元件傳值直接通過屬性的方式,子元件通過 props 接收。
父元件調用子元件方法是通過給子元件綁定 ref 擷取子元件執行個體。随後找到子元件的方法并調用。
父元件 TodoList.vue
<template>
<div>
<div>
<input type="text" v-model="text"><button @click="add">添加待辦</button>
<todo-item
:taskList="taskList"
ref="item"
/>
<button @click="del">删除包含完成的事項</button>
</div>
</div>
</template>
<script>
import TodoItem from './TodoItem.vue';
export default {
name: 'TodoList',
data () {
return {
text:"",
taskList:[]
}
},
components: {
'todo-item': TodoItem,
},
methods: {
add(){
this.taskList.push({text:this.text})
},
del(){
//通過ref綁定子元件執行個體,直接調用其方法
this.taskList = this.$refs.item.del(this.taskList,'完成');
}
}
}
</script>
子元件 TodoItem.vue
<template>
<div>
<div v-for="(item,index) in taskList">
<span>{{item.text}}</span>
</div>
</div>
</template>
<script>
export default {
name: 'TodoItem',
props:['taskList'],
methods: {
//子元件方法,供父元件調用
del(arr,str){
return arr.filter((item)=>item.text.indexOf(str)<0)
}
}
}
</script>
二、子元件與父元件通信
子元件與父元件通信有 2 種方法。
-
子元件通過 props 擷取父元件的方法,并向父元件傳參。
父元件 TodoList.vue
<template>
<div>
<div>
<button @click="show">顯示清單</button>
<todo-item
:taskList="taskList"
:isShow="isShow"
:del="del"
/>
<div>{{tip}}</div>
</div>
</div>
</template>
<script>
import TodoItem from './TodoItem.vue';
export default {
name: 'TodoList',
data () {
return {
isShow:false,
tip:'未删除',
taskList:[{text:"完成國際會議",done:true},{text:"還未開始國内會議",done:false}]
}
},
components: {
'todo-item': TodoItem,
},
methods: {
show(){
this.isShow = !this.isShow
},
del(str){
this.tip = str;
//通過ref綁定子元件,直接調用其方法
this.taskList = this.taskList.filter((item)=>item.done)
}
}
}
</script>
子元件 TodoItem.vue
<template>
<div v-if="isShow">
<div v-for="(item,index) in taskList" >
<span>{{item.text}}</span>
</div>
<button @click="del('删除成功')">删除完成的事項</button>
</div>
</template>
<script>
export default {
name: 'TodoItem',
props:['taskList','isShow','del']
}
</script>
-
子元件通過觸發 $emit 調取父元件的方法,并向父元件傳參。
父元件 TodoList.vue
<template>
<div>
<div>
<button @click="show">顯示清單</button>
<todo-item
:taskList="taskList"
:isShow="isShow"
@on-all="del"
/>
<div>{{tip}}</div>
</div>
</div>
</template>
<script>
import TodoItem from './TodoItem.vue';
export default {
name: 'TodoList',
data () {
return {
isShow:false,
tip:'未删除',
taskList:[{text:"完成國際會議",done:true},{text:"還未開始國内會議",done:false}]
}
},
components: {
'todo-item': TodoItem,
},
methods: {
show(){
this.isShow = !this.isShow
},
del(str){
this.tip = str;
//通過ref綁定子元件,直接調用其方法
this.taskList = this.taskList.filter((item)=>item.done)
}
}
}
</script>
子元件 TodoItem.vue
<template>
<div v-if="isShow">
<div v-for="(item,index) in taskList" >
<span>{{item.text}}</span>
</div>
<button @click="del">删除完成的事項</button>
</div>
</template>
<script>
export default {
name: 'TodoItem',
props:['taskList','isShow'],
methods: {
//通過$emit觸發父元件方法,給父元件傳參
del(){
this.$emit('on-all','删除成功');
}
}
}
</script>
- 差別
通過 props 方式簡寫:
Father 元件
<template>
<div>
<son :del="del">
</div>
<template>
export default {
name: 'Father',
method:{
del(){
console.log("這是父元件的方法");
}
}
}
Son 元件
<template>
<div @click = "del"></div>
<template>
export default {
name: 'Son',
props:['del'],
}
通過 $emit 方式簡寫:
Father 元件
<template>
<div>
<son @on-del="del">
</div>
<template>
export default {
name: 'Father',
method:{
del(){
console.log("這是父元件的方法");
}
}
}
Son 元件
<template>
<div @click = "$emit('on-del')"></div>
<template>
export default {
name: 'Son',
}
三、其他元件通信
其他元件通信可使用 Vuex 狀态管理工具。其核心思想是将所有狀态集中管理,一處有變動。其他地方同步更新。可參考 Vuex 使用指南。