跟禹神学vue--总结
1 父组件给子组件传递参数--props传参
(1)父组件中准备好数据
data() {return {todos:[{id:'001',title:'01',done:true},{id:'002',title:'02',done:false},{id:'003',title:'03',done:true}]}
}
(2)父组件中引入子组件(import + components),并传递参数
<template><div id="root"><div class="todo-container"><div class="todo-wrap"><MyList :todos="todos"/></div></div></div>
</template><script>import MyList from './components/MyList'export default {name:'App',components:{MyList},}
</script>
(3)子组件声明父组件传递的参数并接收使用
<template><ul class="todo-main"><MyItem // 直接使用todosv-for="todoObj in todos":key="todoObj.id" :todo="todoObj" /></ul>
</template><script>export default {name:'MyList',//声明接收父组件传递过来的数据props:['todos']}
</script>
2 子组件给父组件传递参数--props传参
(1)父组件中定义一个参数,回调留在父组件中
methods: {//添加一个todo(子传父)addTodo(todoObj){// 数组开头放一个this.todos.unshift(todoObj)},
}
(2)父组件给子组件传递函数,供子组件调用并传参数
<template><div id="root"><div class="todo-container"><div class="todo-wrap"><MyHeader :addTodo="addTodo"/></div></div></div>
</template>
(3)子组件声明接收并调用
//接收从App传递过来的addTodo
props:['addTodo'],
<template><div class="todo-header"><input type="text" placeholder="请输入你的任务名称,按回车键确认" v-model="title" @keyup.enter="add"/></div>
</template>// add方法
add(){//校验数据if(!this.title.trim()) return alert('输入不能为空')//将用户的输入包装成一个todo对象const todoObj = {id:nanoid(),title:this.title,done:false}//通知App组件去添加一个todo对象this.addTodo(todoObj)//清空输入this.title = ''}
},
3、子组件给父组件传参--自定义事件
(1)子组件定义一个事件,通过this.$emit传给父组件
add() {//校验数据if (!this.title.trim()) return alert("输入不能为空");//将用户的输入包装成一个todo对象const todoObj = { id: nanoid(), title: this.title, done: false };//通知App组件去添加一个todo对象//this.addTodo(todoObj)//换成子给父传递数据,触发事件this.$emit("addTodo", todoObj);//清空输入this.title = "";
},
<template><div class="todo-header"><inputtype="text"placeholder="请输入你的任务名称,按回车键确认"v-model="title"@keyup.enter="add"/></div>
</template>
(2)父组件绑定子组件的自定义事件
绑定事件的方式:
方式一:v-on:自定义事件
方式二:@自定义事件
自定义事件实现方式一
<template><div id="root"><div class="todo-container"><div class="todo-wrap"><!-- 修改为自定义事件 --><MyHeader @addTodo="addTodo" /></div></div></div>
</template>
//添加一个todo
addTodo(todoObj) {this.todos.unshift(todoObj);
},
自定义事件实现方式二
<template><div id="root"><div class="todo-container"><div class="todo-wrap"><!-- 修改为自定义事件 --><MyHeader ref="acceptAddTodo" /></div></div></div>
</template>methods:{//添加一个todo
addTodo(todoObj) {this.todos.unshift(todoObj);},
}mounted({this.$refs.acceptAddTodo.$on('addTodo',this.addTodo)}
4、任意组件之间传参--全局事件总线
(1)main.js全局安装事件总线
//创建vm
new Vue({el:'#app',render: h => h(App),beforeCreate() {Vue.prototype.$bus = this}
})
(2)接收方:接收的回调,并使用发送方传递过来的参数
//勾选or取消勾选一个todo
checkTodo(id) {this.todos.forEach((todo) => {if (todo.id === id) todo.done = !todo.done;});
},
//删除一个todo
deleteTodo(id) {this.todos = this.todos.filter((todo) => todo.id !== id);
},
(3)接收方:通过this.$bus.$on(事件名,参数)接收参数,在mounted中声明接收
mounted() {/*全局事件总线接受MyIterm的参数*/this.$bus.$on('checkTodo',this.checkTodo)this.$bus.$on('deleteTodo',this.deleteTodo)},
(3)接收方:使用参数之后,在beforeDestroy中解绑事件
beforeDestroy() {this.$off('checkTodo')this.$off('deleteTodo')}
(4)发送方:通过this.$bus.$emit(事件名,参数)发送数据
methods: {//勾选or取消勾选handleCheck(id){//通知App组件将对应的todo对象的done值取反this.$bus.$emit('checkTodo',id)},//删除handleDelete(id){if(confirm('确定删除吗?')){//通知App组件将对应的todo对象删除// this.deleteTodo(id)this.$bus.$emit('deleteTodo',id)}}
},
5、任意组件之间传参--消息订阅与发布
(1)安装pubsub-js ,并导入
npm i pubsub-jsimport PubSub from "pubsub-js";
(2)订阅方(接收方),通过pubsub的subscribe方法接收参数
methods:{// deleteTodo(msgName,id) 消息订阅与发送 不需要的数据拿_代表deleteTodo(_, id) {this.todos = this.todos.filter((todo) => todo.id !== id);},
},
mounted() {// 消息订阅与发送this.pubId = PubSub.subscribe.$on("deleteTodo", this.deleteTodo);},
(3)订阅方(接收方),取消订阅
beforeDestroy() {// 消息订阅与发送PubSub.unsubscribe.$on(this.pubId);
},
(4)发布方(发送方),发布消息
<button class="btn btn-danger" @click="handleDelete(todo.id)">删除</button>//删除
handleDelete(id) {if (confirm("确定删除吗?")) {//消息订阅与发送--发送方PubSub.publish("deleteTodo", id);}
},