Vue3 通用组件的使用&父子组件间交互__项目实践总结

717 阅读2分钟

全局组件的挂载使用

通常我们会挂载一些全局使用的组件如按业务二次封装的文本溢出时显示的tooltips

1.在main.ts 引入组件

import TooltipSpan from '@/components/tooltip-span.vue';

2.挂载组件

app.component('tooltip-span', TooltipSpan);

3.在需要使用的组件中直接用

 <tooltip-span content="提示语句"> </tooltip-span>

其他业务组件的使用与封装

1.在UI图评审后是否有可以封装的组件(已开发大屏为例)

  • 1-1.模块盒子组件可进行封装,对于特殊内容留出插槽,便于后期编写后过程中对组件进行改造。
  • 1-2.card轮播,数据滚动组件等样式的组件直接封装,开放对应的参数传入即可。
  • 1-3.一些公用的业务组件也可以封装,留出参数入口,和抛出必要的参数和方法。
组件交互
- 1.组件的几种通信在下面文章中已经记录

https://juejin.cn/post/7083470631919943693

不再赘述,这里就重点记录下,在此次项目中使用较多的方式

1.provide 和 inject

常用于抛出父组件定义和操作的变量,子组件只注入使用

//父组件 import {provide} from 'vue'
setup() {
provide("name", "沐华")
}

//子组件 import {inject } from 'vue' 

setup() { let name=inject('name') }
return{
name
}


- 2.使用ref 调用子组件的方法时
  • 2.1在非语法糖的写法
// 父组件
<template>
<div>
 父页面
<son-com ref="sonRef"/>
<button @click="handleClick">test</button>
</div>
</template>
<script>
import {
defineComponent,
ref,
} from 'vue';
export default defineComponent({
const sonRef = ref(null);
const handleClick = () => {
tableFilterDemoRef.value.song();
}
setup(){
return {
sonRef,
handleClick,
}
}
})
</script> 

// 子组件
<template>
<div>
子页面
</div>
</template>
<script>
import {
defineComponent
} from 'vue';
export default defineComponent({
const song = () => {
alert('hellor world');
}
setup(){
return {
song, // 别忘记 return
}
}
})
</script> 

  • 2.2在语法糖组件中写法是需要暴露子组件的宏
//子组件多了使用编译宏一步暴露方法或属性
defineExpose({
  song
})
//父组件
tableFilterDemoRef.value.song();


- 3.子组件使用emit

3.1非语法糖操作如下

  //context.emit("helloEmit", "hello")

setup (props, context) {
      function helloEmit () {
      context.emit("helloEmit", "hello")
     }

      return {
       helloEmit
    }
}

};

3.2语法糖中操作也是需要暴露定义emits

//子组件
let emits. = defineEmits(['helloEmit', ....])
emits('helloEmit',"hello")

3.Vuex & EventBus

在大型项目中父子组件,或兄弟组件的交互可选Vuex进行全局变量管理或是EventBus

3.1 Vuex

的声明state, mutations,actions 的方式大致和vue2一致; store定义时和使用时需要引入


import { createStore } from 'vuex' //定义时引入

import { useStore } from 'vuex' //使用时引入

定义store

import { createStore } from 'vuex' 
export default createStore({
  state: {
    cont: 0
  },
  mutations: {
    watchRouterPath(state, arr) {
      state.cont++
      console.log(arr);
    }
  },
  actions: {
  },
  modules: {
  }
})

使用store

import { useStore } from 'vuex'
const store = useStore()
store.commit('watchRouterPath', arr);
3.2 EventBus

Vue3.0已经移除了$on ,$off ``$emit这几个事件API,不再用事件去触发应用实例,所以需要通过第三方插件来实现EventBus,如mitt (opens new window)或者 tiny-emitter (opens new window)

使用mitt

//引入插件
npm install --save mitt

定义一个Bus.ts文件;通过自定义一个 bus 对象,来挂载 mitt 的 API


import mitt from 'mitt'

const bus = {}


```js
// 初始化一个 mitt 实例
const emitter = mitt();

// 定义一个空对象用来承载我们的自定义方法
const bus: any = {};

// 把你要用到的方法添加到 bus 对象上
bus.$on = emitter.on;
bus.$emit = emitter.emit;

// 最终是暴露自己定义的 bus
export default bus;

这样我们在组件里就可以使用 bus.$on 、bus.$emit 来发布,订阅管理全局状态了;

在本次Vue3项目实践中使用到最多的父子组件交互方式就是emit,和ref调用子组件方法,在以后的实践中使用其他的交互方式也会对文章进行补充。