vue 点击div 获取位置_Vue中组件之间8种通信方式,值得收藏
之前寫(xiě)了一篇關(guān)于vue面試總結(jié)的文章, 有不少網(wǎng)友提出組件之間通信方式還有很多, 這篇文章便是專(zhuān)門(mén)總結(jié)組件之間通信的
vue是數(shù)據(jù)驅(qū)動(dòng)視圖更新的框架, 所以對(duì)于vue來(lái)說(shuō)組件間的數(shù)據(jù)通信非常重要,那么組件之間如何進(jìn)行數(shù)據(jù)通信的呢?首先我們需要知道在vue中組件之間存在什么樣的關(guān)系, 才更容易理解他們的通信方式, 就好像過(guò)年回家,坐著一屋子的陌生人,相互之間怎么稱(chēng)呼,這時(shí)就需要先知道自己和他們之間是什么樣的關(guān)系。vue組件中關(guān)系說(shuō)明:
如上圖所示, A與B、A與C、B與D、C與E組件之間是父子關(guān)系;B與C之間是兄弟關(guān)系;A與D、A與C之間是隔代關(guān)系;D與E是堂兄關(guān)系(非直系親屬) 針對(duì)以上關(guān)系我們歸類(lèi)為:
父子組件之間通信
非父子組件之間通信(兄弟組件、隔代關(guān)系組件等)
本文會(huì)介紹組件間通信的8種方式如下圖所示,?并介紹在不同的場(chǎng)景下如何選擇有效方式實(shí)現(xiàn)的組件間通信方式,希望可以幫助小伙伴們更好理解組件間的通信。
一、props?/?$emit
父組件通過(guò)props的方式向子組件傳遞數(shù)據(jù),而通過(guò)$emit?子組件可以向父組件通信。
1. 父組件向子組件傳值
下面通過(guò)一個(gè)例子說(shuō)明父組件如何向子組件傳遞數(shù)據(jù):在子組件article.vue中如何獲取父組件section.vue中的數(shù)據(jù)articles:['紅樓夢(mèng)', '西游記','三國(guó)演義']
// section父組件<template><div class="section"><com-article :articles="articleList">com-article>div>template><script>import comArticle from './test/article.vue'export default {name: 'HelloWorld',components: { comArticle },
data() {return {articleList: ['紅樓夢(mèng)', '西游記', '三國(guó)演義']
}
}
}script>
// 子組件 article.vue<template><div><span v-for="(item, index) in articles" :key="index">{{item}}span>div>template><script>export default {props: ['articles']
}script>
總結(jié): props 只可以從上一級(jí)組件傳遞到下一級(jí)組件(父子組件),即所謂的單向數(shù)據(jù)流。而且 props 只讀,不可被修改,所有修改都會(huì)失效并警告。
2. 子組件向父組件傳值
對(duì)于$emit?我自己的理解是這樣的:?$emit綁定一個(gè)自定義事件, 當(dāng)這個(gè)語(yǔ)句被執(zhí)行時(shí), 就會(huì)將參數(shù)arg傳遞給父組件,父組件通過(guò)v-on監(jiān)聽(tīng)并接收參數(shù)。通過(guò)一個(gè)例子,說(shuō)明子組件如何向父組件傳遞數(shù)據(jù)。在上個(gè)例子的基礎(chǔ)上, 點(diǎn)擊頁(yè)面渲染出來(lái)的ariticle的item, 父組件中顯示在數(shù)組中的下標(biāo)
// 父組件中<template><div class="section"><com-article :articles="articleList" @onEmitIndex="onEmitIndex">com-article><p>{{currentIndex}}p>div>template><script>import comArticle from './test/article.vue'export default {name: 'HelloWorld',components: { comArticle },
data() {return {currentIndex: -1,articleList: ['紅樓夢(mèng)', '西游記', '三國(guó)演義']
}
},methods: {
onEmitIndex(idx) {this.currentIndex = idx
}
}
}script>
<template><div><div v-for="(item, index) in articles" :key="index" @click="emitIndex(index)">{{item}}div>div>template><script>export default {props: ['articles'],methods: {
emitIndex(index) {this.$emit('onEmitIndex', index)
}
}
}script>
二、 ?$children?/?$parent
上面這張圖片是vue官方的解釋,通過(guò)$parent和$children就可以訪問(wèn)組件的實(shí)例,拿到實(shí)例代表什么?代表可以訪問(wèn)此組件的所有方法和data。接下來(lái)就是怎么實(shí)現(xiàn)拿到指定組件的實(shí)例。
使用方法
// 父組件中<template><div class="hello_world"><div>{{msg}}div><com-a>com-a><button @click="changeA">點(diǎn)擊改變子組件值button>div>template><script>import ComA from './test/comA.vue'export default {name: 'HelloWorld',components: { ComA },
data() {return {msg: 'Welcome'
}
},methods: {
changeA() {// 獲取到子組件Athis.$children[0].messageA = 'this is new value'
}
}
}script>
// 子組件中<template><div class="com_a"><span>{{messageA}}span><p>獲取父組件的值為: {{parentVal}}p>div>template><script>export default {
data() {return {messageA: 'this is old'
}
},computed:{
parentVal(){return this.$parent.msg;
}
}
}script>
要注意邊界情況,如在#app上拿$parent得到的是new Vue()的實(shí)例,在這實(shí)例上再拿$parent得到的是undefined,而在最底層的子組件拿$children是個(gè)空數(shù)組。也要注意得到$parent和$children的值不一樣,$children?的值是數(shù)組,而$parent是個(gè)對(duì)象
總結(jié)
上面兩種方式用于父子組件之間的通信, 而使用props進(jìn)行父子組件通信更加普遍; 二者皆不能用于非父子組件之間的通信。
三、provide/?reject
概念:
provide/?reject?是vue2.2.0新增的api, 簡(jiǎn)單來(lái)說(shuō)就是父組件中通過(guò)provide來(lái)提供變量, 然后再子組件中通過(guò)reject來(lái)注入變量。
注意: 這里不論子組件嵌套有多深, 只要調(diào)用了inject?那么就可以注入provide中的數(shù)據(jù),而不局限于只能從當(dāng)前父組件的props屬性中回去數(shù)據(jù)
舉例驗(yàn)證
接下來(lái)就用一個(gè)例子來(lái)驗(yàn)證上面的描述: 假設(shè)有三個(gè)組件: A.vue、B.vue、C.vue 其中 C是B的子組件,B是A的子組件
// A.vue<template><div><comB>comB>div>template><script>import comB from '../components/test/comB.vue'export default {name: "A",provide: {for: "demo"
},components:{
comB
}
}script>
// B.vue<template><div>
{{demo}}<comC>comC>div>template><script>import comC from '../components/test/comC.vue'export default {name: "B",inject: ['for'],
data() {return {demo: this.for
}
},components: {
comC
}
}script>
// C.vue<template><div>
{{demo}}div>template><script>export default {name: "C",inject: ['for'],
data() {return {demo: this.for
}
}
}script>
四、ref?/?refs
ref:如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子組件上,引用就指向組件實(shí)例,可以通過(guò)實(shí)例直接調(diào)用組件的方法或訪問(wèn)數(shù)據(jù), 我們看一個(gè)ref?來(lái)訪問(wèn)組件的例子:
// 子組件 A.vueexport default {
data () {return {name: 'Vue.js'
}
},methods: {
sayHello () {console.log('hello')
}
}
}
// 父組件 app.vue<component-a ref="comA">component-a>template>
總結(jié)
以上是生活随笔為你收集整理的vue 点击div 获取位置_Vue中组件之间8种通信方式,值得收藏的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: ad 原理图差分线_Altium差分线如
- 下一篇: mongodb一致性协议_mongodb