Vue父子組件元素獲取方法互相調(diào)用示例詳解
一、前言
Vue
項(xiàng)目開發(fā)過程中,有時(shí)候我們需要父組件直接訪問子組件,子組件直接訪問父組件,或者子組件訪問根組件。梳理出如下請求方法:
- 父組件訪問子組件:
$children
或者$refs
; - 子組件訪問父組件:
$parent
; - 子組件訪問根組件(通過
new Vue
創(chuàng)建的根Vue
實(shí)例):$root
;
二、父組件訪問子組件
2.1 使用 $children
在父組件中使用 this.$children
拿到的是一個(gè)數(shù)組類型,它包含所有子組件實(shí)例。
<div id="app"> <cpn></cpn> <cpn></cpn> <button @click="btnClick">按鈕</button> </div> <template id="cpn"> <div> <h1>我是子組件</h1> </div> </template> <script> let vm = new Vue({ el: "#app", data: {}, methods: { btnClick() { //1.拿到所有子組件,是一個(gè)數(shù)組 console.log(this.$children); //2.拿到一個(gè)組件實(shí)例,可以直接訪問子組件中的方法和 data 中的數(shù)據(jù) this.$children[0].showMessage(); console.log(this.$children[0].name); } }, components: { cpn: { template: '#cpn', data() { return { name: 'webchang' } }, methods: { showMessage() { console.log('我是子組件'); } } } } }); </script>
2.2 使用 $refs
使用$children 的缺陷如下:
通過 $children
訪問子組件時(shí),是一個(gè)數(shù)組類型,訪問其中的子組件必須通過索引值。
但是當(dāng)子組件過多,我們需要拿到其中一個(gè)時(shí),往往不能確定它的索引值,甚至還可能會發(fā)生變化。
有時(shí)候,我們想明確獲取其中一個(gè)特定的組件,這個(gè)時(shí)候就可以使用 $refs
2.3 $refs 的使用
通過設(shè)置子組件的ref
,父組件通過this.$refs.xxx.method_name(data)
調(diào)用子組件方法,data
參數(shù)可選。
$refs
和 ref
指令通常是一起使用的。
首先,我們在子組件上添加一個(gè) ref
屬性,相當(dāng)于給某一個(gè)子組件綁定一個(gè)特定的ID
。
其次,this.$refs
拿到的是所有標(biāo)有 ref
屬性的子組件(如果一個(gè)子組件實(shí)例沒有 ref
屬性,通過這種方式是拿不到的),最后拿到的是一個(gè)對象,屬性名是子組件實(shí)例的 ref
屬性,屬性值是該組件實(shí)例。
通過 this.$refs.ID
就可以訪問到該組件。
示例代碼如下:
<div id="app"> <cpn ref="child1"></cpn> <cpn ref="child2"></cpn> <!-- 這個(gè)子組件實(shí)例沒有 ref 屬性,通過 this.$refs 方式拿不到這個(gè)組件實(shí)例 --> <cpn></cpn> <button @click="btnClick">按鈕</button> </div> <template id="cpn"> <div> <h1>我是子組件</h1> </div> </template> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> let vm = new Vue({ el: "#app", data: { message: "hello" }, methods: { btnClick() { console.log(this.$refs) console.log(this.$refs.child1) console.log(this.$refs.child1.name) this.$refs.child1.showMessage('父組件') } }, components: { cpn: { template: '#cpn', data() { return { name: 'webchang' } }, methods: { showMessage(value) { console.log("子組件方法被調(diào)用,調(diào)用者:" + value) } } } } }); </script>
三、子組件調(diào)用父組件方法
3.1 方法一:this.$parent.event
直接在子組件中通過this.$parent.event
來調(diào)用父組件的方法。示例代碼如下:
父組件
<template> <div> <child></child> </div> </template> <script> import child from './components/dam/child'; export default { components: { child }, methods: { fatherMethod(value) { console.log("父組件方法被調(diào)用,調(diào)用者:" + value) } } }; </script>
子組件
<template> <div> <button @click="childMethod()">點(diǎn)擊</button> </div> </template> <script> export default { methods: { childMethod() { this.$parent.fatherMethod('子組件'); } } }; </script>
注意事項(xiàng):
- 盡管在
Vue
開發(fā)中,我們允許通過$parent
來訪問父組件,但是在真實(shí)開發(fā)中盡量不要這樣做。 - 子組件應(yīng)該盡量避免直接訪問父組件的數(shù)據(jù),因?yàn)檫@樣代碼耦合度太高了。
- 如果我們將子組件放在另外一個(gè)組件之內(nèi),很可能該父組件沒有對應(yīng)的屬性,往往會引起問題。
- 另外,通過
$parent
直接修改父組件的狀態(tài),那么父組件中的狀態(tài)將變得飄忽不定,很不利于調(diào)試和維護(hù)。
3.2 方法二: $emit
在子組件里用$emit
向父組件觸發(fā)一個(gè)事件,父組件監(jiān)聽這個(gè)事件。
父組件
<template> <div> <child @fatherMethod="fatherMethod"></child> </div> </template> <script> import child from '~/components/dam/child'; export default { components: { child }, methods: { fatherMethod() { console.log('測試'); } } }; </script>
子組件
<template> <div> <button @click="childMethod()">點(diǎn)擊</button> </div> </template> <script> export default { methods: { childMethod() { this.$emit('fatherMethod'); } } }; </script>
3.3 方法三:方法傳參
父組件把方法傳入子組件中,在子組件里直接調(diào)用這個(gè)方法。
父組件
<template> <div> <child :fatherMethod="fatherMethod"></child> </div> </template> <script> import child from '~/components/dam/child'; export default { components: { child }, methods: { fatherMethod() { console.log('測試'); } } }; </script>
子組件
<template> <div> <button @click="childMethod()">點(diǎn)擊</button> </div> </template> <script> export default { props: { fatherMethod: { type: Function, default: null } }, methods: { childMethod() { if (this.fatherMethod) { this.fatherMethod(); } } } }; </script>
子組件 更簡便的寫法
<template> <div> <button @click="fatherMethod()">點(diǎn)擊</button> </div> </template> <script> export default { props: { fatherMethod: { type: Function, default: null } }, methods: { } }; </script>
四、其他調(diào)用方法
由于最終所有組件都會渲染成真實(shí)的Dom
元素,所以可以通過js
或jquery
,獲取Dom
元素對象,通過模擬點(diǎn)擊的方式觸發(fā)元素綁定的方法,通過本地Cookie
、localStorage
或sessionStorage
做參數(shù)緩存,實(shí)現(xiàn)值傳遞。
此方法不限于父子組件,只要組件位于同一頁面都可使用,但因?yàn)椴环?code>vue規(guī)范,并非特殊情況不建議使用。
組件A:
<template> <div> <h1>我是組件A</h1> <button id='btn' @click='methodA()'>點(diǎn)我</button> </div> </template> <script> export default { methods: { methodA() { var parameter= localStorage.getItem('parameter'); console.log('我是組件A方法'); } } }; </script>
組件B:
<template> <div> <h1>我是組件B</h1> <button @click='methodB(data)'>點(diǎn)我</button> </div> </template> <script> export default { methods: { methodB(data) { localStorage.setItem('parameter',data); $('#btn').click();//模擬按鈕點(diǎn)擊 console.log('模擬點(diǎn)擊按鈕,觸發(fā)A組件方法'); } } }; </script>
拓展閱讀
以上就是Vue 父子組件元素獲取、方法互相調(diào)用的詳細(xì)內(nèi)容,更多關(guān)于Vue父子組件元素獲取方法互調(diào)的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
vue實(shí)現(xiàn)抖音時(shí)間轉(zhuǎn)盤
這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)抖音時(shí)間轉(zhuǎn)盤,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-09-09vue實(shí)現(xiàn)兩列水平時(shí)間軸的示例代碼
本文主要介紹了vue實(shí)現(xiàn)兩列水平時(shí)間軸的示例代碼,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-11-11vue項(xiàng)目如何實(shí)現(xiàn)ip和localhost同時(shí)訪問
這篇文章主要介紹了vue項(xiàng)目如何實(shí)現(xiàn)ip和localhost同時(shí)訪問,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-10-10vuejs2.0子組件改變父組件的數(shù)據(jù)實(shí)例
本篇文章主要介紹了vuejs2.0子組件改變父組件的數(shù)據(jù)實(shí)例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-05-05Vue2使用TailwindCSS方法及遇到問題小結(jié)
Tailwind CSS是一個(gè)全新的、可定制的CSS框架,它提供了一系列的CSS類,用于構(gòu)建現(xiàn)代化的Web界面,這篇文章主要介紹了Vue2使用TailwindCSS方法及遇到問題小結(jié),需要的朋友可以參考下2024-03-03