Vue组件传

跟禹神学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);
  }
},
相关推荐
.生产的驴6 分钟前
SpringBoot 消息队列RabbitMQ 消息确认机制确保消息发送成功和失败 生产者确认
java·javascript·spring boot·后端·rabbitmq·负载均衡·java-rabbitmq
布瑞泽的童话20 分钟前
无需切换平台?TuneFree如何搜罗所有你爱的音乐
前端·vue.js·后端·开源
白鹭凡33 分钟前
react 甘特图之旅
前端·react.js·甘特图
2401_8628867837 分钟前
蓝禾,汤臣倍健,三七互娱,得物,顺丰,快手,游卡,oppo,康冠科技,途游游戏,埃科光电25秋招内推
前端·c++·python·算法·游戏
书中自有妍如玉44 分钟前
layui时间选择器选择周 日月季度年
前端·javascript·layui
Riesenzahn1 小时前
canvas生成图片有没有跨域问题?如果有如何解决?
前端·javascript
f8979070701 小时前
layui 可以使点击图片放大
前端·javascript·layui
小贵子的博客1 小时前
ElementUI 用span-method实现循环el-table组件的合并行功能
javascript·vue.js·elementui
明似水1 小时前
掌握 Flutter 中的 `Overlay` 和 `OverlayEntry`:弹窗管理的艺术
javascript·flutter