vue弹窗组件规范写法

402 阅读1分钟

以前问题

问题1: 弹窗内容确定和取消后,公用弹窗会出现数据没有清除掉的问题。
解决: 在关闭弹窗(点击取消或者确认时候),应当调用表单的resetFields()来对表单进行清除即可。

问题2: 在弹窗组件中使用v-if来控制弹窗的显示和销毁,会出现每次弹窗都需要销毁创建,并且没有自带的过渡动画显得弹窗效果生硬。
解决: 在父组件上使用v-if可以更符合vue的原则,但是不建议使用v-if来控制,因为这样也会导致动画效果没有,因此最好是父组件使用一个变量了控制引入的弹窗组件来动态控制弹窗显示与否。

代码例子: 弹窗组件:

<template>
  <div class="border">
    <h1>dialog、drawer等父子组件数据流演示</h1>
    <h1>Dialog的宽度,已依据UI规范重置,详见element.less文件</h1>
    <el-button @click="dialogTestVisible = true">弹窗测试</el-button>

    <!-- 不建议使用v-if控制显示(1、动画效果没有;2、接口频繁重复请求) -->
    <dialog-test :visible.sync="dialogTestVisible" :id="dialogTestId" @refresh="handleRefrersh"></dialog-test>
  </div>
</template>

<script>
export default {
  components: {
    DialogTest: () => import('./components/DialogTest')
  },
  data() {
    return {
      dialogTestVisible: false,
      dialogTestId: ''
    }
  },
  methods: {
    handleRefrersh() {

    },
  }
}
</script>

<style lang="less" scoped>
.border {
  height: calc(100vh - 112px);
  background: @white;
}
</style>

components/DialogTest.vue

<template>
  <el-dialog :visible="visible" :title="title" @close="handleClose">
    <!-- 123 -->
    <el-form :model="form" ref="form" :rules="rules" label-width="auto">
      <el-row :gutter="32">
        <el-col :span="12">
          <el-form-item label="规范测试">
            <el-input></el-input>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="规范测试">
            <el-input></el-input>
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>
    <el-button @click="handleSuccess">测试</el-button>
    <span slot="footer" class="dialog-footer">
      <el-button @click="handleClose" size="small">取 消</el-button>
      <el-button type="primary" size="small" @click="handleConfirm">确 定</el-button>
    </span>
  </el-dialog>
</template>

<script>
export default {
  props: {
    visible: {
      type: Boolean,
      default: false
    },
    id: {
      type: String | Number,
      default: ''
    }
  },
  watch: {
    visible(val) {
      if(val) {
        this.title = this.id ? '编辑' : '新增';
        if(this.id) {
          // 调接口或者拿传递进来的数据复显
        }
      }
    }
  },
  data() {
    return {
      title: '',
      form: {

      },
      rules: {

      }
    }
  },
  created() {
    // 请求一些选项数据等不长变化的项,不依赖id改变而变化的数据
  },
  methods: {
    handleSuccess() {
      this.$success({
        title: 'This is a success message',
        // JSX support
        content: (
          <div>
            <p>some messages...some messages...</p>
            <p>some messages...some messages...</p>
          </div>
        ),
      })
    },
    handleClose() {
      //使用update:visible对应的是:visible.sync="dialogTestVisible",也可以替换成使用@closeDialog来进行对弹窗的关闭
      this.$emit("update:visible", false);
      this.$refs.form.resetFields();//解决弹窗组件复用内容,数据保留的问题
    },
    handleConfirm() {
      this.$refs.form.validate((valid) => {
        if(valid) {
          
        }
      })
    }
  }
}
</script>

<style>

</style>

注意: Vue .sync修饰符与$emit(update:xxx)写法问题
使用.sync修饰符,即

    // this.$emit('update:father-num',100);  //无效
    this.$emit('update:fatherNum',100); //有效
    //......
    <father v-bind:father-num.sync="test"></father>

与不使用.sync,即

      this.$emit('update:father-num',100);  //有效
      //this.$emit('update:fatherNum',100); // 无效
      
      //......
     <father v-bind:father-num="test" v-on:update:father-num="test=$event" ></father>