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);
  }
},
相关推荐
Pedantic1 小时前
SwiftUI 手势层级(Gesture Hierarchy)详解
前端
飘尘1 小时前
前端转型全栈(Java后端)的快速上手指引
前端·后端·全栈
一颗烂土豆2 小时前
Meshopt 压缩深度解析,为什么它比 Draco 更快
前端·javascript·webgl
浏览器工程师3 小时前
AI Agent 接浏览器任务,先别让它一路点到底
前端·后端
雨季mo浅忆3 小时前
VSCode自动格式化三要素
前端
爱勇宝3 小时前
深扒 Anthropic 1680 位工程师简历:应届生几乎没机会,AI 公司最缺的不是博士
前端·后端·程序员
kyriewen4 小时前
同事每天催我 Code Review,我写了个脚本让 AI 替我 review PR——现在他反过来催 AI 了
前端·javascript·ai编程
user20585561518136 小时前
Windows 项目安装时报 `node-sass` 错误,如何快速处理
前端
LiaCode6 小时前
Redis 在生产项目的使用
前端·后端