vue組件之間共享數據

一、概述

先來看一下頁面

現有一個首頁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的值,那麼其他頁面,也會隨之變動。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章