目录
数据以形参的形式传递
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
- <div class="school">
- <h2>学校名称:{{ name }}h2>
- <h2>学校地址:{{ address }}h2>
- div>
-
- <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
- <div class="student">
- <h2>学生姓名:{{ name }}h2>
- <h2>学生性别:{{ sex }}h2>
- <button @click="sendStudentName">把学生名字给school组件button>
- div>
-
- <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>
需要数据的地方订阅消息,提供数据的地方发布消息
语法:
this.$nextTick(回调函数)
作用:在下一次DOM更新结束后执行其指定的回调
什么时候用:当噶便数据后,要基于更新后的新DOM进行某些操作时,要在nextTick所指定的回调函数中执行
myitem.vue
- <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>
-
- <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>