组件间共三种传参路径:父-子、子-父、兄弟之间
注意:框架中操作数组不能用下标,只能用数组API
1 父-子
父子间传值也遵循按值传递:如果直接想控制父元素的数组内容,则可以直接通过操作数组的地址来修改数组的元素
父组件用 :子组件接收的变量名=“父组件的变量名” 向子组件发送变量,
子组件在<script>内的<script>内用props:[子组件接收的变量名]接住父组件传下来的变量
2 子-父
子组件内:如删除当前表项,但是函数是在父组件内的,所以需要把当前的表项索引在调用删除函数时传给父组件,让父组件实现删除当前表项的功能(使用this.$emit("父组件函数",参数...))
父组件:在使用子组件时,同时绑定一个自己的删除函数,将自己的函数传给子组件
3 兄弟之间
使用一个new Vue()对象作为中介
脚手架中操作:在main.js同级目录下创建一个bus.js(导出一个new Vue对象),在main.js引入bus,并将bus添加到所有组件的原型对象当中。
数据的接收方,在自己加载完成后,向公交车(new Vue()上添加一个自定义的事件)
数据的发送方,在自己的事件处理函数中,找到公共的bus对象,用$emit()触发别人提前在bus(中介)上绑定好的事件,并传参
四个组件间关系如下:

具体代码如下:
todo.vue
<template>
<div>
<h1>待办事件列表</h1>
<todo-add></todo-add>
<todo-list></todo-list>
</div>
</template>
<script>
import todoAdd from './todo-add'
import todoList from './todo-list'
export default {
components:{todoAdd,todoList}
}
</script>
todo-add.vue
<template>
<div>
<h1>待办事件列表</h1>
<todo-add></todo-add>
<todo-list></todo-list>
</div>
</template>
<script>
import todoAdd from './todo-add'
import todoList from './todo-list'
export default {
components:{todoAdd,todoList}
}
</script>
todo-list.vue
<template>
<ul>
<todo-item v-for="(task,i) of tasks" :key="i" :i="i" @del="del" :task="task">
<!-- <template是父组件的卡片,向子组件的slot插槽放> 在运行时,就被插入到孩子提前准备的插槽中显示-->
<template slot="task">{{task}}</template>
</todo-item>
</ul>
</template>
<script>
import todoItem from "./todo-item"
export default {
data(){
return{
tasks:['唱','跳','RAP']
}
},
methods:{
del(i){
this.tasks.splice(i,1);
},
add(task){
this.tasks.push(task);
}
},
components:{todoItem},
created(){
// 回调函数绑定一个处理函数,处理函数前面是什么都没有的
// 由于回调函数的this指向window,所以用bind使this指向当前对象
this.bus.$on(/*自定义事件名*/"add",/*自己的函数*/this.add.bind(this));
}
}
</script>
todo-item.vue
<template>
<li>
{{i+1}} - <slot name="task"></slot>
<button @click="del">x</button>
</li>
</template>
<script>
export default {
props:['i'],
methods:{
del(){
if(confirm(`是否继续删除第${this.i+1}项任务`)) this.$emit("del",this.i);
}
}
}
</script>
main.js同级的bus.js
import Vue from 'vue' export default new Vue
main.js
import Vue from 'vue' import App from './App.vue' import router from './router' import store from './store' import bus from './bus'
//将bus添加到Vue的原型对象中 Vue.prototype.bus=bus; Vue.config.productionTip = false new Vue({ router, store, render: h => h(App) }).$mount('#app')