一、父組件向子組件傳值
首先父組件發送的形式是用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總線。