1.1.1經過綁定 props 將父組件的數據關聯到子組件,並修飾 .sync 或者用 v-model 同步來自子組件的數據變化前端
//使用.sync : //父組件 <template> <div class="home"> <my-dialog :show.sync="valueChild"/> <button @click="changeValue">toggle</button> </div> </template> <script> import myDialog from '@/components/myDialog.vue' export default { name: 'home', components: { myDialog }, data(){ return{ valueChild:true, } }, methods:{ changeValue(){ this.valueChild = !this.valueChild } } } </script> //子組件 <template> <div> <div>myDialog</div> <div v-if="show"> <p>默認初始值是{{show}},因此是顯示的</p> <button @click.stop="closeDiv">關閉</button> </div> </div> </template> <script> export default { props:['show'], methods:{ closeDiv(){ this.$emit('update:show',false) } } } </script>
// v-model : //父組件: <template> <div class="home"> <myDialog v-model="show"></myDialog> <button @click="toggle">Toggle</button> </div> </template> <script> import myDialog from '@/components/myDialog.vue' export default { name: 'home', components: { myDialog }, data() { return { show: false } }, methods: { toggle() { this.show = !this.show } } } </script> //子組件: <template> <div> <div v-if="value" class="modal"> {{value}} <button @click="close">x</button> </div> </div> </template> <script> export default { props: ['value'], methods: { close() { this.$emit('input', false) } } } </script>
1.1.2綁定 listener 事件監聽器,當子組件狀態或者數據發生變化時,觸發事件並將數據傳遞到父組件vue
$listeners 和 $attrs 二者表面層都是一個意思,$attrs 是向下傳遞數據,$listeners 是向下傳遞方法,經過手動去調用 $listeners 對象裏的方法,原理就是 $emit 監聽事件,$listeners 也能夠當作一個包裹監聽事件的一個對象。
// 父組件: <template> <div class="home"> {{firstMsg}} <myDialog v-on:changeData="changeData" v-on:another='another'></myDialog> </div> </template> <script> import myDialog from '@/components/myDialog.vue' export default { name: 'home', components: { myDialog }, data() { return { firstMsg: '父組件' } }, methods: { changeData(params) { this.firstMsg = params }, another() { alert(2) } } } </script> //子組件: <template> <div> <p @click="$emit('another')">子組件</p> <other v-on="$listeners"/> </div> </template> <script> import other from '@/components/other.vue' export default { props: ['value'], components:{ other }, created () { // eslint-disable-next-line no-console console.log(this.$listeners) } } </script> //孫子組件: <template> <div> <p @click='$listeners.changeData("change")'>孫子組件</p> </div> </template> <script> export default { name: 'demo', created () { // eslint-disable-next-line no-console console.log(this.$listeners) }, } </script>
1.2.1 獲取 props 或者 $attrs 傳下來的數據this
//父組件: <template> <div class="home"> <myDialog :foo="foo" :boo="boo" :coo="coo" :doo="doo" title="前端工匠"></myDialog> </div> </template> <script> import myDialog from '@/components/myDialog.vue' export default { name: 'home', components: { myDialog }, data() { return { foo: "Javascript", boo: "Html", coo: "CSS", doo: "Vue" } }, methods: { changeData(params) { this.firstMsg = params }, another() { alert(2) } } } </script> //子組件: <template> <div> <p>foo:{{foo}}</p> <p>子組件的$attrs: {{ $attrs }}</p> <other v-bind="$attrs" /> </div> </template> <script> import other from '@/components/other.vue' export default { components: { other }, inheritAttrs: false, // 能夠關閉自動掛載到組件根元素上的沒有在props聲明的屬性 props: { foo: String // foo做爲props屬性綁定 }, created() { // eslint-disable-next-line no-console console.log(this.$attrs); } } </script> //孫子組件: <template> <div> <p>boo: {{ boo }}</p> <p>孫子:{{$attrs}}</p> </div> </template> <script> export default { name: 'demo', inheritAttrs: false, props: { boo: String }, created() { // eslint-disable-next-line no-console console.log(this.$attrs); }, } </script>
2.1經過 EventBus 或者 $root 去註冊事件,由兄弟組件去監聽事件傳遞過來的數據變化 eslint
2.2 在 Vuex 存放狀態,並在兩個組件中都監聽狀態變化
2.3 在父組件上綁定狀態,並經過 v-model 或者 .sync 綁定到兩個兄弟組件中去,以同步數據變化code
在 Vue 中,處於祖孫關係的組件,並且孫組件被直接寫在了祖先組件的 template 內,要從祖先組件獲取孫組件的數據,有如下幾種方式:component
3.1.1能夠在模板上給孫組件綁定 ref 並經過 $refs 調用孫組件的方法獲取數據對象
//父組件 <template> <div class="home"> {{title}} {{text}} <myDialog ref="comA"></myDialog> </div> </template> <script> import myDialog from '@/components/myDialog.vue' export default { name: 'home', components: { myDialog }, data() { return { title:'', text:'' } }, computed: { }, mounted() { const comA = this.$refs.comA; // console.log(comA.title); // Vue.js this.title = comA.title this.text = comA.text comA.sayHello(); // 彈窗 }, methods: {} } </script> //子組件: <template> <div> <div v-if="show">sayHello</div> <other ref="comB" /> </div> </template> <script> import other from '@/components/other.vue' export default { components: { other }, data() { return { title: 'Vue.js', show: false, text:'' } }, created() { }, mounted() { const comB = this.$refs.comB; this.text = comB.text }, methods: { sayHello() { this.show = true // window.alert('Hello'); } } } </script> //孫子組件: <template> <div> </div> </template> <script> export default { name: 'demo', data(){ return{ text:'c' } }, created() { }, } </script>
3.1.2 能夠在模板上給孫組件綁定 listener 獲取孫組件傳過來的數據
3.1.3 能夠在模板上給孫組件綁定 v-model 或者 .sync 同步孫組件的數據事件
3.2.1先在子組件上綁定 v-model 或者 .sync,接着再在子組件的模板上經過 v-model 或者 .sync 綁定孫組件,以同步孫組件的數據
3.2.2如今孫組件上綁定 listener,再給子組件綁定 listener,數據由事件層層上傳給祖先組件ip
3.3.1直接在祖先組件的 template 中經過 v-bind 將數據傳遞到孫組件中,孫組件經過 props 或者 $attrs 進行接收input
3.4.1先在子組件上 v-bind 綁定數據,接着再在子組件上經過 v-bind 綁定孫組件,數據層層向下傳遞3.4.2孫組件在 EventBus 中註冊事件,監聽來自祖先組件觸發的事件數據3.4.3祖先組件將數據掛到 Vuex 中,再由孫組件從 Vuex 中去獲取數據