Vue组件通信

1. 父传子、子传父

props、$emit 触发父亲的自定义事件

2. 状态(数据)提升

实际上是子传父、父传子的结合:利用父组件做中转站

<div id="app">
      <test-com1 :pmsg="msg"></test-com1>
      <test-com2 @mod-msg="handler"></test-com2>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
      // 组件1与父组件之间的数据进行父传子
      Vue.component('test-com1', {
        props: ['pmsg'],
        data: function () {
          return { msg: '我是组件1中的值' }
        },
        template: `<div>组件1:{{pmsg}}</div>`
      })
      // 组件2与父组件之间的数据进行子传父
      Vue.component('test-com2', {
        data: function () {
          return { msg: '我是组件2中的值' }
        },
        template: `<button @click="$emit('mod-msg',msg)">修改兄弟组件1的值</button>`
      })
      // 组件2中的数据提升到父组件(状态提升):利用父类来实现兄弟数据传输
      const vm = new Vue({
        el: '#app',
        data: { msg: '我是父组件中的值' },
        methods: {
          handler(val) {
            this.msg = val
          }
        }
      })
</script>

3. 事件中心(EventBus)

利用事件中心实现组件间自由传值:会引起传值紊乱。不知道‘谁’修改了数值

<div id="app">
      <test-com1></test-com1>
      <test-com2></test-com2>
      <button @click="handler">销毁事件</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
      // 事件中心
      const hub = new Vue()
      // 组件1
      Vue.component('test-com1', {
        name: 'Tom',
        data: function () {
          return { num: 1 }
        },
        template: `<div>
                        <div>Tom{{num}}</div>
                        <button @click='handler'>操作jerry</button>
                    </div>`,
        methods: {
          handler() {
            // 在事件中心下挂载tom  这里传的num是Tom
            hub.$emit('tom-com', this.num)
          }
        },
        // TODO: 通过hub.$on 去监听并触发事件
        created() {
          hub.$on('jerry-com', (val) => {
            console.log(val)
            this.num += val
          })
        }
      })
      // 组件2
      Vue.component('test-com2', {
        name: 'Jerry',
        data: function () {
          return { num: 2 }
        },
        template: `<div>
                        <div>Jerry{{num}}</div>
                        <button @click='handler'>操作Tom</button>
                    </div>`,
        methods: {
          handler() {
            // 在事件中心下挂载jerry 这里传的num是Jerry
            hub.$emit('jerry-com', this.num)
          }
        },
        // TODO: 通过hub.$on 去监听并触发事件
        created() {
          hub.$on('tom-com', (val) => {
            console.log(val)
            this.num += val
          })
        }
      })

      // Vue实例对象
      const vm = new Vue({
        el: '#app',
        methods: {
          handler() {
            hub.$off('jerry-com')
            hub.$off('tom-com')
          }
        }
      })
 </script>

4. Vuex(状态管理)

实现各组件间数据共享
state:共享数据源;
mutations:修改数据(state中的数据);
actions:异步请求;
getters:对共享数据进行包装(类似计算属性);
modules:模块化
vuex流程

5. ref

vm.$refs 一个对象,持有注册过 ref attribute 的所有 DOM 元素和组件实例。

$refs 只会在组件渲染完成之后生效,并且它们不是响应式的。

<input type="file" hidden ref="imgFile" @change="onUpdateAvatar" />
onUpdateAvatar() {
	  // this.$refs.imgFile 拿到对应的组件对象
      // 拿到文件对象
      const file = this.$refs.imgFile.files[0]
      // 清空input框
      this.$refs.imgFile.value = ''
    }

6. $parent / $children

 <div id="app">
        <p>{{msg}}</p>
        <test></test>
        <button @click="handleClick">change child</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-router@3.4.3/dist/vue-router.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuex@3.5.1/dist/vuex.min.js"></script>
<script>
        // 儿子
        Vue.component('test', {
            data() {
                return {
                    age: 18
                }
            },
            template: `
                <div>
                    <p>{{age}}</p>
                    <button @click="handleClick">click</button>    
                </div>
            `,
            methods: {
                handleClick() {
                    this.$parent.changeMsg('ifer');
                },
            },
        });
        // 父亲
        const vm = new Vue({
            el: '#app',
            name: 'App',
            data: {
                msg: 'hello world'
            },
            methods: {
                changeMsg(msg) {
                    this.msg = msg;
                },
                handleClick() {
                    // this.$children[0] 第 1 个子组件
                    this.$children[0].age = 19;
                }
            }
        });
</script>

7. provide / inject

<div id="app">
        <test1></test1>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-router@3.4.3/dist/vue-router.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuex@3.5.1/dist/vuex.min.js"></script>
<script>
        // 父亲
        Vue.component('test1', {
            template: '<div>test1 <test2></test2></div>'
        });
        // 儿子
        Vue.component('test2', {
            // #2 接受数据
            inject: ['msg'],
            template: '<div>test2 {{msg}}</div>'
        });
        // 爷爷
        const vm = new Vue({
            el: '#app',
            name: 'App',
            data: {},
            // #1 提供数据
            provide: {
                msg: 'hello'
            },
        });
</script>

8. $attrs / $listeners

vm.attrs 包含了父作用域中不作为 prop 被识别 (且获取) 的 attribute 绑定 (class 和 style除外)。
vm.$listeners 包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。

<div id="app">
        <test :msg="msg" @changemsg="changeMsg"></test>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-router@3.4.3/dist/vue-router.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuex@3.5.1/dist/vuex.min.js"></script>
    <script>
        // 儿子
        Vue.component('test', {
            template: `<div>
                <p>{{$attrs.msg}}</p>  
                <button @click="$listeners.changemsg('ifer')">change msg</button>  
            </div>`,
            mounted() {
            },
        });
        // 父亲
        const vm = new Vue({
            el: '#app',
            name: 'App',
            data: {
                msg: 'hello'
            },
            methods: {
                changeMsg(msg) {
                    this.msg = msg;
                }
            },
        });
</script>

9. localStorage/sessionStorage

利用浏览器本地存储

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值