vue项目中利用$attrs和$listeners达到简化代码结

2020-05-14  本文已影响0人  videring

在vue项目中,一个vue单文件里往往有多个弹框(以elementUI为了,那就是el-dialog组件),杂乱而繁多,在这里尝试以一种简化的方式来处理。

// vue单文件页面
<template>
  <div>
    <el-button @click="visible=true">打开弹窗</el-button>
    selectNumber:{{selectNumber}}
    <el-dialog
       :visible.sync="visible"
       :show-close="false"
       title="我是题目"
       width="400px"
       @close="closeDialog('hehe')">
          {{selectNumber}}
          <el-button @click="handleClick">Add</el-button>
          <el-button @click="handleClose">关闭</el-button>
     </el-dialog>
  </div>
</template>
<script>
export default {
  data() {
    return {
      selectNumber: 0,
      visible: false
    }
  }
 methods: {
    handleClick() {
      this.selectNumber +=1
    },
    closeDialog() {
      this.visible = false
      this.$message({ type: 'success', message: '关闭' })
    }
  }
}
</script>
  1. 通过MessageBox方式来处理逻辑较简单的弹窗效果,见官方示例MessageBox 弹框

  2. 通过mixin的方式组织代码使结构更清晰简洁,但是这种无法使template部分更为简洁

  3. 将弹框封装成组件,将弹框中的业务逻辑封装进组件,接着前例,改造如下:

// vue单文件页面
<template>
  <div>
    <el-button @click="visible=true">打开弹窗</el-button>
    selectNumber:{{selectNumber}}
    <test-dialog
           :visible.sync="visible"
           :show-close="false"
           title="我是题目"
           width="400px"
           :selectNumber.sync="selectNumber"
           @close="closeDialog('hehe')">
     </test-dialog>
  </div>
</template>
<script>
import testDialog from './testDialog.js'
export default {
  data() {
    return {
      selectNumber: 0,
      visible: false
    }
  },
  components: {
    testDialog
  },
  methods: {
    closeDialog() {
      this.visible = false
      this.$message({ type: 'success', message: '关闭' })
    }
  }
}
</script>

// test-dialog组件:

export default {
  name: 'testDialog',
  template: `
      <el-dialog v-bind="$attrs" :visible.sync="visible" v-on="$listeners">
          {{selectNumber}}
          {{this.$attrs}}
          <el-button @click="handleClick">Add</el-button>
          <el-button @click="handleClose">关闭</el-button>
      </el-dialog>
  `,
  props: {
    visible: false
  },
  data() {
    return {
      ...this.$attrs
    }
  },
  watch: {
    visible: {
      handler() {
        Object.keys(this.$attrs).forEach(attr => {
          this[attr] = this.$attrs[attr]
        })
      },
      deep: true,
      immediate: true,
    }
  },
  methods: {
    handleClick() {
      this.selectNumber += 1
      this.tableData.push(this.selectNumber)
    },
    handleClose() {
      this.$emit('update:visible', false)
      this.$emit('update:selectNumber', this.selectNumber)
      this.$emit('update:tableData', this.tableData)
    }
  },
  created() {
    // console.log('this.$attrs ', this, this.$attrs, new Date().valueOf())
  }
}

test-dialog组件主要用到了$attrs$listeners来达到透传的效果,通过.sync使得数据能更新到父组件中。从效果上来看,既达到了js的拆分,又实现了模板的拆分,同时部分变量(sync修饰的)达到了父子组件共享的效果。

上一篇 下一篇

猜你喜欢

热点阅读