仅做记录之用
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)
},
},
});