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