博客 / 詳情

返回

vue2jsx遇到的小坑

最近在公司的代碼中遇到的一些坑,目前公司代碼質量有點蛇皮..(組件套組件被套用的組件只是一個表單,翻來翻去就為了看個破錶單...)雖然不是我寫的,但是在維護上確實有點麻煩... 索性直接用jsx抽個表單.

依賴:

"@vue/babel-helper-vue-jsx-merge-props": "^1.4.0",
"@vue/babel-preset-jsx": "^1.4.0",
"element-ui": "^2.15.13",
"vue": "^2.6.14"

練習項目圖省事直接用的cli

廢話不多説直接上代碼:
傳入對象: dataObj dataObj2 是一樣的 我把這兩個組件都引到了同一個頁面去測試,省事

  dataObj2: {
    type: "add",// info
    list: [
      {
        label: "input框",
        prop: "name",
        type: "input",
        value: "123",
        disabled: false,
        attrs: {
          placeholder: "請輸入name",
          onInput:(e)=>{
            console.log('%c [ arrts裏面的input ]-', 'font-size:13px; background:pink; color:#bf2c9f;', e)
          }
        },
        event: {
          input: (e) => {
            console.log(
              "%c [ onInput input dataObj2]-",
              "font-size:13px; background:skyblue; color:#bf2c9f;",
              e
            );
          },
          onInput: (e) => {
            console.log(
              "%c [ onInput input dataObj222]-",
              "font-size:13px; background:skyblue; color:#bf2c9f;",
              e
            );
          },
          onChange: (e) => {
            console.log(
              "%c [ onChange change dataObj2]-",
              "font-size:13px; background:skyblue; color:#bf2c9f;",
              e
            );
          },
        },
      },
      {
        label: "select框",
        prop: "desc",
        type: "select",
        value: "",
        option: [
          { label: "活動一", value: "huodong1" },
          { label: "活動二", value: "huodong2" },
        ],
      },
      {
        label: "radio單選框",
        prop: "radio",
        type: "radio",
        value: "",
        option: [
          { label: "單選框一", value: "radio1" },
          { label: "單選框二", value: "radio2" },
        ],
      },
      {
        label: "input框2",
        prop: "name2",
        type: "input",
        value: "",
        disabled: false,
        attrs: {
          placeholder: "請輸入name2",
        },
        event: {
          input: (e) => {
            console.log(
              "%c [ e input ]-",
              "font-size:13px; background:skyblue; color:#bf2c9f;",
              e
            );
          },
          change: (e) => {
            console.log(
              "%c [ e change ]-",
              "font-size:13px; background:skyblue; color:#bf2c9f;",
              e
            );
          },
        },
      },
    ],
    rules: {
      name: [
        { required: true, message: "請輸入活動名稱", trigger: "blur" },
      ],
      desc: [
        { required: true, message: "請輸入活動形式", trigger: "blur" },
      ],
      name2: [
        { required: true, message: "請輸入活動名稱2", trigger: "blur" },
      ],
    },
    labelWidth: "100px",
  }

jsx版:

結構
<div class="form-box">
  <helloJsx :datas="dataObj2" @saveSubmit="submit2"></helloJsx>
</div>

組件代碼:

<script>
export default {
  props: ["datas"],
  data() {
    return {
      form: {},
    };
  },
  methods: {
    html() {
      return (
        <div>
          {this.datas.refFormName}
          <el-form
            label-width={this.datas.labelWidth}
            ref="onlyForm"
            class="class-form"
            rules={this.datas.rules}
            props={{ model: this.form }}
          >
            {this.datas.list.map((e) => (
              <el-form-item label={e.label} prop={e.prop}>
                {e.type === "input" ? (
                  <el-input
                    v-model={this.form[e.prop]}
                    {...{ on: { ...e.event } }}
                    {...{ attrs: e.attrs }}
                    disabled={
                      e.disabled
                        ? e.disabled
                        : this.datas.type === "info"
                        ? true
                        : false
                    }
                  ></el-input>
                ) : (
                  ""
                )}
                {e.type === "select" ? (
                  <el-select
                    v-model={this.form[e.prop]}
                    {...{ on: { ...e.event } }}
                    {...{ attrs: e.attrs }}
                    disabled={
                      e.disabled
                        ? e.disabled
                        : this.datas.type === "info"
                        ? true
                        : false
                    }
                  >
                    {e.option.map((s) => {
                      return (
                        <el-option label={s.label} value={s.value}></el-option>
                      );
                    })}
                  </el-select>
                ) : (
                  ""
                )}
                {e.type === "radio" ? (
                  <el-radio-group
                    v-model={this.form[e.prop]}
                    disabled={
                      e.disabled
                        ? e.disabled
                        : this.datas.type === "info"
                        ? true
                        : false
                    }
                    {...{ on: { ...e.event } }}
                    {...{ attrs: e.attrs }}
                  >
                    {e.option.map((e) => {
                      return (
                        <el-radio label={e.value}>{e.label}</el-radio>
                      );
                    })}
                  </el-radio-group>
                ) : (
                  ""
                )}
              </el-form-item>
            ))}
            {this.datas.type !== "info" ? (
              <el-form-item>
                <el-button type="primary" onClick={this.submitForm}>
                  立即創建
                </el-button>
                <el-button onClick={this.resetForm}>重置</el-button>
              </el-form-item>
            ) : (
              ""
            )}
          </el-form>
        </div>
      );
    },
    submitForm() {
      this.$refs["onlyForm"].validate((valid) => {
        if (valid) {
          console.log(
            "%c [ data-submit2 ]-",
            "font-size:13px; background:skyblue; color:#bf2c9f;",
            2222
          );
          this.$emit("saveSubmit", this.form);
        } else {
          console.log("error222 submit!!");
          return false;
        }
      });
    },
    resetForm() {
      this.$refs["onlyForm"].resetFields();
    },
  },
  render() {
    return this.html();
  },
};
</script>


<style scoped>
.class-form {
  width: 300px;
}
</style>

組件複用版:
結構

<h3>循環配置項</h3>
<div class="form-box">
  <myForm :datas="dataObj" @submit="submit" @back="back"></myForm>
</div>

組件代碼:

<template>
  <div>
    <el-form
      :label-width="datas.labelWidth"
      :ref="datas.refFormName"
      class="class-form"
      :rules="datas.rules"
      :model="form"
    >
      <el-form-item
        :label="item.label"
        :prop="item.prop"
        v-for="(item, index) in datas.list"
        :key="index"
      >
        <el-input
          v-if="item.type === 'input'"
          v-model="form[item.prop]"
          :disabled="
            item.disabled ? item.disabled : datas.type === 'info' ? true : false
          "
          v-bind="{ ...item.attrs }"
          v-on="{ ...item.event }"
        ></el-input>
        <el-select
          v-if="item.type === 'select'"
          v-model="form[item.prop]"
          :placeholder="'請選擇' + item.label"
          :disabled="
            item.disabled ? item.disabled : datas.type === 'info' ? true : false
          "
        >
          <el-option
            :label="i.label"
            :value="i.value"
            v-for="i in item.option"
            :key="i.value"
          ></el-option>
        </el-select>
        <el-radio-group
          v-if="item.type === 'radio'"
          v-model="form[item.prop]"
          :disabled="
            item.disabled ? item.disabled : datas.type === 'info' ? true : false
          "
        >
          <el-radio :label="i.value" v-for="i in item.option" :key="i.value">{{
            i.label
          }}</el-radio>
        </el-radio-group>
      </el-form-item>
      <el-form-item v-if="datas.type !== 'info'">
        <el-button type="primary" @click="submitForm('ruleForm')"
          >立即創建</el-button
        >
        <el-button @click="resetForm('ruleForm')">重置</el-button>
      </el-form-item>
      <el-form-item v-else>
        <el-button @click="back('ruleForm')">關閉</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<script>
export default {
  name: "Demo02MyForm",
  props: {
    datas: {
      type: Object,
      require: true,
      default: () => {
        return {
          type: "add", // add edit info
          list: [],
          rules: {},
          labelWidth: "100px",
          refFormName: "form",
        };
      },
    },
  },
  data() {
    return {
      form: {},
    };
  },

  mounted() {
    this.initData();
  },

  methods: {
    initData() {
      const obj = {};
      this.datas.list.forEach((e) => {
        obj[e.prop] = obj[e.value] ? obj[e.value] : "";
      });
      this.form = obj;
      if (this.datas.type !== "add") {
        for (const key in this.form) {
          this.datas.list.forEach((e) => {
            if (e.prop === key) {
              this.form[key] = e.value;
            }
          });
        }
      }
    },
    submitForm() {
      this.$refs[this.datas.refFormName].validate((valid) => {
        if (valid) {
          this.$emit("submit", this.form);
        } else {
          console.log("error submit!!");
          return false;
        }
      });
    },
    resetForm() {
      this.$refs[this.datas.refFormName].resetFields();
    },
    back() {
      this.$emit("back", false);
    },
  },
};
</script>

<style scoped>
.class-form {
  width: 300px;
}
</style>
user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.