vue组件之间共享数据

本文介绍了一个Vue Element UI项目中如何优化工单详情数据在多个子组件间的共享,以避免重复调用接口。通过在父组件`index.vue`中统一获取并更新`orderDetails`数据,然后将该数据作为属性绑定到`A.vue`、`B.vue`和`C.vue`三个子组件上,实现了仅调用一次接口即可同步所有页面的数据。此外,还展示了如何通过事件监听在父组件中更新数据并传递给子组件。
摘要由CSDN通过智能技术生成

一、概述

先来看一下页面

现有一个首页inde.vue,是加载有3个tab,分别是工单处理A.vue,工单报价B.vue,工单回单C.vue。

这3个tab是不同的vue文件,需要共享一个工单详情orderDetails数据。这个数据从后端api请求接口获取。

简单的做法是,A,B,C这3个页面都去调用接口。那么这样的话,加载首页时,接口会被调用3次,浪费资源。

有没有可能只调用一次接口,就可以让3个页面获取呢?答案是可以的。

二、测试

新建好vue ElementUI项目之后,在views目录下创建文件夹Tab,目录结构如下:

Tab/
├── details
│   ├── A.vue
│   ├── B.vue
│   └── C.vue
└── index.vue

index.vue

<template>
  <div>
    <el-tabs v-model="activeName" type="card" closable @tab-click="handleClick">
      <el-tab-pane
        v-for="(item, index) in tabs"
        :key="index"
        :label="item"
        :name="item"
      >
        <A ref="A" @children="updateOrder" v-show="tabIndex==0" :orderDetails="orderDetails"></A>
        <B ref="B" @children="updateOrder" v-show="tabIndex==1" :orderDetails="orderDetails"></B>
        <C ref="C" @children="updateOrder" v-show="tabIndex==2" :orderDetails="orderDetails"></C>
      </el-tab-pane>
    </el-tabs>
    <div style="height: 10px"></div>
    <button @click="testUpate">更改数据</button>
  </div>
</template>
<script>
  import A from './details/A'
  import B from './details/B'
  import C from './details/C'
  export default {
    name: "index",
    components: {
      A,
      B,
      C,
    },
    data() {
      return {
        tabIndex:0,  // 当前点击的index
        orderDetails:{}, // 工单详情
        // tab展示菜单
        tabs: ['工单处理', '工单报价', '工单回单'],
        activeName:"工单处理"
      };
    },
    mounted() {
      this.getOrderDetails()
    },
    methods: {
      handleClick(tab, event) {
        // console.log("handleClick",this.editableTabsValue)
        // console.log(tab, event);
        this.tabIndex = tab.index
      },
      updateOrder(){
        this.getOrderDetails()
      },
      // 获取工单详情
      getOrderDetails(){
        this.orderDetails={
          id: 1,
          process: '创建工单',
          status: 1,
          desc: '已创建工单【202109162058】',
          operate: '小张',
          createTime: '2021/09/16 20:58:52'
        }
      },
      // 测试更改数据
      testUpate(){
        this.orderDetails={
          id: 2,
          process: '分派工单',
          status: 2,
          desc: '已分派工单给小王【12345678910】',
          operate: '小张',
          createTime: '2021/09/16 21:58:52'
        }
      }
    }
  };
</script>
View Code

A.vue

<template>
  <div>
    <div>组件A,详情:</div>
    <div>{{orderDetails}}</div>
  </div>
</template>

<script>
  export default {
    name: "A",
    props:{
      orderDetails:{
        type:Object,
        default:{}
      }
    },
  }
</script>

<style scoped>

</style>
View Code

B.vue

<template>
  <div>
    <div>组件B,详情:</div>
    <div>{{orderDetails}}</div>
  </div>
</template>

<script>
  export default {
    name: "B",
    props:{
      orderDetails:{
        type:Object,
        default:{}
      }
    },
  }
</script>

<style scoped>

</style>
View Code

C.vue

<template>
  <div>
    <div>组件C,详情:</div>
    <div>{{orderDetails}}</div>
  </div>
</template>

<script>
  export default {
    name: "C",
    props:{
      orderDetails:{
        type:Object,
        default:{}
      }
    },
  }
</script>

<style scoped>

</style>
View Code

代码解释:

先来看index.vue

<A ref="A" @children="updateOrder" v-show="tabIndex==0" :orderDetails="orderDetails"></A>

由于父组件index需要调用子组件A,因此使用children调用updateOrder方法。这个方法用来请求后端api接口。注意:只需要在父组件中调用接口即可,子组件不需要调用接口。

再来看:orderDetails="orderDetails",表示绑定属性orderDetails

A.vue

这里需要定义传值的类型,使用prop关键字,这里的定义的orderDetails是一个对象。

总结:

由于在index,分别为组件A,B,C绑定了orderDetails。因此在index中变更orderDetails的值,那么其他页面,也会随之变动。

Vue中,父组件之间可以通过props和$emit来实现数据共享。 1. 使用props传递数据: 父组件可以通过props属性将数据传递给组件。在组件中,可以通过props选项接收父组件传递的数据,并在组件中使用。 ```vue // 父组件 <template> <div> <child-component :message="message"></child-component> </div> </template> <script> import ChildComponent from './ChildComponent.vue'; export default { components: { ChildComponent }, data() { return { message: 'Hello from parent component' }; } }; </script> // 组件 <template> <div> <p>{{ message }}</p> </div> </template> <script> export default { props: ['message'] }; </script> ``` 2. 使用$emit触发事件: 组件可以通过$emit方法触发一个自定义事件,并将数据作为参数传递给父组件。在父组件中,可以通过监听组件触发的事件来获取组件传递的数据。 ```vue // 父组件 <template> <div> <child-component @message-updated="updateMessage"></child-component> <p>{{ message }}</p> </div> </template> <script> import ChildComponent from './ChildComponent.vue'; export default { components: { ChildComponent }, data() { return { message: '' }; }, methods: { updateMessage(newMessage) { this.message = newMessage; } } }; </script> // 组件 <template> <div> <button @click="sendMessage">Send Message</button> </div> </template> <script> export default { methods: { sendMessage() { this.$emit('message-updated', 'Hello from child component'); } } }; </script> ``` 这样,父组件就可以通过props接收组件传递的数据组件也可以通过$emit触发事件将数据传递给父组件
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值