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);
  }
},
相关推荐
也无晴也无风雨32 分钟前
深入剖析输入URL按下回车,浏览器做了什么
前端·后端·计算机网络
Martin -Tang1 小时前
Vue 3 中,ref 和 reactive的区别
前端·javascript·vue.js
FakeOccupational3 小时前
nodejs 020: React语法规则 props和state
前端·javascript·react.js
放逐者-保持本心,方可放逐3 小时前
react 组件应用
开发语言·前端·javascript·react.js·前端框架
曹天骄4 小时前
next中服务端组件共享接口数据
前端·javascript·react.js
阮少年、4 小时前
java后台生成模拟聊天截图并返回给前端
java·开发语言·前端
郝晨妤5 小时前
鸿蒙ArkTS和TS有什么区别?
前端·javascript·typescript·鸿蒙
AvatarGiser6 小时前
《ElementPlus 与 ElementUI 差异集合》Icon 图标 More 差异说明
前端·vue.js·elementui
喝旺仔la6 小时前
vue的样式知识点
前端·javascript·vue.js
别忘了微笑_cuicui6 小时前
elementUI中2个日期组件实现开始时间、结束时间(禁用日期面板、控制开始时间不能超过结束时间的时分秒)实现方案
前端·javascript·elementui