vue(12)

目录

消息订阅与发布(pubsub)

 TodoList案例消息订阅与发布

nextTick


数据以形参的形式传递

消息订阅与发布(pubsub)

1.一种组件间通信的方式,用于任意组件间通信

2.使用步骤

1)安装pubsub:

npm i pubsub-js

2)引入

import pubsub from 'pubsub-js'

3)接收数据:A组件想接收数据,则在A组件中订阅消息,订阅的回调在A组件自身

methods(){
    demo(data){..........}
}
............
mounted(){
    this.pid=pubsub.subscribe('xxx',this.demo)
//订阅消息
}

4)提供数据:

pubsub.publish('xxx',数据)

5.最好在beforeDestory钩子中,用pubsub.unsubscribe(pid) 去取消订阅

school.vue

<template>
  <div class="school">
    <h2>学校名称:{{ name }}</h2>
    <h2>学校地址:{{ address }}</h2>
  </div>
</template>

<script>
import pubsub from 'pubsub-js'

export default {
  name: "School",
  data() {
    return {
      name: "尚硅谷",
      address: "北京",
    }
  },
  methods:{
    demo(msgName,data){
      console.log('hello消息收到了',data,this);
    }
  },
  mounted(){
    // console.log('school',this);
    // this.$bus.$on('hello',(data)=>{
    //   console.log("我是school组件,收到了数据",data)
    // })
    
    // this.pubId=pubsub.subscribe('hello',(msgName,data)=>{
    //   console.log('有人发布了hello消息,hello消息的回调执行了',msgName,data);
    // })
    this.pubId=pubsub.subscribe('hello',this.demo)
  },
  beforeDestroy(){
    // this.$bus.$off('hello')
    pubsub.unsubscribe(this.pubId)
  },
}
</script>
<style scoped>
.school {
  background-color: skyblue;
  padding: 5px;
}
</style>

student.vue

<template>
  <div class="student">
    <h2>学生姓名:{{ name }}</h2>
    <h2>学生性别:{{ sex }}</h2>
    <button @click="sendStudentName">把学生名字给school组件</button>
  </div>
</template>

<script>
import pubsub from 'pubsub-js'
export default {
  name: "Student",
  data() {
    return {
      name: "张三",
      sex: "男"
    };
  },
  mounted(){
    // console.log('student',this.x);

  },
  methods:{
    sendStudentName(){
      // 触发事件
      // this.$bus.$emit('hello',this.name)
      pubsub.publish('hello',666)
    }
  }

};
</script>
<style lang="less" scoped>
.student {
  background-color: pink;
  padding: 5px;
  margin-top: 30px;
}
</style>

 TodoList案例消息订阅与发布

需要数据的地方订阅消息,提供数据的地方发布消息

nextTick

语法:

this.$nextTick(回调函数)

作用:在下一次DOM更新结束后执行其指定的回调

什么时候用:当噶便数据后,要基于更新后的新DOM进行某些操作时,要在nextTick所指定的回调函数中执行

myitem.vue

<template>
  <li>
    <label>
      <input
        type="checkbox"
        :checked="todo.done"
        @change="handleCheck(todo.id)"
      />
      <span v-show="!todo.isEdit">{{ todo.title }}</span>
      <input
        v-show="todo.isEdit"
        type="text"
        :value="todo.title"
        @blur="handleBlur(todo, $event)"
        ref="inputTitle"
      />
    </label>

    <button class="btn btn-danger" @click="handleDelete(todo.id)">删除</button>
    <button
      v-show="!todo.isEdit"
      class="btn btn-edit"
      @click="handleEdit(todo)"
    >
      编辑
    </button>
  </li>
</template>

<script>
import pubsub from "pubsub-js";
export default {
  name: "MyItem",
  // 声明接收todo对象
  props: ["todo"],
  methods: {
    // 勾选、取消勾选
    handleCheck(id) {
      // console.log(id);
      // 通知App组件将对应的todo对象的done取反,数据在哪里,操作对象的数据在哪里
      // this.checkTodo(id);
      this.$bus.$emit("checkTodo", id);
    },
    // 删除数据
    handleDelete(id) {
      // 根据用户的反应来确定是否进行
      if (confirm("确定删除吗?")) {
        // deleteTodo是父组件的函数名
        // this.deleteTodo(id)
        // console.log(id);

        // 借助全局事件总线,自定义事件的事件名
        // this.$bus.$emit('deleteTodo',id)

        // 订阅消息的消息名
        pubsub.publish("deleteTodo", id);
      }
    },
    // 编辑,目的是为了使文字变成输入框
    handleEdit(todo) {
      if (todo.hasOwnProperty("isEdit")) {
        todo.isEdit = true;
      } else {
        console.log("todo身上没有isEdit");
        this.$set(todo, "isEdit", true);
      }
      // nextTick(下一轮)所指定的回调会在dom节点更新之后再执行
      this.$nextTick(function () {
        this.$refs.inputTitle.focus();
      });
      // 把文字变成输入框后,就让输入框获取焦点
      // 但是这句代码不能实现,是因为
      // 这样只能生硬的添加属性,不能使页面发声改变
      //  todo.isEdit=true
    },
    // 失去焦点回调(真正执行修改逻辑)
    handleBlur(todo, e) {
      todo.isEdit = false;
      // console.log('updateTodo',todo.id,e.target.value);
      // 判断它输入是否为空
      if (!e.target.value.trim()) return alert("输入不能为空");
      this.$bus.$emit("updateTodo", todo.id, e.target.value);
    },
  },
};
</script>

<style>
/* item */
li {
  list-style: none;
  height: 36px;
  line-height: 36px;
  padding: 0 5px;
  border-bottom: 1px solid #ddd;
}
li label {
  float: left;
  cursor: pointer;
}

li label li input {
  vertical-align: middle;
  margin-right: 6px;
  position: relative;
  top: -1px;
}

li button {
  float: right;
  display: none;
  margin-top: 3px;
}
li:before {
  content: initial;
}
li:last-child {
  border-bottom: none;
}

li:hover {
  background-color: #ddd;
}
li:hover button {
  display: block;
}
</style>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值