开发者社区> 问答> 正文

Vue数据传递--教你特殊的实现技巧

Vue数据传递--教你特殊的实现技巧

展开
收起
社区秘书 2019-12-16 14:40:53 919 0
1 条回答
写回答
取消 提交回答
  • 
    
    
    vuex
    
    不介绍,数据量和复杂度达不到不用它你才会向下看。
    
    props *demo*
    
    父子组件传值,官方api,只写个demo。
    
    1.父组件
    
    <son :info="info" @update="updateHandler"/>
    // data
    info: 'sendToSon'
    // methods
    updateHandler (newVal) {
     this.info = newVal
    }
    2.子组件
    
    // props
    props: ['info']
    // 向上传值,某个方法中使用
    this.$emit('update', 'got')
    父向子传值-->props 子向父传值-->子组件绑定事件回调定义在父组件,子组件触发此事件。 因不推荐子组件内直接修改父组件传入的props,需使用自定义事件。 限制 父子组件。 eventBus demo bus皆为导入的bus实例
    
    // bus
    const bus = new Vue()
    // 数据接收组件
    // 当前组件接收值则
    bus.$on('event1', (val)=>{})
    // 数据发出组件
    // 当前组件发出值则
    bus.$emit('event1', val)
    \//欢迎加入前端全栈开发交流圈一起学习交流:864305860
    可以看出本质是一个vue实例充当事件绑定的媒介。 在所有实例中使用其进行数据的通信。 双(多)方使用同名事件进行沟通。
    
    问题
    
    $emit时,必须已经 $on,否则将无法监听到事件,也就是说对组件是有一定的同时存在的要求的。(注:路由切换时,新路由组件先 created,旧路由组件再destoryed,部分情况可以分别写入这两个生命周期,见此问题)。 $on在组件销毁后不会自动解除绑定,若同一组件多次生成则会多次绑定事件,则会一次 $emit,多次响应,需额外处理。 数据非“长效”数据,无法保存,只在 $emit后生效。 所以是否有一种更适用的方案呢? 特殊的eventBus?
    
    demo
    
    我们先来看个代码,线上代码。 bus皆为导入的bus实例。
    
    // bus
    const bus = new Vue({
     data () {
      return {
       // 定义数据
       val1: ''
      }//欢迎加入前端全栈开发交流圈一起学习交流:864305860
     },
     created () {
      // 绑定监听
      this.$on('updateData1', (val)=>{
       this.val1 = val
      })
     }
    })
    // 数据发出组件
    import bus from 'xx/bus'
    // 触发在bus中已经绑定好的事件
    bus.$emit('update1', '123')
    // 数据接收组件
    
    {{val1}}
    // 使用computed接收数据
    computed () {
     val1 () {
      // 依赖并返回bus中的val1
      return bus.val1
     }
    }//欢迎加入前端全栈开发交流圈一起学习交流:864305860
    不同 正统的eventBus只是用来绑定和触发事件,并不关心数据,不与数据发生交集。而这个方案多一步将数据直接添加在bus实例上。且事件监听与数据添加需提前定义好。 数据接收方不再使用$on来得知数据变化,而是通过计算属性的特征被动接收。 解决的问题 通信组件需同时存在?数据在bus上存储,所以没有要求。 多次绑定?绑定监听都在bus上,不会重复绑定。 数据只在$emit后可用?使用计算属性直接读取存在bus上的值,不需要再次触发事件。
    探讨 为什么使用计算属性 其实应该是为什么不能直接添加到data上,如 data1: bus.data1?我们可以再看一段代码,线上代码。 将bus修改为
    data () {
     return {
      // 多一层结构
      val: {
       result: 0
      }//欢迎加入前端全栈开发交流圈一起学习交流:864305860
     }
    },
    created () {
     this.$on('update1', val => {
      console.log('触发1', i1++)
      this.val.result = val
     })
    }
    数据接收组件改为
    
    // template
    data中获取直接修改值:{{dataResult}}
    data中获取直接修改值的父层:{{dataVal}}
    computed中依赖直接修改值:{{computedResult}}
    // js//欢迎加入前端全栈开发交流圈一起学习交流:864305860
    data () {
      return {
       // 获取直接修改值
       dataResult: bus.val.result,
       // 获取直接修改值的父层
       dataVal: bus.val
      }
     },
     computed: {
      computedResult () {
       // 依赖直接修改值
       return bus.val.result
      }
     }//欢迎加入前端全栈开发交流圈一起学习交流:864305860
    可以看到,data中获取直接修改值值的数据是无法动态响应的。
    
    为什么要用事件
    
    其实不用$emit触发,使用 bus.val = 1直接赋值也是可以的,那么为什么不这么做呢? 简化版的vuex 其实这种eventBus就是简化版的vuex。 vue文档中有这样一段话: 组件不允许直接修改属于 store 实例的 state,而应执行 action 来分发 (dispatch) 事件通知 store 去改变,我们最终达成了 Flux 架构。这样约定的好处是,我们能够记录所有 store 中发生的 state 改变。 store对应 bus实例,state对应 data, action对应 事件, dispatch对应$emit。 同时vuex中组件获取数据的方式正是通过计算属性,那么其实vuex和Flux架构的理解和使用也没有那么难不是吗。
    
    结语
    
    感谢您的观看,如有不足之处,欢迎批评指正。
    
    2019-12-16 14:41:26
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
Vue.js 在前端服务化上的探索与实践 立即下载
利用编译将 Vue 组件转成 React 组件 立即下载
Vue.js在前端服务化上的实践与探索 立即下载