子组件和父组件之间优雅通信---松耦合

1、传统的写法

js 复制代码
// 父组件
<!-- 父组件 -->
<template>
  <ChildComponent 
    @tabActiveFn="onTabActiveUpdate"
  />
  <button @click="goOrder"></button>
</template>

<script>
export default {
  methods: {
    refresh() {
      console.log('刷新数据');
    },
    onTabActiveUpdate(newValue) {
      this.tabActive = newValue;
      this.refresh();
    },
     goOrder(){
        this.$router.replace({ name: 'order' });
    },
  }
}
</script>
js 复制代码
// 子组件
<!-- 子组件 -->
<template v-for="(item, index) in TAB">
  <span :key="index" :class="[tabActive === item.index ? 'active' : 'tab']" @click="changeTab(item)"> {{ item.name }}</span>
  <button @click="goOrder"></button>
</template>

<script>
export default {
data() {
    return {
      tabActive: 1,
      TAB: [
        { index: 1, name: 'xxx服务' },
        { index: 2, name: 'xxx服务' }
      ],
  },
  methods: {
    changeTab(item) {
      this.$emit('tabActiveFn', item.index);
      this.tabActive = item.index;
    },
     goOrder(){
        this.$router.replace({ name: 'order' });
    },
  }
}
</script>

2、使用语法糖

  • (1)父组件定义一个万能方法onInvoke(action) { this[action]?.(); },根据传入的字符串调用对应方法。
  • (2)父组件通过自定义事件@invokeFn<ChildComponent @invokeFn="onInvoke"/>暴露给子组件。
  • (3)子组件<button @click="$emit('invokeFn', 'goOrder')"></button>,点击时,触发父组件invokeFn事件并传值goOrder
  • (4)父组件收到事件,执行onInvoke('goOrder'),最终安全调用goOrder方法。
js 复制代码
// 父组件
<!-- 父组件 -->
<template>
  <ChildComponent 
    @tabActiveFn="onTabActiveUpdate"
    @invokeFn="onInvoke"
  />
</template>

<script>
export default {
  methods: {
    refresh() {
      // 刷新数据
      console.log('刷新数据');
    },
    onTabActiveUpdate(newValue) {
      this.tabActive = newValue;
      this.refresh();
    },
    goOrder(){
        this.$router.replace({ name: 'order' });
    },
    onInvoke(action) {
      this[action]?.();
    },
  }
}
</script>
js 复制代码
// 子组件
<!-- 子组件 -->
<template v-for="(item, index) in TAB">
  <span :key="index" :class="[tabActive === item.index ? 'active' : 'tab']" @click="changeTab(item)"> {{ item.name }}</span>
  <button @click="$emit('invokeFn', 'goOrder')"></button>
</template>

<script>
export default {
data() {
    return {
      tabActive: 1,
      TAB: [
        { index: 1, name: 'xxx服务' },
        { index: 2, name: 'xxx服务' }
      ],
  },
  methods: {
    changeTab(item) {
      this.$emit('tabActiveFn', item.index);
      this.tabActive = item.index;
    }
  }
}
</script>

其中,this.[action],使用方括号语法,动态的访问当前对象(this)上名为action变量值的属性或者方法。例如:action是'goOrder',它就试图获取this.goOrder

?()是可选链操作符函数 的结合,如果this.[action]的值不是null或者undefined,则调用该函数;如果是,则整个表达式短路,返回undefined,而不会抛出错误。

可选链?.是ES2020中引入的一个非常实用的语法。它的核心价值是在于防止在访问嵌套属性或者方法时,因中间某个值为null或者undefined而导致运行时错误

优点:松耦合,子组件完全不需要知道父组件具体有哪些方法,它只需要知道自己需要触发什么指令。父组件则负责接收指令并执行对应的逻辑,这使得子组件的复用性非常高,可以轻松被不同父组件使用,只要这些父组件都实现了相应的指令并监听了对应的事件即可。

相关推荐
IT_陈寒28 分钟前
Redis缓存击穿把我整不会了,原来还有这手操作
前端·人工智能·后端
idcu1 小时前
深入 Lyt.js 组件系统:L2 渲染引擎层的核心
前端·typescript
这是程序猿1 小时前
Spring Boot自动配置详解
java·大数据·前端
文心快码BaiduComate1 小时前
干货|Comate Harness Engineering工程实践指南
前端·后端·程序员
还有多久拿退休金1 小时前
一张栈的图,治好你面试答不出 script 阻塞的病
前端·javascript
光辉GuangHui1 小时前
Agent Skill 也需要测试:如何搭建 Skill 评估框架
前端·后端·llm
To_OC1 小时前
我终于搞懂 Claude Code 核心逻辑!90%的人都用错了模式
前端·ai编程
蓝宝石的傻话1 小时前
Headless浏览器的隐形陷阱:为什么你的AI自动化工具抓不到页面早期错误?
前端
irving同学462381 小时前
Node 后端实战:JWT 认证与生产级错误处理
前端·后端
莽夫搞战术2 小时前
【Google Stitch】AI原生画布重新定义设计,让想法变成可交互界面
前端·人工智能·ui