【蓝桥杯】表单生成器(大学组)

仅做记录之用
index.html

<!DOCTYPE html>
<html lang="zn-CH">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <script src="./lib/vue.min.js"></script>
    <script src="./lib/axios.min.js"></script>
    <link rel="stylesheet" href="./css/index.css" />
    <title>表单生成器</title>
  </head>

  <body>
    <div id="app">
      <form>
        <div class="left-box">
          <!-- 组件容器 -->
          <div v-for="(item, i) in formData" :key="`${i}item`" class="item">
            <!-- 此处 label 为表单的标题 -->
            <div class="label">{{item.title}}</div>
            <!-- TODO: 根据 formData 中的 type 不同完成组件渲染  -->
            <template v-if="item.type=='select'"
              ><my-select :options="item.options" v-model="item.value"/></template>
            <template v-if="item.type=='checkbox'">
              <template v-for="(op, index) in item.options" :key="index">
                <my-checkbox :label="op.label" v-model="item.value">{{op.name}}</my-checkbox>
              </template>
            </template>
            <template v-if="item.type=='rate'"
              ><my-rate :options="item.options" v-model="item.value"
            /></template>
          </div>
        </div>
        <!-- 表单设置 -->
        <div class="right-box">
          <div>
            <button class="btn" @click="fetchData">初始化</button>
            <button class="btn" id="result" @click="confirm">获得数据</button>
            <button class="btn" id="render" @click="setData">渲染数据</button
            ><br /><br />
          </div>
          <textarea v-model="testData" cols="45" rows="12"></textarea>
          <div class="error" v-if="hasError">JSON 格式输入有误,请仔细检查</div>
        </div>
      </form>
    </div>
    <script src="./components/checkbox.js"></script>
    <script src="./components/select.js"></script>
    <script src="./components/rate.js"></script>
    <script>
      var app = new Vue({
        el: "#app",
        data: {
          formData: [],
          testData: "",
          hasError: false,
        },
        created() {
          this.fetchData();
        },
        methods: {
          async fetchData() {
            // 请求 JSON 数据
            const { data } = await axios.get("./data.json");
            this.formData = data.result;
            this.confirm();
          },
          // 设置数据
          setData(e) {
            e && e.preventDefault();
            try {
              const newData = JSON.parse(this.testData);
              this.formData = this.formData.map((x) => {
                x.value = newData[x.field];
                return x;
              });
              this.hasError = false;
            } catch (err) {
              if (err) {
                this.hasError = true;
              }
            }
          },
          // 获得数据
          confirm(e) {
            e && e.preventDefault();
            const params = {};
            this.formData.forEach(({ field, value }) => {
              params[field] = value;
            });
            this.testData = JSON.stringify(params, null, 2);
          },

          selectVal(item, v1){
            console.log(item,v1,"666")
          }
          
        },
      });
    </script>
  </body>
</html>


select.js

/*
 * 选择框组件
 */
const selectTemplate = `
<div class="select">
<div class="input" @click="openValue">
  <input id="selectVal" v-model="content" type="text" placeholder="请点击选择">
  <span class="tri" :class="{tri_up: show}"></span>
</div>
<div class="list" v-show="show">
  <ul>
    <li @click="getvalue(item)" v-for="(item,index) in listData" :key="item.index">{{ item.name }}</li>
  </ul>
</div>
</div>
`;
Vue.component("my-select", {
  template: selectTemplate,
  props: ["options", "value"],
  // TODO 请在此继续完成组件代码的编写
  data() {
    return {
      listData: this.options,
      show: false,
      content: "",
    };
  },
  created() {
    let id = this.options.findIndex((item) => item.label == this.value);
    console.log(id);
    if (id != -1) this.content = this.options[id].name;
  },
  watch: {
    value() {
      let id = this.options.findIndex((item) => item.label == this.value);
      console.log(id);
      if (id != -1) this.content = this.options[id].name;
    },
  },
  methods: {
    openValue() {
      this.show = !this.show;
    },
    getvalue(item) {
      this.content = item.name;
      this.show = !this.show;
      this.$emit("input", item.label);
    },
  },
});


checkbox.js


/*
 * 多选框组件
 */
const checkboxTemplate = `
<div class="radio-box">
  <input type="checkbox" :checked="isCheck" @change="change" :id="label">
  <label :for="label" class="radio-stype check-box"></label><span> <slot /> </span>
</div>
`;
Vue.component("my-checkbox", {
  template: checkboxTemplate,
  props: ["label", "value"],
  // TODO 请在此继续完成组件代码的编写
  data() {
    return {
      isCheck: this.value.includes(this.label),
    };
  },
  watch: {
    value() {
      this.isCheck = this.value.includes(this.label)
    },
  },
  methods: {
    change() {
      console.log(this.isCheck)
      this.isCheck = !this.isCheck
      let res = [...this.value]
      res = this.isCheck? res.push(this.label) : res.filter(i => i!=this.label)
      this.$emit('input', res)
    },
  },
});
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值