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: `
组件1:{ {pmsg}}
`
}) // 组件2与父组件之间的数据进行子传父 Vue.component('test-com2', { data: function () { return { msg: '我是组件2中的值' } }, template: `` }) // 组件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: `
Tom{ {num}}
`
, 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: `
Jerry{ {num}}
`
, 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:模块化
Vue组件通信_第1张图片

5. ref

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

<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 childbutton>
div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue-router.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuex.min.js"></script>
<script>
        // 儿子
        Vue.component('test', {
     
            data() {
     
                return {
     
                    age: 18
                }
            },
            template: `
                

{ {age}}

`
, 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/[email protected]/dist/vue-router.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuex.min.js"></script>
<script>
        // 父亲
        Vue.component('test1', {
     
            template: '
test1
'
}); // 儿子 Vue.component('test2', { // #2 接受数据 inject: ['msg'], template: '
test2 { {msg}}
'
}); // 爷爷 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/[email protected]/dist/vue-router.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuex.min.js"></script>
    <script>
        // 儿子
        Vue.component('test', {
     
            template: `

{ {$attrs.msg}}

`
, mounted() { }, }); // 父亲 const vm = new Vue({ el: '#app', name: 'App', data: { msg: 'hello' }, methods: { changeMsg(msg) { this.msg = msg; } }, }); </script>

9. localStorage/sessionStorage

利用浏览器本地存储

你可能感兴趣的:(vue,dom)