vue组件开发-数据处理

2021-09-28  本文已影响0人  瓢鳍小虾虎
  1. 数据在哪里,对数据的操作就放到哪里,如果子组件需要操作数据,把数据操作的方法通过props传进去,更好的方式是子组件对外传递一个自定义事件。

  2. 父子/兄弟组件共用数据的时候,如果对象数据是通过props传进来的,尽量不要直接双向绑定对象数据的属性去替代数据的操作,违反props不可更改的原则。也不利于维护。可以考虑计算属性。

  3. 数据既要初始化又要交互修改,可以使用双向绑定data或者双向绑定计算属性,如果使用了计算属性(一般会从props或者store获取值计算),需要配置get和set

  4. 跨层级的组件通信可以使用provide/inject实现。(vue2.2.0以上版本支持)这个技术概念上类似于react的内容上下文传递数据的方式。

  5. 复杂的多组件数据通信还可以使用事件总线技术。

import Vue from 'vue'
import App from './App.vue'

Vue.config.productionTip = false // 关闭Vue生产提示

new Vue({
  render: h => h(App),
  beforeCreate() {
    Vue.prototype.$bus = this // 安装全局事件总线
  }
}).$mount('#app')

接收消息子组件中

mouted() {
  this.$bus.$on('eventName', (v)=>{
  // 处理回调
  })
},
beforeDestroy() {
  his.$bus.$off('eventName') // 参数支持单个字符串或者字符串数组,千万别不传参数,会注销所有event
}

发起消息子组件中

this.$bus.$emit('eventName', {})

使用的要注意命名规范(比如‘bus_业务组件名_eventAbc’),避免冲突,或者准备一个全局常量文件,事件名都配置在这里共同使用。

事件总线比较适合用于跨度比较大的组件之间通讯,比如父组件和孙子组件,或者兄弟组件。

事件总线也是发布订阅模式的体现,我们还可以使用第三方的库比如pubsub-js来实现发布订阅模式。

安装:

npm i pubsub-js

使用:

import pubsub from 'pubsub-js'
// ...
mouted() {
  this.pubId = pubsub.subscribe('msgname', (msgname, data)=>{
  // 处理回调
  })
},
beforeDestroy() {
  pubsub.unsubscribe(this.pubId)
}
  1. 对数组的操作不要使用"arr[0] = xxx"这种形式,不会被vue监视到,要使用数组操作的方法如unshift、push、splice或者扩展表达式等等,数组数据累计操作可以使用reduce代替传统for循环。

  2. 如果表单类数据在提交到后台之前怕丢失(用户刷新或者其他操作导致),可以存在localStorage或者sessionStorage中

localStorage.setItem('key', JSON.stringify(v))
  1. 假如数组中存放的是对象数据,如果需要监视数据需要在watch中开启深度监视,因为默认vue只会监视对象的一层属性
watch: {
  arr: {
    deep: true,
    handler(d) {
    // ...
    }
  }
}
  1. 组件内部交互相关的状态数据,不一定非要明确定义到data中,也不需要外部传入,在交互行为过程中动态添加就可以。如果组件嵌套和交互过于复杂,就需要考虑拆组件。
// ...
handleEdit(listItem) {
   if (listItem.hasOwnProperty('isEdit')) {
    listItem.isEdit = true
  } else {
    this.$set(listItem, 'isEdit', true)
  }
},
handleBlur(listItem) {
  listItem.isEdit = false
}

  1. 如果输入框还没有进入文档流,或者被隐藏,同时你需要在交互handle中让组件显示并且获得焦点,记得使用$nextTick,因为这种情况下js函数会先执行完,然后vue才会去重新解析模板、操作dom,最终导致获得焦点失败。

一句话来说就是如果你要操作更新后的dom,就用nextTick。

handleEdit(listItem, event) {
   if (listItem.hasOwnProperty('isEdit')) {
    listItem.isEdit = true
  } else {
    this.$set(listItem, 'isEdit', true)
  }

  this.$nextTick(() => {
    event.target.focus()
  })
  
},
  1. 随着需求扩展,原先的组件可能会需要包含各种分支结构,但是这些结构又不好抽离成业务组件,这时可以考虑使用插槽(slot)来解耦组件。分隔组件内部结构的时候尽量使用template标签,可以避免不必要的dom创建。

  2. 另外提一下mixins,他也可以同于解耦组件功能,并且可以多个mixin组合使用,也就是说,mixin中包含和当前组件同名的钩子的时候,代码逻辑可以合并在一起执行。mixins

上一篇 下一篇

猜你喜欢

热点阅读