Vue元件間資料傳遞的方式(3種)
vue中傳遞資料的方式有哪些
資料流的方式傳遞資料
通過 props 傳遞屬性
父級給demo2元件繫結一個msg資料
父元件
<template> <div class='container'> <demo2 :msg="msg" @change="change" /> </div> </template> <script> import demo2 from './demo2' export default { data(){ return { msg:'這是測試資料' } },methods:{ change(value){ this.msg = value } },components: { demo2 } } </script>
子元件通過定義props來使用msg,$emit觸發外部的函式來改變父級傳入的值
子元件
<template> <div class='container'> {{msg}} <button @click="change">點一下</button> </div> </template> <script> export default { props:['msg'],methods:{ change(){ this.$emit('change','這是新的資料') } } } </script>
通過 $attrs 來收集屬性
$attrs 會收集元件上繫結的屬性,對應class和style不會處理。如果與props同用,props的優先順序要高於attrs
父元件
<template> <div class="container"> <demo2 class="demo" style="color:red" :msg="msg" /> </div> </template> <script> import demo2 from "./demo2"; export default { data() { return { msg: "這是測試資料" }; },components: { demo2 } }; </script>
子元件中this.$attrs會收集元件上繫結的屬性
子元件
<template> <div class="container">{{$attrs.msg}} </div> </template> <script> export default { // inheritAttrs:true,// 會隱藏行間的屬性 // props:['msg'],// 這裡props的優先順序比$attrs要高,如果設定了props,那麼msg會在data上,而$attrs中就沒有msg created(){ console.log(this.$attrs) // 物件中只有msg一個屬性 } }; </script>
通過$listeners 來收集方法
$listeners 會收集元件上繫結的方法。 可以通過傳遞實參的方式改變父元件的值
父元件
<template> <div class='container'> {{msg}} <demo2 class="demo" style="color:red" @msgChange="change"/> </div> </template> <script> import demo2 from './demo2' export default { data () { return { msg: '這是測試資料' } },methods: { change(newvalue){ this.msg = newvalue; } },components: { demo2 } } </script>
子元件中this.$listeners會收集繫結在元件上的方法。通過this.$listeners.XXX()可以直接呼叫,以此可以來修改父元件data中的值
子元件
<template> <div class="container"> <button @click="change">點一下</button> </div> </template> <script> export default { // inheritAttrs:true,created(){ console.log(this) },methods:{ change(){ // this.$emit('msgChange') // this.$parent.change() // 與$emit功能相同,$parent也能夠實現該效果 this.$listeners.msgChange('改變後的值') } } }; </script>
通過provide提供依賴,inject注入依賴實現資料跨多級子元件傳遞
通過給父級的 provide 提供一個依賴物件,讓其所用子元件都能訪問到這個物件
“
provide 和 inject 繫結並不是可響應的。這是刻意為之的。然而,如果你傳入了一個可監聽的物件,那麼其物件的 property 還是可響應的。
”
其實也就是說provide 和 inject 繫結本身不做額外的事情(資料繫結之類),只是將提供的資料暴露給子元件。那麼暴露出來的資料是不是可相應的就取決與資料本身
父元件
<template> <div class='container'> <demo2 class="demo" style="color:red" :msg="msg" @msgChange="change"/> </div> </template> <script> import demo2 from './demo2' export default { provide(){ return { msg:this.msg,msgChange:this.change,// 這裡this本身就是一個可監聽的物件。 // this也就是當前vue例項本身已完成了資料響應,這裡只是將這個例項暴露給了他的所用子元件 app:this } },data () { return { msg: '這是測試資料' } },methods: { change(){ this.msg += 1; } },components: { demo2 } } </script>
後代的子元件可以通過reject注入相應的依賴
子元件
<template> <div class="container"> <!-- 這個msg的值不會變 --> <div>{{msg}} </div> <!-- msg的值會變,因為依然指向父元件的vue例項 --> <div>{{app.$data.msg}}</div> <button @click="msgChange">點一下</button> </div> </template> <script> export default { inject:['msg','msgChange','app'] }; </script>
直接訪問元件例項的方式獲取資料
通過 ref 獲取元件例項
ref 屬性定義在元件上獲取的是元件的vue例項,定義在原生標籤上獲取的是對應的dom
需要等掛載之後才能拿到$refs中的內容
父元件
<template> <div class='container'> {{msg}} <demo2 ref="test"/> </div> </template> <script> import demo2 from './demo2' export default { data () { return { msg: '' } },// 需要等掛載之後才能拿到$refs中的內容。 // 所用不能在模板中使用 mounted(){ this.msg = this.$refs.test.msg },components: { demo2 } } </script>
子元件
<script> export default { data(){ return { msg:'這是子元件的資料' } } } </script>
通過\$parent/$children 獲取元件例項
同樣的也是必須在mounted之後才能獲取對應例項
這裡是父元件展示子元件中的msg,子元件展示父元件的msg
父元件通過$children獲取子元件例項
父元件
<template> <div class='container'> {{msg}} <demo2/> </div> </template> <script> import demo2 from './demo2' export default { data () { return { msg: '',fatherMsg:"這是父元件的內容" } },mounted(){ console.log(this.$children) //獲取子元件例項上的sonMsg,$children是個陣列需要選擇對應的索引 this.msg = this.$children[0].sonMsg; },components: { demo2 } } </script>
子元件通過$paren獲取父元件例項
子元件
<template> <div class='container'> {{msg}} </div> </template> <script> export default { data () { return { msg:'',sonMsg: '這是子元件的資料' } },mounted(){ //獲取父元件的例項上的fatherMsg this.msg = this.$parent.fatherMsg; } } </script>
定義一個公共倉庫共享資料
定義 eventBus 共享資料
在Vue原型上新增一個$bus為一個新的vue物件,可以在全域性的vue例項中通過$bus獲取到這個vue物件,從而獲取這個物件上的屬性和方法。
在main.js中定義
Vue.prototype.$bus = new Vue({ data:{ a:1,b:2 },methods:{ log(){ console.log(this.a) } } })
全域性Vue例項都能獲取到定義在$bus上的屬性和方法
通過 Vuex 共享資料
官方給出的跨多元件傳遞資料的解決方案。
store index.js
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) export default new Vuex.Store({ state: { test:'123123123',test2:'123123123',},mutations: { changeTest(state,payload){ console.log(state,payload) state.test = payload.value },changeTest2(state,payload) state.test2 = payload.value } },actions: { asyncChageTest({commit},payload){ setTimeout( ()=>{ commit('changeTest2',payload) },2000) } },modules: { } })
在元件中使用
<template> <div class='container'> {{this.$store.state.test}} {{test}} {{this.$store.state.test2}} {{test2}} <button @click="change">點一下</button> <button @click="asyncChange">點一下</button> </div> </template> <script> // 引入mapState輔助函式改造state資料 import { mapState,mapMutations,mapActions } from 'vuex' export default { data(){ return { msg:'這是測試資料' } },computed:{ ...mapState(['test','test2']) },methods:{ // 放非同步或者同步的方法引入 ...mapMutations(['changeTest']),...mapActions(['asyncChageTest']),change(){ // 同步修改state值的兩種方法 this.$store.commit('changeTest',{value:'改變後test的值'}); // this.changeTest({value:'改變後的值'}) },asyncChange(){ // 非同步修改state值的兩種方法 this.$store.dispatch('asyncChageTest',{value:'改變後test2的值'}) // this.asyncChageTest({value:'改變後test2的值'}) } },} </script>
以上就是對Vue中元件間資料傳遞的方式進行了一個總結,在日常的開發中還是需要根據使用的場景採取合適的方式進行資料的傳遞
到此這篇關於Vue元件間資料傳遞的方式(3種)的文章就介紹到這了,更多相關Vue元件間資料傳遞內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!