vue 点击div 获取位置_Vue中组件之间8种通信方式,值得收藏
之前寫了一篇關于vue面試總結的文章, 有不少網友提出組件之間通信方式還有很多, 這篇文章便是專門總結組件之間通信的
vue是數據驅動視圖更新的框架, 所以對于vue來說組件間的數據通信非常重要,那么組件之間如何進行數據通信的呢?首先我們需要知道在vue中組件之間存在什么樣的關系, 才更容易理解他們的通信方式, 就好像過年回家,坐著一屋子的陌生人,相互之間怎么稱呼,這時就需要先知道自己和他們之間是什么樣的關系。vue組件中關系說明:
如上圖所示, A與B、A與C、B與D、C與E組件之間是父子關系;B與C之間是兄弟關系;A與D、A與C之間是隔代關系;D與E是堂兄關系(非直系親屬) 針對以上關系我們歸類為:
父子組件之間通信
非父子組件之間通信(兄弟組件、隔代關系組件等)
本文會介紹組件間通信的8種方式如下圖所示,?并介紹在不同的場景下如何選擇有效方式實現的組件間通信方式,希望可以幫助小伙伴們更好理解組件間的通信。
一、props?/?$emit
父組件通過props的方式向子組件傳遞數據,而通過$emit?子組件可以向父組件通信。
1. 父組件向子組件傳值
下面通過一個例子說明父組件如何向子組件傳遞數據:在子組件article.vue中如何獲取父組件section.vue中的數據articles:['紅樓夢', '西游記','三國演義']
// 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: ['紅樓夢', '西游記', '三國演義']
}
}
}script>
// 子組件 article.vue<template><div><span v-for="(item, index) in articles" :key="index">{{item}}span>div>template><script>export default {props: ['articles']
}script>
總結: props 只可以從上一級組件傳遞到下一級組件(父子組件),即所謂的單向數據流。而且 props 只讀,不可被修改,所有修改都會失效并警告。
2. 子組件向父組件傳值
對于$emit?我自己的理解是這樣的:?$emit綁定一個自定義事件, 當這個語句被執行時, 就會將參數arg傳遞給父組件,父組件通過v-on監聽并接收參數。通過一個例子,說明子組件如何向父組件傳遞數據。在上個例子的基礎上, 點擊頁面渲染出來的ariticle的item, 父組件中顯示在數組中的下標
// 父組件中<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: ['紅樓夢', '西游記', '三國演義']
}
},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官方的解釋,通過$parent和$children就可以訪問組件的實例,拿到實例代表什么?代表可以訪問此組件的所有方法和data。接下來就是怎么實現拿到指定組件的實例。
使用方法
// 父組件中<template><div class="hello_world"><div>{{msg}}div><com-a>com-a><button @click="changeA">點擊改變子組件值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()的實例,在這實例上再拿$parent得到的是undefined,而在最底層的子組件拿$children是個空數組。也要注意得到$parent和$children的值不一樣,$children?的值是數組,而$parent是個對象
總結
上面兩種方式用于父子組件之間的通信, 而使用props進行父子組件通信更加普遍; 二者皆不能用于非父子組件之間的通信。
三、provide/?reject
概念:
provide/?reject?是vue2.2.0新增的api, 簡單來說就是父組件中通過provide來提供變量, 然后再子組件中通過reject來注入變量。
注意: 這里不論子組件嵌套有多深, 只要調用了inject?那么就可以注入provide中的數據,而不局限于只能從當前父組件的props屬性中回去數據
舉例驗證
接下來就用一個例子來驗證上面的描述: 假設有三個組件: 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 元素;如果用在子組件上,引用就指向組件實例,可以通過實例直接調用組件的方法或訪問數據, 我們看一個ref?來訪問組件的例子:
// 子組件 A.vueexport default {
data () {return {name: 'Vue.js'
}
},methods: {
sayHello () {console.log('hello')
}
}
}
// 父組件 app.vue<component-a ref="comA">component-a>template>
總結
以上是生活随笔為你收集整理的vue 点击div 获取位置_Vue中组件之间8种通信方式,值得收藏的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ad 原理图差分线_Altium差分线如
- 下一篇: vue 请求多个api_Vue 创建多人