成人怡红院-成人怡红院视频在线观看-成人影视大全-成人影院203nnxyz-美女毛片在线看-美女免费黄

站長資訊網
最全最豐富的資訊網站

vue指令怎么實現組件通信

vue指令實現組件通信的方法:1、父組件通過“props”的方式向子組件傳遞數據,而通過“$emit”子組件可以向父組件通信;2、通過“ref/$refs”屬性實現組件通信;3、通過eventBus事件總線實現組件通信;4、使用Vuex實現組件通信;5、通過“$attrs”與“$listeners”實現組件通信等。

vue指令怎么實現組件通信

本教程操作環境:Windows10系統、Vue 3版、DELL G3電腦

vue指令怎么實現組件通信?

Vue實現組件間通信的七種方式

1. props / $emit

父組件通過props的方式向子組件傳遞數據,而通過$emit 子組件可以向父組件通信:

  • 父傳子:父組件通過import引入子組件,并注冊,在子組件標簽上添加要傳遞的屬性,子組 件通過props接收,接收有兩種形式一是通過數組形式[‘要接收的屬性’ ],二是通過對象形式{ }
  • 子傳父:父組件向子組件傳遞事件方法,子組件通過$emit觸發事件,回調給父組件

props的特點:

  • props只能是父組件向子組件進行傳值,props使得父子組件之間形成一個單向的下行綁定。子組件的數據會隨著父組件的更新而響應式更新;但是子組件無法引起父組件的數據更新。
  • props可以顯示定義一個或一個以上的數據,對于接收的數據,可以是各種數據類型,同樣也可以是傳遞一個對象或函數。
  • props屬性名規則:若在props中使用駝峰形式,模板中標簽需要使用短橫線的形式來書寫。

代碼示例:

父傳子(prop的用法)

父組件:

<template>     <div id="father">         <son :msg="msg" :fn="myFunc"></son>     </div> </template>  <script> import son from "./son.vue"; export default {     name: "father",     components: {         son     },     data() {         msg: "我是父組件";     },     methods: {         myFunc() {             console.log("我是父組件的方法");         }     } }; </script>
登錄后復制

子組件:

<template>     <div id="son">         <p>{{msg}}</p>         <button @click="fn">按鈕</button>     </div> </template> <script> export default {     name: "son",     props: ["msg", "fn"] }; </script>
登錄后復制

子傳父($emit的用法)

$emit 綁定一個自定義事件,當這個事件被執行的時候就會將參數傳遞給父組件,而父組件通過v-on監聽并接收參數

父組件:

<template>   <div id="father">     <son :arrList="arrList" @changeIndex="changeIndex"></son>     <p>{{currentIndex}}</p>   </div> </template>  <script> import son from './son.vue' export default {   name: 'father',   components: { son},   data() {     return {       currentIndex: -1,       arrList: ['龍族', '繪梨衣', '前端','后端']     }   },   methods: {     changeIndex(index) {       this.currentIndex = index     }   } } </script>
登錄后復制

子組件:

<template>   <div>     <div v-for="(item, index) in arrList" :key="index" @click="emitIndex(index)">{{item}}</div>   </div> </template>  <script> export default {   props: ['arrList'],   methods: {     emitIndex(index) {       this.$emit('changeIndex', index) // 觸發父組件的方法,并傳遞參數index     }   } } </script>
登錄后復制

2.ref / $refs

ref:這個屬性用在子組件上,它的引用就指向了該子組件的實例,可以通過實例來訪問組件的數據和方法;如果在普通的 DOM 元素上使用,引用指向的就是 DOM元素

父組件:

<template>   <child ref="child"></component-a> </template> <script>   import child from './child.vue'   export default {     components: { child },     mounted () {       console.log(this.$refs.child.name);  // mySon       this.$refs.child.sayHello();  // Hello father!     }   } </script>
登錄后復制

子組件:

<template>   <div id="app"></div> </template> <script> export default {   name:'child',   data () {     return {       name: 'mySon'     }   },   methods: {     sayHello () {       console.log('Hello father!')     }   } } </script>
登錄后復制

3.eventBus(事件總線)

其原理就是:事件訂閱發布,eventBus 又稱為事件總線,在vue中可以使用它來作為溝通橋梁的概念, 就像是所有組件共用相同的事件中心,可以向該中心注冊發送事件或接收事件, 所以組件都可以通知其他組件。

使用步驟如下:

(1)創建事件中心管理組件之間的通信

// event-bus.js  import Vue from 'vue' export const EventBus = new Vue()
登錄后復制

(2)發送事件 假設有兩個兄弟組件firstCom和secondCom:

firstCom和secondCom的父組件:

<template>   <div>     <first-com></first-com>     <second-com></second-com>   </div> </template>  <script> import firstCom from './firstCom.vue' import secondCom from './secondCom.vue' export default {   components: { firstCom, secondCom } } </script>
登錄后復制

在firstCom組件中發送事件:

<template>   <div>     <button @click="add">點擊增加</button>       </div> </template>  <script> import {EventBus} from './event-bus.js' // 引入事件中心  export default {   data(){     return{       num:0     }   },   methods:{     add(){       EventBus.$emit('addition', {         num:this.num++       })     }   } } </script>
登錄后復制

(3)接收事件

在secondCom組件中接收事件:

<template>   <div>求和: {{count}}</div> </template>  <script> import { EventBus } from './event-bus.js' export default {   data() {     return {       count: 0     }   },   mounted() {     EventBus.$on('addition', param => {       this.count = this.count + param.num;     })   } } </script>
登錄后復制

在上述代碼中,這就相當于將num值存貯在了事件總線中,在其他組件中可以直接訪問。事件總線就相當于一個橋梁,不用組件通過它來通信。雖然看起來比較簡單,但是這種方法也有不變之處,如果項目過大,使用這種方式進行通信,后期維護起來會很困難。

4.Vuex

Vuex 是一個專為 Vue.js 應用程序開發的狀態管理模式。它采用集中式存儲管理應用的所有組件的狀態,并以相應的規則保證狀態以一種可預測的方式發生變化.

Vuex 解決了多個視圖依賴于同一狀態和來自不同視圖的行為需要變更同一狀態的問題,將開發者的精力聚焦于數據的更新而不是數據在組件之間的傳遞上

Vuex各個模塊:

  • state:用于數據的存儲,是store中的唯一數據源
  • getters:如vue中的計算屬性一樣,基于state數據的二次包裝,常用于數據的篩選和多個數據的相關性計算
  • mutations:類似函數,改變state數據的唯一途徑,且不能用于處理異步事件
  • actions:類似于mutation,用于提交mutation來改變狀態,而不直接變更狀態,可以包含任意異步操作
  • modules:類似于命名空間,用于項目中將各個模塊的狀態分開定義和操作,便于維護

Vuex使用步驟:

(1)這里我們先新建 store文件夾, 對Vuex進行一些封裝處理

在 store 文件夾下添加 index.js 文件

// index.js   // 自動掛載指定目錄下的store import Vue from 'vue' import Vuex from 'vuex'   Vue.use(Vuex)   let modules = {}   // @/store/module 目錄下的文件自動掛載為 store 模塊 const subModuleList = require.context('@/store/modules', false, /.js$/) subModuleList.keys().forEach(subRouter => {   const moduleName = subRouter.substring(2, subRouter.length - 3)   modules[moduleName] = subModuleList(subRouter).default }) //也可自己手動掛載(自行選擇)   export default new Vuex.Store({   state: {},   mutations: {},   actions: {},   modules })
登錄后復制

(2)在 store 文件夾下添加 module 文件夾,在module文件夾再新建 user.js 文件

// user.js   import user from '@/utils/user.js' import userApi from '@/apis/user' import { OPEN_ACCOUNT_STAGE, STAGE_STATUS } from '@/constant'   let getUserPromise = null   export default {   namespaced: true,   state() {     return {       userInfo: null, // 用戶信息       isLogined: !!user.getToken(), // 是否已經登錄     }   },   mutations: {     // 更新用戶信息     updateUser(state, payload) {       state.isLogined = !!payload       state.userInfo = payload     },   },   actions: {     // 獲取當前用戶信息      getUserInfo(context, payload) {       //相關代碼     },       // 登出      logout(context, payload = {}) {       // 是否手動退出       const { manual } = payload       if (manual) {         await userApi.postLogout()       }       user.clearToken()       context.commit('updateUser', null)     },   } }
登錄后復制

(3)然后在項目的 main.js 文件中引入

import Vue from 'vue' import App from '@/app.vue' import { router } from '@/router' import store from '@/store/index'   const vue = new Vue({   el: '#app',   name: 'root',   router,   store,   render: h => h(App), })
登錄后復制

(4)封裝很愉快結束了了,然后就正常操作即可

this.$store.state.user.isLogined this.$store.state.user.userInfo this.$store.commit('user/updateUser', {})  await this.$store.dispatch('user/logout', { manual: true })
登錄后復制

5.$attrs與 $listeners

現在我們來討論另一種情況:如果我們給出的組件關系圖中A組件與D組件是隔代關系, 那它們之前進行通信有哪些方式呢?

  1. 使用props綁定來進行一級一級的信息傳遞, 如果D組件中狀態改變需要傳遞數據給A, 使用事件系統一級級往上傳遞
  2. 使用eventBus,這種情況下還是比較適合使用, 但是碰到多人合作開發時, 代碼維護性較低, 可讀性也低
  3. 使用Vuex來進行數據管理, 但是如果僅僅是傳遞數據, 而不做中間處理,使用Vuex處理感覺有點大材小用了.

所以就有了 $attrs / $listeners ,通常配合 inheritAttrs 一起使用。

inheritAttrs

默認情況下父作用域的不被認作 props 的 attribute 綁定 (attribute bindings) 將會“回退”且作為普通的 HTML attribute 應用在子組件的根元素上。當撰寫包裹一個目標元素或另一個組件的組件時,這可能不會總是符合預期行為。

通過設置 inheritAttrs 到 false,這些默認行為將會被去掉。而通過實例 property $attrs 可以讓這些 attribute 生效,且可以通過 v-bind 顯性的綁定到非根元素上。

注意:這個選項不影響 class 和 style 綁定,Vue對class和style做了特殊處理

簡單來說就是

  • inheritAttrs:true 時繼承除props之外的所有屬性
  • inheritAttrs:false 只繼承class 和 style屬性
  • $attrs:包含了父作用域中不被認為 (且不預期為) props 的特性綁定 (class 和 style 除外),并且可以通過 v-bind="$attrs" 傳入內部組件。當一個組件沒有聲明任何 props 時,它包含所有父作用域的綁定 (class 和 style 除外)。
  • $listeners:包含了父作用域中的 (不含 .native 修飾符) v-on 事件監聽器。它可以通過 v-on="$listeners" 傳入內部組件。它是一個對象,里面包含了作用在這個組件上的所有事件監聽器,相當于子組件繼承了父組件的事件。

代碼示例:

父組件:

<template>    <child :name="name" :age="age" :infoObj="infoObj" @updateInfo="updateInfo" @delInfo="delInfo" /> </template> <script>     import Child from '../components/child.vue'     export default {         name: 'father',         components: { Child },         data () {             return {                 name: '繪梨衣',                 age: 22,                 infoObj: {                     from: '河北',                     job: 'superman',                     hobby: ['reading', 'writing', 'eating']                 }             }         },         methods: {             updateInfo() {                 console.log('update info');             },             delInfo() {                 console.log('delete info');             }         }     } </script>
登錄后復制

兒子組件:

<template>     <!-- 通過 $listeners 將父作用域中的事件,傳入 grandSon 組件,使其可以獲取到 father 中的事件 -->     <grand-son :height="height" :weight="weight" @addInfo="addInfo" v-bind="$attrs" v-on="$listeners"  /> </template> <script>     import GrandSon from '../components/grandSon.vue'     export default {         name: 'child',         components: { GrandSon },         props: ['name'],         data() {           return {               height: '170cm',               weight: '55kg'           };         },         created() {             console.log(this.$attrs);         // 結果:age, infoObj, 因為父組件共傳來name, age, infoObj三個值,由              //于name被 props接收了,所以只有age, infoObj屬性             console.log(this.$listeners); // updateInfo: f, delInfo: f         },         methods: {             addInfo () {                 console.log('add info')             }         }     } </script>
登錄后復制

孫子組件:

<template>     <div>         {{ $attrs }} --- {{ $listeners }}     <div> </template> <script>     export default {         props: ['weight'],         created() {             console.log(this.$attrs); // age, infoObj, height              console.log(this.$listeners)            // updateInfo: f, delInfo: f, addInfo: f             this.$emit('updateInfo')            // 可以觸發 father 組件中的updateInfo函數         }     } </script>
登錄后復制

6.$parent / $children

  • 使用$parent可以讓組件訪問父組件的實例(訪問的是上一級父組件的屬性和方法)。
  • 使用 $children 可以讓組件訪問子組件的實例,但是, $children 并不能保證順序,并且訪問的數據也不是響應式的。

注意:

  • 通過 $parent 訪問到的是上一級父組件的實例,可以使用 $root 來訪問根組件的實例
  • 在組件中使用$children拿到的是所有的子組件的實例,它是一個數組,并且是無序的
  • 在根組件 #app 上拿 $parent 得到的是 new Vue()的實例,在這實例上再拿 $parent 得到的是undefined,而在最底層的子組件拿 $children 是個空數組
  • $children 的值是數組,而 $parent是個對象

用法:

子組件:

<template>   <div>     <span>{{message}}</span>     <p>父組件的值為:  {{parentVal}}</p>   </div> </template>  <script> export default {   data() {     return {       message: 'Vue'     }   },   computed:{     parentVal(){       return this.$parent.msg;     }   } } </script>
登錄后復制

父組件:

<template>   <div class="app">     <div>{{msg}}</div>     <child></child>     <button @click="change">點擊改變子組件值</button>   </div> </template>  <script> import child from './child.vue' export default {   components: { child },   data() {     return {       msg: 'Hello'     }   },   methods: {     change() {       // 獲取到子組件       this.$children[0].message = 'JavaScript'     }   } } </script>
登錄后復制

7.依賴注入(provide / inject)

這種方式就是vue中依賴注入,該方法用于 父子組件之間 的通信。當然這里所說的父子不一定是真正的父子,也可以是祖孫組件,在層數很深的情況下,可以使用這種方式來進行傳值。就不用一層一層的傳遞數據了。

provide和inject是vue提供的兩個鉤子,和data、methods是同級的。并且provide的書寫形式和data一樣。

  • provide 鉤子用來發送數據或方法
  • inject鉤子用來接收數據或方法

注意: 依賴注入所提供的屬性是非響應式的。

用法:

父組件:

provide() {      return {              num: this.num       }; }
登錄后復制

子組件:

inject: ['num']
登錄后復制

還有另一種寫法,這種寫法可以訪問父組件中的所有屬性:

provide() {  return {     app: this   }; } data() {  return {     num: 111   }; }  inject: ['app'] console.log(this.app.num)
登錄后復制

總結

1.父子組件間通信

  • 子組件通過 props 屬性來接受父組件的數據,然后父組件在子組件上注冊監聽事件,子組件通過 emit 觸發事件來向父組件發送數據。
  • 通過 ref 屬性給子組件設置一個名字。父組件通過 $refs 組件名來獲得子組件,子組件通過 $parent 獲得父組件,這樣也可以實現通信。
  • 使用 provide/inject,在父組件中通過 provide提供變量,在子組件中通過 inject 來將變量注入到組件中。不論子組件有多深,只要調用了 inject 那么就可以注入 provide中的數據

2.跨代組件間通信

跨代組件間通信其實就是多層的父子組件通信,同樣可以使用上述父子組件間通信的方法,只不過需要多層通信會比較麻煩。

3.兄弟組件間通信

通過 $parent + $refs 以父組件為中間人來獲取到兄弟組件,也可以進行通信。

4.任意組件間通信

使用 eventBus ,其實就是創建一個事件中心,相當于中轉站,可以用它來傳遞事件和接收事件。它的本質是通過創建一個空的 Vue 實例來作為消息傳遞的對象,通信的組件引入這個實例,通信的組件通過在這個實例上監聽和觸發事件,來實現消息的傳遞。

推薦學習:《vue.js視頻教程》

贊(0)
分享到: 更多 (0)
?
網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
门卫老头吮她的花蒂在线观看| 免费网站正能量WWW正能量| 久久久久亚洲AV无码专| 久久夜色精品国产噜噜亚洲AV| 免费看的WWW哔哩哔哩| 女人两个奶被揉到高潮就不想了| 日本19禁啪啪无遮挡免费| 少妇与大狼拘作爱| 亚洲AV成人无码网站不卡| 亚洲日本一线产区和二线产| 中文有无人妻VS无码人妻激烈 | 精品一区二区三区在线播放视频 | 国产亲妺妺乱的性69视频播放| 交换配乱吟粗大SNS840| 美女内射毛片在线看| 日韩AV片无码一区二区不卡电影| 无码少妇一区二区三区芒果| 亚洲人成人无码WWW影院| 777琪琪午夜理论电影网| 草草地址线路①屁屁影院成人| 国产毛片久久久久久国产毛片| 久久精品成人欧美大片| 欧美日韩一区二区三区精品视频在线 | 一本一道波多野毛片结衣AV黑人| AV鲁丝一区鲁丝二区鲁丝四| 国产成人剧情AV麻豆果冻| 精品无码久久久久久久久久| 欧美日韩免费专区在线| 无码少妇一区二区浪潮AV| 一区二区三区熟女少妇小牛| 成人无码精品1区2区3区免费看| 国产亚洲精品自在久久蜜TV| 蜜桃av无码一区二区三区| 少妇夜夜春夜夜爽试看视频| 亚洲日本高清成人AⅤ片| 啊灬啊灬啊灬啊灬快灬高潮了| 国产内射老熟女AAAA∵| 满月产奶1∨1POP骨科推荐| 色综合久久久久综合体桃花网| 亚洲精品无码AV片| 宝宝都湿透了还嘴硬疼怎么回事 | 女性C春合欢液高朝液精华液| 挺进大幂幂的滋润花苞御女天下 | 亚洲A∨精品无码一区二区| 性欧美牲交XXXXX视频| 国产精品对白刺激久久久| 毛片TV网站无套内射TV网站| 图片区小说区激情春色| 在厨房乱子伦对白| 国产精品久久久久久一区二区三区| 久久九九精品国产综合喷水| 色噜噜精品一区二区三区| 野花高清影视免费观看西瓜| 乖我们换个姿态再来一遍吧的小说| 久久精品国产只有精品66| 色一情一乱一伦一视频免费看| 亚洲综合无码一区二区| 国产★蜜臀AV无码| 毛多水多肥胖老太婆| 小SAO货撅起屁股扒开GIF动| AV最新高清无码专区| 狠狠色噜噜狠狠狠狠色综合久| 人人妻人人澡人人爽人人精直播| 亚洲精品国产成人AV蜜臀| 顶级CSGO大片| 男女啪啪无遮挡免费网站| 亚洲AV无码成人YELLOW| 成人片黄网站色多多WWW| 鲁丝片一区二区三区免费| 亚洲 无码 国产精品| 成年女人毛片视频免费| 老熟女高潮一区二区三区| 无码人妻少妇色欲AV一区二区| JAPANESE春药高潮| 久久久久女教师免费一区| 无码人妻巨屁股系列大又挺拔| WWW无人区一码二码三码区别| 久久精品成人无码观看不卡| 无码专区6080YY免费视频| 边做边爱完整版免费视频播放 | 精品人妻AV区波多野结衣| 挺进大幂幂的滋润花苞御女天下| らだ天堂中文在线| 迈开腿让我尝一下你的味道一 | 精品国产乱码久久久久久蜜桃网站| 色综合久色AⅤ网| HEZYO东京热无码专区| 久久人人做人人爽人人AV| 小妖精太湿太紧了拔不出| 厨房里的激战2免费观看不打丐赛| 免费无码鲁丝片一区二区| 亚洲色偷偷综合亚洲AV伊人蜜桃| 国产免费无码一区二区| 少妇爆乳无码AV无码专区| SHOPIFY日本站5ZAWW| 免费看无码自慰一区二区| 亚洲午夜无码毛片Av| 国内精品国内精品自线在拍| 天天爱天天做天天做天天吃中文| www.xx欧美大鸡巴| 年轻的小婊孑4中文字幕电影| 夜里18款禁用B站入口探APP| 狠狠人妻久久久久久综合蜜桃| 无码人妻精品一区二区三区在线 | 特级毛片AAAAAA| 成在人线AV无码免费| 人妻人人澡人人添人人爽 | 欧美性狂猛BBBBBBXXXX| 18日韩xxxx| 麻豆亚洲AV成人无码久久精品| 野花高清在线观看免费官网中文版| 黄桃AV无码免费一区二区三区| 无码无套少妇毛多18P| 国产成人无码AV一区二区 | 欧美人与性动交Α欧美精品| 中文天堂在线最新版在线WWW| 久久无码人妻一区二区三区 | 亚洲VA中文字幕无码久久不卡| 国产午夜精品久久精品电影| 五十路丰满中年熟女中出| 国产精品久久高潮呻吟无码 | 国产精品国色综合久久| 天天做天天爱夜夜爽毛片毛片| 国产99在线 | 韩国| 熟妇人交VIDEOS复古| 国产成人精品亚洲精品| 无码免费中文字幕视频| 国产美女被遭强高潮网站免费| 午夜亚洲WWW湿好大| 国产性大战XXXXX久久久| 新版АⅤ资源新版在线天堂| 国产无线乱码一区二三区| 亚洲AV成人无码久久精品| 豪妇荡乳1一5白玉兰免费下载| 亚洲AV无码成H在线观看| 狠狠干2015最新版| 亚洲熟妇AV日韩熟妇AV| 久久亚洲人成网站| 69成人免费视频无码专区| 欧美一区二区三放荡人妇| 成年午夜免费AⅤ在线观看| 四虎国产精品成人影院| 国产裸体XXXX视频在线播放| 亚洲AV无码久久精品成人| 精品无人区卡一卡二卡三乱码| 亚洲中文无码A∨在线观看| 美女扒开粉嫩尿口的照片| A级毛片内射免费视频| 日韩精品无码一区二区中文字幕| 妇女性内射冈站HDWWW000| 无码专区永久免费AV网站| 精品厕所偷拍各类美女TP嘘嘘| 野花高清在线观看免费3中文| 男人J桶进女人P无遮挡在线观看| YINLUAN小镇公交车尺寸| 少妇BBW搡BBBB搡| 国产午夜精品理论片| 亚洲一区二区自偷自拍另类| 男人GAY自慰吞精网站| 成AV人电影在线观看| 无码H黄肉3D动漫在线观看| 好爽又高潮了毛片| 真实国产乱人伦在线视频播放| 人妻丰满熟妇AV无码处处不卡| 国产成人亚洲综合精品| 亚洲VA在线VA天堂VA不卡| 美女MM131爽爽爽作爱视频| 波多野结衣AV一区二区无码| 无码精品人妻一区二区三区影院| 精品国产一区二区亚洲人成毛片 | 野花日本大全免费观看版动漫| 欧美精品少妇XXXXⅩ另类| 公交车后车座疯狂的做的细节| 亚洲爆乳无码一区二区三区| 麻豆一二三四区乱码| 成人性生交大片免费看| 亚洲AV无码一区二区在线蜜桃| 麻豆日产精品卡2卡3卡4卡5卡| 波多野结衣50连登视频| 小辣椒AV福利在线网站| 老外又长又大插的太深了| 草莓视频18在线在线播放| 亚洲AV成人一区二区三区在线观| 乱辈通奷ⅩXXXXHD| 堕落的人妻1―10雨柔| 亚洲精品国偷拍自产在线观看| 欧美黑人巨大手机在线观看| 国产精品三级在线观看无码| 伊人丁香狠狠色综合久久| 搡老女人老妇女老熟女偷拍| 精品午夜中文字幕熟女人妻在线| X姓女RAPPER| 亚洲AV午夜成人片精品网站| 欧美成人精品高清视频在线观看| 国产SP调教打屁股视频网站| 一二三四在线观看免费高清视频| 三级4级全黄60分钟| 久久精品亚洲熟妇少妇任你躁| 成人乱子视频在线播放| 亚洲人成人无码www在线观看|