• vue: 从组件通讯到vuex (上)


    关于vue之间的组件通讯

    1: prop,refs 父组件 => 子组件

    1) prop

    // app.vue
    
    <template>
      <div id="app">
        <childTest1 :msg="msg"/>
      </div>
    </template>
    
    <script>
    import childTest1 from './components/childTest1'
    
    export default {
      name: 'App',
      data () {
        return {
          msg: 'data from parent'
        }
      },
      methods: {
      },
      components: {
        childTest1
      }
    }
    </script>

    // childTest1.vue
    <template>
      <div class="hello">
        {{msg}}
      </div>
    </template>
    
    <script>
    export default {
      name: 'childTest1',
      props: ['msg'],
      data () {
        return {
          msgTest2: null
        }
      },
      methods: {
      }
    }
    </script>

    2) refs

    // app.vue
    <template>
      <div id="app">
        <childTest1 :msg="msg" ref="childTest1"/>
      </div>
    </template>
    
    <script>
    import childTest1 from './components/childTest1'
    
    export default {
      name: 'App',
      data () {
        return {
          msg: 'data from parent'
        }
      },
      created () {
        // 无效
        this.$refs.childTest1.setMsgTest2('refs set msg test')
      },
      mounted () {
        this.$refs.childTest1.setMsgTest2('refs set msg test')
      },
      methods: {
    
      },
      components: {
        childTest1
      }
    }
    </script>
    // childTest1.vue
    
    <template>
      <div class="hello">
        <p>{{msg}}</p>
        <p style="color: #f80000">{{msgTest2}}</p>
      </div>
    </template>
    
    <script>
    export default {
      name: 'childTest1',
      props: ['msg'],
      data () {
        return {
          msgTest2: null
        }
      },
      methods: {
        setMsgTest2 (val) {
          this.msgTest2 = val
        }
      }
    }
    </script>

    2 : $emit 子组件 => 父组件

    // App.vue
    
    <template>
      <div id="app">
    
        <childTest1 :msg="msg" ref="childTest1" @changeMsg="setMsg"/>
      </div>
    </template>
    
    <script>
    import childTest1 from './components/childTest1'
    
    export default {
      name: 'App',
      data () {
        return {
          msg: 'data from parent'
        }
      },
      created () {
        // 无效
        this.$refs.childTest1.setMsgTest2('refs set msg test')
      },
      mounted () {
        this.$refs.childTest1.setMsgTest2('refs set msg test')
      },
      methods: {
        setMsg (val) {
          this.msg = val
        }
    
      },
      components: {
        childTest1
      }
    }
    </script>
    // childTest1.vue
    <template>
      <div class="hello">
        <p>{{msg}}</p>
        <p style="color: #f80000">{{msgTest2}}</p>
        <button @click="changeMsg">changeMsg</button>
      </div>
    </template>
    
    <script>
    export default {
      name: 'childTest1',
      props: ['msg'],
      data () {
        return {
          msgTest2: null
        }
      },
      methods: {
        setMsgTest2 (val) {
          this.msgTest2 = val
        },
        changeMsg () {
          this.$emit('changeMsg', 'child change test msg')
        }
      }
    }
    </script>

    上面是简单的组件通讯,简单的父子组件传递可以使用上述形式,当比较复杂的情况下, 或者组件是相互独立,而且中间一个发生变化另一个变化的时候可以使用vue bus。

    3: vue bus 独立组件 => 独立组件 (父 => 子 子 => 父)

    // app.Vue
    
    <template>
      <div id="app">
        {{parentMsg}}
        <childTest1 :msg="msg" ref="childTest1" @changeMsg="setMsg"/>
        <ChildTest2 />
      </div>
    </template>
    
    <script>
    import ChildTest1 from './components/ChildTest1'
    import ChildTest2 from './components/ChildTest2'
    import ChildTestBus from './bus/ChildTest'
    
    export default {
      name: 'App',
      data () {
        return {
          parentMsg: 'parent init msg',
          msg: 'data from parent'
        }
      },
      created () {
        ChildTestBus.$on('changeMsg', val => this.setParentMsg(val))
        // 无效
        this.$refs.childTest1.setMsgTest2('refs set msg test')
      },
      mounted () {
        this.$refs.childTest1.setMsgTest2('refs set msg test')
      },
      destrory () {
        ChildTestBus.$off('changeMsg')
      },
      methods: {
        setParentMsg (val) {
          this.parentMsg = val
        },
        setMsg (val) {
          this.msg = val
        }
    
      },
      components: {
        ChildTest1,
        ChildTest2
      }
    }
    </script>
    // ChildTest1.vue
    
    <template>
      <div class="hello">
        <p>{{msg}}</p>
        <p style="color: #f80000">{{msgTest2}}</p>
        <button @click="changeMsg">changeMsg</button>
        <button @click="changeParentMsg" style="background: #ddd">changeMsgFromTest1</button>
      </div>
    </template>
    
    <script>
    import ChildTestBus from '../bus/ChildTest'
    export default {
      name: 'ChildTest1',
      props: ['msg'],
      data () {
        return {
          msgTest2: null
        }
      },
      methods: {
        setMsgTest2 (val) {
          this.msgTest2 = val
        },
        changeMsg () {
          this.$emit('changeMsg', 'child change test msg')
        },
        changeParentMsg () {
          ChildTestBus.$emit('changeMsg', 'change msg from childTest1')
        }
      }
    }
    </script>
    
    <!-- Add "scoped" attribute to limit CSS to this component only -->
    <style scoped>
    </style>
    // ChildTest2.vue
    
    <template>
      <div class="hello">
        <p style="color: blue">{{msgTest2}}</p>
        <button @click="changeMsg">changeMsgFromTest2</button>
      </div>
    </template>
    
    <script>
    import ChildTestBus from '../bus/ChildTest'
    export default {
      name: 'ChildTest2',
      props: ['msg'],
      data () {
        return {
          msgTest2: 'msg in childTest2'
        }
      },
      methods: {
        changeMsg () {
          ChildTestBus.$emit('changeMsg', 'change msg from childTest2')
        }
      }
    }
    </script>
    
    <!-- Add "scoped" attribute to limit CSS to this component only -->
    <style scoped>
    </style>
    // ChildTest.js
    
    import Vue from 'Vue'
    export default new Vue()

    上述就可以实现复杂点的组件通讯了,这里有着注意点,当你使用bus时,通过$on事件获取消失时,得在组件注销时解除监听。

    这个的缺点时当你的应用比较大时,这个触发和监听信息的代码需要在多处使用,这样我们就需要统一管理了,既便于维护,也方便理解

    这个时候就可以用到vuex ,详情下级分解

  • 相关阅读:
    NO.05--谈一谈Angular 和 Vue.js 的对比。
    NO.04--我的使用心得之使用vue绑定class名
    No.03---Vue学习之路之模块化组织
    NO.02---聊聊Vue提升
    NO.01---今天聊聊Vuex的简单入门
    hello word!------为什么开通博客以及自我介绍
    JavaScript 常用正则示例
    Newtonsoft.Json(Json.Net)学习笔记
    aspx后台传递Json到前台的两种接收方法
    MVC5中后台提供Json,前台处理Json,绑定给Dropdownlist的例子
  • 原文地址:https://www.cnblogs.com/mapletao/p/8495077.html
Copyright © 2020-2023  润新知