组件间共三种传参路径:父-子、子-父、兄弟之间
注意:框架中操作数组不能用下标,只能用数组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')