vue組件之間的三種傳值方式


 

一、父組件向子組件傳值

首先父組件發送的形式是用bind綁定值到子組件身上,然后子組件數props屬性接收

<body>
    <div id="app">
        <!-- 父組件,可以在引用子組件的時候,通過屬性綁定的形式,把需要傳遞給子組件的數據,以屬性綁定的形式,傳遞到子組件內部,供子組件使用 -->
        <com1 :parentmsg="msg"></com1>
    </div>
</body>

</html>
<script>
    var vm = new Vue({
        el: "#app",
        data: {
            msg: "這是父組件中的數據"
        },
        methods: {},
        components: {
            com1: {
                data() {
                    // return {
                    //     title: "123",
                    //     content: "qqq"
                    // }
                },
                template: '<h1 @click="change">這是子組件 --- {{parentmsg}}</h1>',
                props: ['parentmsg'],
                // directives: {},
                // filters: {},
                // components: {},
                // methods: {
                //     change() {
                //         this.parentmsg = "被修改了"
                //     }
                // }
            }
        }
    })
</script>

二、子組件向父組件傳值

<body>
    <div id="app">
        <com2 @func="show"></com2>
    </div>
</body>
<template id="tmpl">
    <h1>這是子組件</h1>
    <h4>點擊按鈕獲取從父組件傳過來的 func 方法</h4>
    <input type="button" value="點擊" @click="myclick">
</template>

</html>
<script>
    var com2 = {
        template: '#tmpl',
        methods: {
            myclick() {
                this.$emit('func', this.sonmsg)
            }
        }
    }
    var vm = new Vue({
        el: "#app",
        data: {
            datamsgFormSon: null

        },
        methods: {
            show(data) {
                this.datamsgFormSon = data
            }
        },
        components: {
            com2: com2
        }
    })
</script>

三、非父子之間傳值(兄弟組件傳值)

<body>
    <div id="app">
      <zs></zs>
      <ls></ls>
    </div>
  </body>
</html>
<script>
  var bus = new Vue();
  Vue.component("zs", {
    template: '<div>這是張山<button @click="sb">傳值</button></div>',
    methods: {
      sb() {
        bus.$emit("tt", {
          name: "我是zs"
        });
      }
    }
  });
  Vue.component("ls", {
    template: "<div>我是ls</div>",
    created() {
      bus.$on("tt", function(data) {
        console.log(data);
      });
    }
  });
</script>

 

三、通過Vuex狀態管理傳值
1.通過npm加載vuex,創建store.js文件,然后在main.js中引入,store.js文件代碼如下:
 import Vue from 'vue'
  import Vuex from 'vuex'
  Vue.use(Vuex);
  const state = {
    author:'Wise Wang'
  };
  const mutations = {
    newAuthor(state,msg){
      state.author = msg
    }
  }
  export default  new Vuex.Store({
    state,
    mutations
  })
 2.父組件parent代碼如下:
 <template>
    <div class="parent">
      <h2>{{ msg }}</h2>
      <p>父組件接手到的內容:{{ username }}</p>
      <input type="text" v-model="inputTxt">
      <button @click="setAuthor">傳參</button>
      <son psMsg="父傳子的內容:叫爸爸" @transfer="getUser"></son>
    </div>
  </template>
  <script>
  import son from './Son'
  export default {
    name: 'HelloWorld',
    data () {
      return {
        msg: '父組件',
        username:'',
        inputTxt:''
      }
    },
    components:{son},
    methods:{
      getUser(msg){
        this.username= msg
      },
      setAuthor:function () {
        this.$store.commit('newAuthor',this.inputTxt)
      }
    }
  }
  </script>
 3.子組件son代碼如下:
<template>
    <div class="son">
      <p>{{ sonMsg }}</p>
      <p>子組件接收到內容:{{ psMsg }}</p>
      <p>這本書的作者是:{{ $store.state.author }}</p>
      <!--<input type="text" v-model="user" @change="setUser">-->
      <button @click="setUser">傳值</button>
      </div>
  </template>
  <script>
  export default {
    name: "son",
    data(){
      return {
        sonMsg:'子組件',
        user:'子傳父的內容'
      }
    },
    props:['psMsg'],
    methods:{
      setUser:function(){
        this.$emit('transfer',this.user)
      }
    }
  }
  </script>

 

四、bus總線傳值

思路:在Vue的原型上創建一個屬性bus,該屬性的值為new Vue(),即bus也是一個vue實例

第一步:在main.js中創建bus總線,類似公共變量的方式。

 

 第二步:在子組件A中,通過bus總線拋出信息和值。this.bus就是Vue實例,$emit也是上面的方法

 

 

 

 第三步:在子組件B中,在created或mounted等生命周期函數上,監聽那個事件和獲取那個值。

注意:bus總線,是聯動的,當A組件觸動bus總線的時候,B組件中也會響應式的觸發。

B組件中的bus,需要在函數中,比如:created函數、mounted函數、甚至是data函數。

data中:

 

 生命周期函數中:

 

 

總之,監聽bus總線的事件,必須要函數中,但是該函數執行的時候,跟bus總線無關。

路由組件中:兩個組件不在一個頁面,bus總線即使改變了值,當點擊另一個路由路徑的時候,data函數又將值初始化了,

所以說,bus總線作用的兩個組件應該在同一頁面中。當然,可以用一個倉庫來存儲這個改變的值,比如:vuex、webStorage、數據庫等等。
例如:bus在vuex中使用:

A組件:

methods: {
      handleClick () {
        this.bus.$emit('busEvent', this.loginFlag) //1、發出“事件和值”
      }
    },

B組件:

<script>
export default {
    data () {
      return {
        busValue: this.$store.state.login ,//(2)從store中獲取該值
      }
    },
    methods: {
      handleClick () {
        console.log(this.busValue)
      }
    },
    created () {
      var localValue;
     this.bus.$on('busEvent', res => {
        localValue = res//當bus觸發時,這里生效,將busValue值修改了,
                            //但是,當點開該頁面路由組件的時候,data函數初始化了busValue值
        this.$store.state.login = res; //(1)將該值存在store中
      })
    }
    
}
</script>

但是,還是有問題:當用戶未點擊過B路由組件前,點擊A路由組件不會觸發bus總線,因為,B組件的代碼根本沒有加載過來。

現在就出現了這種情況:A已經觸發了bus總線,B不能監聽到bus總線。

所以說,A、B組件還是在一個頁面時,可以使用bus總線。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM