2022-08-18

vue中組件之間的通信


組件可以有以下幾種關(guān)系:

[圖片上傳失敗...(image-8918e-1660823023573)]

A-B、B-C质况、B-D都是父子關(guān)系

C-D是兄弟關(guān)系

A-C结榄、A-D是隔代關(guān)系

不同使用場景囤捻,如何選擇有效的通信方式 ?vue組件中通信的幾種方式 视哑?

1. props ★★

2. $emit/$on ★★ 事件總線

3. vuex ★★★

4.$parent/$children

5. $attrs/$listeners

6. provide/inject ★★★

vue中組件之間通信挡毅?

常見使用場景可以分為三類:

  • 父子組件通信
  • 兄弟組件通信
  • 跨層組件通信
  1. 分幾種
  2. 使用
  3. 選用

最后說一下在項目中怎么選用:比如我們我們項目中只是涉及到簡單的數(shù)據(jù)數(shù)據(jù)傳遞選擇props跪呈,其次如果項目中需要保存狀態(tài)的時候選用vuex等等,只是說一個簡單例子庆械!

方法一、props

父組件A通過props向子組件B傳遞值沐序, B組件傳遞A組件通過$emitA組件通過v-on/@觸發(fā)

1-1 父組件=>子組件傳值

// 父組件
<template>
    <div id="app">
        <Child v-bind:child="users"></Child> //前者自定義名稱便于子組件調(diào)用策幼,后者要傳遞數(shù)據(jù)名
    </div>
</template>
<script>
    import Child from "./components/Child" //子組件
    export default {
        name: 'App',
        data(){
            return{
              users:["Eric","Andy","Sai"]
            }
        },
        components:{
            "Child":Child
        }
    }
</script>
// 子組件
<template>
    <div class="hello">
        <ul>
            <li v-for="item in child">{{ item }}</li> //遍歷傳遞過來的值渲染頁面
        </ul>
    </div>
</template>
<script>
    export default {
        name: 'Hello World',
        props:{
            child:{           //這個就是父組件中子標簽自定義名字
              type:Array,     //對傳遞過來的值進行校驗
              required:true   //必添
            }
          }
    }
</script>

總結(jié):父組件通過props向下傳遞數(shù)據(jù)給子組件特姐。

1-2子組件=>父組件傳值

// 子組件 Header.vue
<template>
  <div>
    <h1 @click="changeTitle">{{ title }}</h1> //綁定一個點擊事件
  </div>
</template>
<script>
    export default {
      name: 'header',
      data() {
        return {
          title:"Vue.js Demo"
        }
      },
      methods:{
        changeTitle() {
          this.$emit("titleChanged","子向父組件傳值"); //自定義事件  傳遞值“子向父組件傳值”
        }
      }
    }
</script>
// 父組件
<template>
  <div id="app">
    <header v-on:titleChanged="updateTitle"></header>
    //與子組件titleChanged自定義事件保持一致
   // updateTitle($event)接受傳遞過來的文字
    <h2>{{ title }}</h2>
  </div>
</template>
<script>
import Header from "./components/Header"
    export default {
      name: 'App',
      data(){
        return{
          title:"傳遞的是一個值"
        }
      },
      methods:{
        updateTitle(e){   //聲明這個函數(shù)
          this.title = e;
        }
      },
      components:{
       "app-header":Header,
      }
    }
</script>

總結(jié):子組件通過events給父組件發(fā)送消息唐含,實際上就是子組件把自己的數(shù)據(jù)發(fā)送到父組件捷枯。

方法二专执、$emit/$on => $bus

vue實例 作為事件總線(事件中心)用來觸發(fā)事件和監(jiān)聽事件,可以通過此種方式進行組件間通信包括:父子組件攀痊、兄弟組件苟径、跨級組件

例:

創(chuàng)建bus文件

import Vue from 'vue'

export defult new Vue()
// gg組件
<template id="a">
  <div>
    <h3>gg組件</h3>
    <button @click="sendMsg">將數(shù)據(jù)發(fā)送給dd組件</button>
  </div>
</template>
<script>
import bus from './bus'
export default {
    methods: {
        sendMsg(){
            bus.$emit('sendTitle','傳遞的值')
        }
    }
}
</script>
// dd組件
<template>
    <div>
        接收gg傳遞過來的值:{{msg}}
    </div>
</template>
<script>
import bus from './bus'
export default {
    data(){
        return {
            mag: ''
        }
    }
    mounted(){
        bus.$on('sendTitle',(val)=>{
            this.mag = val
        })
    }
}
</script>

方法三棘街、vuex

[圖片上傳失敗...(image-97ac67-1660823023573)]

1-1 vuex介紹

Vuex實現(xiàn)了一個單向數(shù)據(jù)流盒件,在全局擁有一個State存放數(shù)據(jù),當組件要更改State中的數(shù)據(jù)時恩沽,必須通過Mutation提交修改信息罗心,Mutation同時提供了訂閱者模式供外部插件調(diào)用獲取State數(shù)據(jù)的更新。

而當所有異步操作(常見于調(diào)用后端接口異步獲取更新數(shù)據(jù))或批量的同步操作需要走Action渤闷,但Action也是無法直接修改State的飒箭,還是需要通過Mutation來修改State的數(shù)據(jù)。最后肩碟,根據(jù)State的變化凸椿,渲染到視圖上脑漫。

1-2 vuex中核心概念

  • statevuex的唯一數(shù)據(jù)源,如果獲取多個state,可以使用...mapState吨拍。
    export const store = new Vuex.Store({   
    // 注意Store的S大寫
    <!-- 狀態(tài)儲存 -->
       state: {
            productList: [
               {
               name: 'goods 1',
               price: 100
                   
               }
           ]
       }
    })
    
  • getter: 可以將getter理解為計算屬性密末,getter的返回值根據(jù)他的依賴緩存起來跛璧,依賴發(fā)生變化才會被重新計算新啼。
    import Vue from 'vue'
    import Vuex from 'vuex';
    Vue.use(Vuex)
    
    export const store = new Vuex.Store({ 
        state: {
            productList: [
                {
                name: 'goods 1',
                price: 100
                },
            ]
        },
        // 輔助對象 mapGetter
        getters: {
            getSaledPrice: (state) => {
                let saleProduct = state.productList.map((item) => {
                    return {
                        name: '**' + item.name + '**',
                        price: item.price / 2
                    }
                })
                return saleProduct;
            }
        }
    })
    
    // 獲取getter計算后的值
    export default {
        data () {
            return {
                productList : this.$store.getters.getSaledPrice 
            }
        }
    }
    
  • mutation:更改vuexstate中唯一的方是提交mutation都有一個字符串和一個回調(diào)函數(shù)燥撞。回調(diào)函數(shù)就是使勁進行狀態(tài)修改的地方色洞。并且會接收state作為第一個參數(shù)payload為第二個參數(shù)火诸,payload為自定義函數(shù)荠察,mutation必須是同步函數(shù)奈搜。
    // 輔助對象 mapMutations
    mutations: {
        <!-- payload 為自定義函數(shù)名-->
        reducePrice: (state, payload) => {
            return state.productList.forEach((product) => {
                product.price -= payload;
            })
        }
    }
    
    <!-- 頁面使用 -->
    methods: {
        reducePrice(){
            this.$store.commit('reducePrice', 4)
        }
    }
    
  • actionaction類似mutation都是修改狀態(tài)馋吗,不同之處,

    action提交的mutation不是直接修改狀態(tài)
    action可以包含異步操作宏粤,而mutation不行
    action中的回調(diào)函數(shù)第一個參數(shù)是context灼卢,是一個與store實例具有相同屬性的方法的對象
    action通過store.dispatch觸發(fā),mutation通過store.commit提交
    actions: { // 提交的是mutation蛇摸,可以包含異步操作 reducePriceAsync: (context, payload) => { setTimeout(()=> { context.commit('reducePrice', payload); // reducePrice為上一步mutation中的屬性 },2000) } }
    // 輔助對象 mapActions methods: { reducePriceAsync(){ this.$store.dispatch('reducePriceAsync', 2) }, }

  • module:由于是使用單一狀態(tài)樹赶袄,應(yīng)用的所有狀態(tài)集中到比較大的對象抠藕,當應(yīng)用變得非常復(fù)雜是,store對象就有可能變得相當臃腫敬辣。為了解決以上問題溉跃,vuex允許我們將store分割成模塊告抄,每個模塊擁有自己的state,mutation,action,getter,甚至是嵌套子模塊從上至下進行同樣方式分割。
    const moduleA = {
        state: {...},
        mutations: {...},
        actions: {...},
        getters: {...}
    }
    const moduleB = {
        state: {...},
        mutations: {...},
        actions: {...},
        getters: {...}
    }
    const store = new Vuex.Store({
        a: moduleA,
        b: moduleB
    })
    store.state.a
    store.state.b
    

1-3 vuex中數(shù)據(jù)存儲 localStorage

vuexvue 的狀態(tài)管理器龄糊,存儲的數(shù)據(jù)是響應(yīng)式的炫惩。但是并不會保存起來阿浓,刷新之后就回到了初始狀態(tài),具體做法應(yīng)該在vuex里數(shù)據(jù)改變的時候把數(shù)據(jù)拷貝一份保存到localStorage里面爸舒,刷新之后,如果localStorage里有保存的數(shù)據(jù)鹊奖,取出來再替換store里的state忠聚。

例:

let defaultCity = "上海"
try {    
// 用戶關(guān)閉了本地存儲功能唱捣,此時在外層加個try...catch
  if (!defaultCity){
  // f復(fù)制一份
        defaultCity = JSON.parse(window.localStorage.getItem('defaultCity'))
        }
    }catch(e){
        console.log(e)
    }
export default new Vuex.Store({
  state: {
    city: defaultCity
  },
  mutations: {
    changeCity(state, city) {
      state.city = city
      try {
      window.localStorage.setItem('defaultCity', JSON.stringify(state.city));
      // 數(shù)據(jù)改變的時候把數(shù)據(jù)拷貝一份保存到localStorage里面
      } catch (e) {}
    }
  }
})

注意:vuex里震缭,保存的狀態(tài),都是數(shù)組党涕,而localStorage只支持字符串巡社,所以需要用JSON轉(zhuǎn)換:

JSON.stringify(state.subscribeList)<font color="red">// array -> string</font>
JSON.parse(window.localStorage.getItem("subscribeList"))<font color="red">// string -> array</font>

方法四、$attr/$listeners

1-1 簡介

多級組件嵌套需要傳遞數(shù)據(jù)時肥荔,通常使用的方法是通過vuex燕耿。但如果僅僅是傳遞數(shù)據(jù)潜圃,而不做中間處理舟茶,使用 vuex 處理,未免有點大材小用隧出。為此Vue2.4 版本提供了另一種方法----$attrs/$listeners

  • $attrs:包含了父作用域中不被 prop 所識別 (且獲取) 的特性綁定 (class 和 style 除外)阀捅。當一個組件沒有聲明任何 prop 時,這里會包含所有父作用域的綁定 (class 和 style 除外)圆雁,并且可以通過 v-bind="$attrs" 傳入內(nèi)部組件帆谍。通常配合 interitAttrs 選項一起使用。
  • $listeners:包含了父作用域中的 (不含 .native 修飾器的) v-on 事件監(jiān)聽器烈涮。它可以通過 v-on="$listeners" 傳入內(nèi)部組件

例:

// index.vue
<template>
  <div>
    <h2>王者峽谷</h2>
    <child-com1 :foo="foo" :boo="boo" :coo="coo" :doo="doo" title="前端工匠"></child-com1>
  </div>
</template>
<script>
    const childCom1 = () => import("./childCom1.vue");
    export default {
      components: { childCom1 },
      data() {
        return {
          foo: "Javascript",
          boo: "Html",
          coo: "CSS",
          doo: "Vue"
        };
      }
    };
</script>
//childCom1.vue
<template class="border">
  <div>
    <p>foo: {{ foo }}</p>
    <p>childCom1的$attrs: {{ $attrs }}</p>
    <child-com2 v-bind="$attrs"></child-com2>
  </div>
</template>
<script>
    const childCom2 = () => import("./childCom2.vue");
    export default {
      components: {
        childCom2
      },
      inheritAttrs: false, // 可以關(guān)閉自動掛載到組件根元素上的沒有在props聲明的屬性
      props: {
        foo: String // foo作為props屬性綁定
      },
      created() {
        console.log(this.$attrs); 
        // { "boo": "Html", "coo": "CSS", "doo": "Vue", "title": "前端工匠" }
      }
    };
</script>
// childCom2.vue
<template>
  <div class="border">
    <p>boo: {{ boo }}</p>
    <p>childCom2: {{ $attrs }}</p>
    <child-com3 v-bind="$attrs"></child-com3>
  </div>
</template>
<script>
const childCom3 = () => import("./childCom3.vue");
export default {
  components: {
    childCom3
  },
  inheritAttrs: false,
  props: {
    boo: String
  },
  created() {
    console.log(this.$attrs); 
    // {"coo": "CSS", "doo": "Vue", "title": "前端工匠" }
  }
};
</script>
// childCom3.vue
<template>
  <div class="border">
    <p>childCom3: {{ $attrs }}</p>
  </div>
</template>
<script>
    export default {
      props: {
        coo: String,
        title: String
      }
    };
</script>

所示$attrs表示沒有繼承數(shù)據(jù)的對象坚洽,格式為{屬性名:屬性值}讶舰。Vue2.4提供了$attrs , $listeners 來傳遞數(shù)據(jù)與事件需了,跨級組件之間的通訊變得更簡單援所。

簡單來說:$attrs與$listeners 是兩個對象,$attrs 里存放的是父組件中綁定的非 Props 屬性挪略,$listeners里存放的是父組件中綁定的非原生事件滔岳。

方法五、provide/inject

1-1 簡介

Vue2.2.0新增API,這對選項需要一起使用摊求,以允許一個祖先組件向其所有子孫后代注入一個依賴刘离,不論組件層次有多深,并在起上下游關(guān)系成立的時間里始終生效茧痕。一言而蔽之:祖先組件中通過provider來提供變量恼除,然后在子孫組件中通過inject來注入變量。

provide / inject API 主要解決了跨級組件間的通信問題令野,不過它的使用場景气破,主要是子組件獲取上級組件的狀態(tài),跨級組件間建立了一種主動提供與依賴注入的關(guān)系狗超。

例:

//a.vue
export default {
    provide: {
        name: '王者峽谷' //這種綁定是不可響應(yīng)的
    }
}
// b.vue
export default {
    inject: ['name'],
    mounted () {
        console.log(this.name) //輸出王者峽谷
    }
}

A.vue朴下,我們設(shè)置了一個 provide:name,值為王者峽谷渗稍,將name這個變量提供給它的所有子組件团滥。

B.vue ,通過 inject 注入了從A組件中提供的name變量拱燃,組件B中力惯,直接通過this.name訪問這個變量了。

這就是 provide / inject API 最核心的用法哮缺。

需要注意的是:provide 和inject綁定并不是可響應(yīng)的尝苇。這是刻意為之的埠胖。然而,如果你傳入了一個可監(jiān)聽的對象诵冒,那么其對象的屬性還是可響應(yīng)的----vue官方文檔,所以谊惭,上面 A.vue 的 name 如果改變了圈盔,B.vue 的 this.name 是不會改變的。

1-2 provide與inject 怎么實現(xiàn)數(shù)據(jù)響應(yīng)式

兩種方法:

1-2-1

  • provide祖先組件的實例铁蹈,然后在子孫組件中注入依賴众眨,這樣就可以在子孫組件中直接修改祖先組件的實例的屬性,不過這種方法有個缺點就是這個實例上掛載很多沒有必要的東西比如props沿腰,methods

1-2-2

  • 使用2.6最新API Vue.observable 優(yōu)化響應(yīng)式 provide(推薦)

例:

組件D颂龙、E和F獲取A組件傳遞過來的color值纽什,并能實現(xiàn)數(shù)據(jù)響應(yīng)式變化,即A組件的color變化后企巢,組件D让蕾、E、F會跟著變(核心代碼如下:)

[圖片上傳失敗...(image-2af63-1660823023573)]

// A 組件 
<div>
      <h1>A 組件</h1>
      <button @click="() => changeColor()">改變color</button>
      <ChildrenB />
      <ChildrenC />
</div>
......
  data() {
    return {
      color: "blue"
    };
  },
  // provide() {
  //   return {
  //     theme: {
  //       color: this.color //這種方式綁定的數(shù)據(jù)并不是可響應(yīng)的
  //     } // 即A組件的color變化后罗丰,組件D再姑、E、F不會跟著變
  //   };
  // },
  provide() {
    return {
      theme: this//方法一:提供祖先組件的實例
    };
  },
  methods: {
    changeColor(color) {
      if (color) {
        this.color = color;
      } else {
        this.color = this.color === "blue" ? "red" : "blue";
      }
    }
  }
  // 方法二:使用2.6最新API Vue.observable 優(yōu)化響應(yīng)式 provide
  // provide() {
  //   this.theme = Vue.observable({
  //     color: "blue"
  //   });
  //   return {
  //     theme: this.theme
  //   };
  // },
  // methods: {
  //   changeColor(color) {
  //     if (color) {
  //       this.theme.color = color;
  //     } else {
  //       this.theme.color = this.theme.color === "blue" ? "red" : "blue";
  //     }
  //   }
  // }
// F 組件 
<template functional>
<div class="border2">
  <h3 :style="{ color: injections.theme.color }">F 組件</h3>
</div>
</template>
<script>
export default {
inject: {
  theme: {
    //函數(shù)式組件取值不一樣
    default: () => ({})
  }
}
};
</script>

注:provide 和 inject主要為高階插件/組件庫提供用例,能在業(yè)務(wù)中熟練運用栖疑,可以達到事半功倍的效果!

方法六卿闹、$parent / $children與 ref

  • ref:如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素锻霎;如果用在子組件上,引用就指向組件實例
  • $parent / $children:訪問父 / 子實例

注意:這兩種都是直接得到組件實例吏口,使用后可以直接調(diào)用組件的方法或訪問數(shù)據(jù)冰更。我們先來看個用 ref來訪問組件的

例:

export default {
  data () {
    return {
      title: 'Vue.js'
    }
  },
  methods: {
    sayHello () {
      window.alert('Hello');
    }
  }
}
<template>
  <component-a ref="comA"></component-a>
</template>
<script>
  export default {
    mounted () {
      const comA = this.$refs.comA;
      console.log(comA.title);  // Vue.js
      comA.sayHello();  // 彈窗
    }
  }
</script>

注:這兩種方法的弊端是蜀细,無法在跨級或兄弟間通信。

我們想在 component-a 中深滚,訪問到引用它的頁面中(這里就是 parent.vue)的兩個 component-b 組件涣觉,那這種情況下,就得配置額外的插件或工具了生兆,比如 Vuex 和 Bus 的解決方案膝宁。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市合蔽,隨后出現(xiàn)的幾起案子介返,更是在濱河造成了極大的恐慌,老刑警劉巖刃宵,帶你破解...
    沈念sama閱讀 219,110評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件牲证,死亡現(xiàn)場離奇詭異十厢,居然都是意外死亡键闺,警方通過查閱死者的電腦和手機澈驼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,443評論 3 395
  • 文/潘曉璐 我一進店門缝其,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人榴都,你說我怎么就攤上這事∽旄撸” “怎么了和屎?”我有些...
    開封第一講書人閱讀 165,474評論 0 356
  • 文/不壞的土叔 我叫張陵柴信,是天一觀的道長。 經(jīng)常有香客問我潜沦,道長绪氛,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,881評論 1 295
  • 正文 為了忘掉前任争占,我火速辦了婚禮询件,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘刻蟹。我一直安慰自己嘿辟,他們只是感情好片效,可當我...
    茶點故事閱讀 67,902評論 6 392
  • 文/花漫 我一把揭開白布淀衣。 她就那樣靜靜地躺著膨桥,像睡著了一般。 火紅的嫁衣襯著肌膚如雪只嚣。 梳的紋絲不亂的頭發(fā)上艺沼,一...
    開封第一講書人閱讀 51,698評論 1 305
  • 那天障般,我揣著相機與錄音,去河邊找鬼藐石。 笑死徐伐,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的办素。 我是一名探鬼主播,決...
    沈念sama閱讀 40,418評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼勺三,長吁一口氣:“原來是場噩夢啊……” “哼吗坚!你這毒婦竟也來了呆万?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,332評論 0 276
  • 序言:老撾萬榮一對情侶失蹤牡彻,失蹤者是張志新(化名)和其女友劉穎出爹,沒想到半個月后缎除,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體器罐,經(jīng)...
    沈念sama閱讀 45,796評論 1 316
  • 正文 獨居荒郊野嶺守林人離奇死亡渐行,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,968評論 3 337
  • 正文 我和宋清朗相戀三年殊轴,在試婚紗的時候發(fā)現(xiàn)自己被綠了袒炉。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,110評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡孽文,死狀恐怖夺艰,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情减牺,我是刑警寧澤,帶...
    沈念sama閱讀 35,792評論 5 346
  • 正文 年R本政府宣布拔疚,位于F島的核電站既荚,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏句各。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,455評論 3 331
  • 文/蒙蒙 一凿宾、第九天 我趴在偏房一處隱蔽的房頂上張望初厚。 院中可真熱鬧遍略,春花似錦骤坐、人聲如沸下愈。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,003評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽履因。三九已至,卻和暖如春站故,著一層夾襖步出監(jiān)牢的瞬間毅舆,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,130評論 1 272
  • 我被黑心中介騙來泰國打工岂津, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留悦即,地道東北人。 一個月前我還...
    沈念sama閱讀 48,348評論 3 373
  • 正文 我出身青樓粱甫,卻偏偏與公主長得像冗美,于是被迫代替她去往敵國和親屎蜓。 傳聞我的和親對象是個殘疾皇子仅财,可洞房花燭夜當晚...
    茶點故事閱讀 45,047評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 組件可以有以下幾種關(guān)系: A-B安拟、B-C糠赦、B-D都是父子關(guān)系 C-D是兄弟關(guān)系 A-C、A-D是隔代關(guān)系 不同使用...
    cesiuming閱讀 347評論 0 0
  • Vue2.0 傳值方式: 在Vue的框架開發(fā)的項目過程中淌山,經(jīng)常會用到組件來管理不同的功能顾瞻,有一些公共的組件會被提取...
    陀飛輪h閱讀 378評論 0 0
  • 前言 組件是 vue.js最強大的功能之一,而組件實例的作用域是相互獨立的退渗,這就意味著不同組件之間的數(shù)據(jù)無法相互引...
    用技術(shù)改變世界閱讀 2,167評論 1 3
  • vue中組件之間的通信 組件可以有以下幾種關(guān)系: A-B会油、B-C、B-D都是父子關(guān)系 C-D是兄弟關(guān)系 A-C翻翩、A...
    葉落疑秋閱讀 106評論 0 2
  • 摘要: 總有一款合適的通信方式喇潘。 作者:浪里行舟 Fundebug經(jīng)授權(quán)轉(zhuǎn)載,版權(quán)歸原作者所有。 前言 組件是 v...
    Fundebug閱讀 15,574評論 3 57