Vue通讯

  1. v-model 与 props
  2. provide 与 inject 依赖注入
  3. v-on 与 $emit
  4. eventBus 事件监听 ($root $emit $on 发布-订阅模式)
  5. $refs、$parent 与 $children
  6. $attrs 与 $listeners
  7. Vuex 状态管理

以下主要对上述几种组件间通信方式进行演示使用。

一、v-model 与 props

父组件 —data–> 子组件

1.父组件

<template>
    <sgh-button :label="label" />
</template>
<script>
export default {
    data(){
        return {
            label: "来点我啊"
        }
    }
}
</script>

2.子组件

<template>
    <button>{{label}}</button>
</template>
<script>
export default {
    props:{
        label:{
            type: String,
            default: ''
        }
    }
}
</script>

二、 provide 与 inject 依赖注入

父组件 —data–> 所有后代组件

v2-b3953ba1cc10268ca5b2c88be1aa76ee_1440w.webp

1.父组件

<template>
  <div class="about">
    <h1>This is an about page</h1>
    <hello-world></hello-world>
  </div>
</template>
<script>
import HelloWorld from "@/components/HelloWorld.vue";
export default {
  components: {
    HelloWorld,
  },
  // provide 注入后代组件
  provide() {
    return {
      label: "来打我呀",
    };
  },
};
</script>

2.子组件

<template>
  <div class="hello">
    {{ label }}
  </div>
</template>

<script>
export default {
  name: "HelloWorld",
  // inject 接收
  inject: ["label"],
};
</script>

三、 v-on 与 $emit

子组件 —data–> 父组件

v2-5d971a23a7258880a587dd01f6b30a7f_1440w.webp

1.父组件

<template>
  <div class="about">
    {{ label }}
    <sgh-input @change-label="changeLabel"></sgh-input>
  </div>
</template>
<script>
import SghInput from "@/components/sgh-input.vue";
export default {
  components: {
    SghInput,
  },
  data() {
    return {
      label: "Welcome",
    };
  },
  provide() {
    return {
      label: this.label,
    };
  },
  methods: {
    changeLabel(label) {
      this.label = label;
    },
  },
};
</script>

2.子组件

<template>
  <div class="sgh-input">
    <input type="text" v-model="label" @change="change" />
    {{ label }}
  </div>
</template>

<script>
export default {
  name: "SghInput",
  inject: ["label"],
  methods: {
    change(e) {
      this.$emit("change-label", e.target.value);
    },
  },
};
</script>

四、eventBus 事件监听 ($root $emit $on 发布-订阅模式)

主要用于非父子组件数据交互

  1. 创建 src/EventBus.js
import Vue from 'vue'

const EventBus = new Vue();

export default EventBus;

2. $root 定义 data src/main.js

new Vue({
  router,
  store,
  render: h => h(App),
  data() {
    return {
      EventBus,         // EventBus
    };
  },
}).$mount('#app')

3. 编写测试兄弟组件数据交互的父组件 src/views/About.vue

<template>
  <div class="about">
    <sgh-input />
    <sgh-button />
  </div>
</template>
<script>
import SghInput from "@/components/sgh-input.vue";
import SghButton from "@/components/sgh-button.vue";
export default {
  components: {
    SghInput,
    SghButton,
  },
};
</script>

4. src/components/sgh-button.vue

<template>
  <div class="sgh-button">
    <button @click="increment">+1</button>
  </div>
</template>

<script>
export default {
  name: "SghButton",
  data() {
    return {
      number: 0,
    };
  },
  methods: {
    // 发布事件
    increment() {
      this.$root.EventBus.$emit("eventName", ++this.number);            
    },
  },
};
</script>

5. src/components/sgh-input.vue

<template>
  <div class="sgh-input">
    <input type="text" v-model="number" />
  </div>
</template>

<script>
export default {
  name: "SghInput",
  data() {
    return {
      number: 0,
    };
  },
  mounted() {
    // 订阅事件
    this.$root.EventBus.$on("eventName", (val) => {
      this.number = val;
    });
  },
};
</script>

五、$refs$parent 与 $children

在 三 的基础上试验

<sgh-input @change-label="changeLabel" ref="ipt"></sgh-input>
v2-05b78307b1994583f24c7be1f54c1f04_1440w.webp
mounted() {
  console.log(this.$refs);          
  console.log(this.$refs.ipt.change);
},

$parent 可取到直接父组件,$children 可取到子组件(数组)。

六、$attrs 与 $listeners

  • $attrs :包含了父作用域中不作为 prop 被识别 (且获取) 的 attribute 绑定 (classstyle除外)。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (classstyle除外),并且可以通过v-bind="$attrs"传入内部组件——在创建高级别的组件时非常有用。
  • $listeners :包含了父作用域中的 (不含.native修饰器的)v-on事件监听器。它可以通过v-on="$listeners"传入内部组件——在创建更高层次的组件时非常有用。

七、Vuex

v2-9ae264ef035447a1438aebdbe535a944_1440w.webp

1.展示 src/store/index.js

vue3.x

import { createStore } from 'vuex'

export default createStore({
  state: {},
  mutations: {},
  actions: {},
  modules: {},
  getters: {}
})

vue2.x

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {},
  mutations: {},
  actions: {},
  modules: {},
  getters: {}
})

2.说明

  • $store.state :可获取状态对象;
  • $store.commit :同步,提交到 mutations (普通的数据缓存);
  • $store.dispatch :异步,提交到 actions (可用于请求数据);
  • mutationsactions 里面定义方法,state 里面定义数据;
  • gettersstate 对象读取方法,读取方式 $store.getters 调用方法读取;

转载于https://zhuanlan.zhihu.com/p/393649359

© 版权声明
THE END
喜欢就支持一下吧
点赞4095打赏 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容