Vue动态表单的应用详解
时间:2022-11-15 09:47:32|栏目:vue|点击: 次
概述
后台管理系统里面有非常多的表单需求,我们希望能够通过写一个json格式的数据,通过vue的循环动态地去渲染动态表单。并且能够在外部得到渲染出来的表单数据,从而做一个入库操作。
v-model的理解
vue-model相当于给表单元素传递一个value,外部监听input事件。所以我们自己封装表单组件的时候也是可以传递一个value值,监听input事件获取输入的值。
<input type="text" v-model="thing"> <!-- 等同于 --> <input type="text" v-bind:value="thing" v-on:input="thing = $event.target.value">
业务应用场景
最近在写一个在线教育平台,发现在后台添加课程的时候,每个课程所需要的参数不一样(有的课程没有特殊参数),使用固定表单在这个场景下使用很不优雅,而且工作量巨大。为了解决这个问题,我们可以在添加课程的时候动态的展示出课程分类表单所需要的参数,获取输入的课程参数,构造数据,进行入库操作。
通过组件展示分类
<!-- reply.vue --> <template> <div> <li> <div v-if="data.id != 0" @click="getfid(data.id)" :id="data.id"> {{ data.name }}</div> <ul v-if="data.children && data.children.length > 0"> <Reply v-for="child in data.children" :key="child.id" :data="child"/> </ul> </li> </div> </template> <script> import bus from './bus.js'; export default { //声明名称 name: "Reply", props: ['data'], //声明组件 components: {}, //声明变量 data() { return { fid: 0, } }, //自定义过滤器 filters: { myfilter: function (value) { value = value.slice(0, 3); return value + "********"; } }, //初始化方法 mounted() { }, //声明方法 methods: { //点选分类id getfid: function (fid) { this.fid = fid; //console.log(this.fid); bus.$emit("msg", fid); localStorage.setItem("fid", this.fid); //取消所有高亮 var divs = document.getElementsByClassName("bg"); //遍历选择器 for (var i = divs.length - 1; i >= 0; i--) { //取消高亮 divs[i].classList.remove("bg"); } //首先将当前元素高亮显示 var mydiv = document.getElementById(fid); //动态添加高亮类选择器 mydiv.classList.add("bg"); } } } </script> <style> ul { padding-left: 10rem; list-style: none; } .bg { background: orange; color: white; } </style>
采用第三方组件监听分类的ID
<!--bus.js--> import Vue from 'vue' export default new Vue();
课程添加页面
<template> <div> <heads></heads> <h1>课程提交页面</h1> <reply :data="mydata"/> <van-cell-group> <van-field label="课程标题" v-model="title"/> <van-field label="课程描述" v-model="desc" rows="5" type="textarea"/> <van-field label="课程价格" v-model="price"/> <div v-for="(value,key,index) in params"> <van-field :label="key" v-model="info[key]"/> </div> <van-button color="gray" @click="addcourse">保存课程</van-button> </van-cell-group> </div> </template> <script> //导入其他组件 import bus from './bus.js'; import reply from "./reply"; import heads from "./heads"; export default { //声明组件 components: { 'reply': reply, 'heads': heads, }, //构造方法 created() { //监听 bus.$on('msg', target => { console.log(target); this.fid = target; if (this.cid === 0) { this.get_cate(this.fid) } else { this.$toast.fail("您已经保存过课程了,无法再次选择分类"); return false; } }); }, //声明变量 data() { return { //数据 mydata: {}, //课程分类id fid: localStorage.getItem("fid"), title: "", price: "", desc: "", cid: 0, videos: [], videosrc: "", params: {}, info: {} } }, //初始化方法 mounted() { this.get_data(); }, //声明方法 methods: { get_cate(fid) { this.axios.get('http://localhost:5000/getcate/', {params: {'fid': fid}}).then(result => { var myparams = result.data.params; if (myparams === '') { myparams = null } myparams = JSON.parse(myparams) this.params = myparams for (var key in this.params) { this.$set(this.info, key, '') } console.log(this.info) }) }, //添加课程 addcourse: function () { var lists = []; for (var key in this.info) { lists.push({'key': key, 'value': this.info[key], 'label': this.params[key]}) } var list_str = JSON.stringify(lists) var data_post = { fid: this.fid, title: this.title, desc: this.desc, price: this.price, id: localStorage.getItem("user_id"), } if (lists.length > 0) { data_post = { fid: this.fid, title: this.title, desc: this.desc, price: this.price, id: localStorage.getItem("user_id"), params:list_str } } this.axios.post( 'http://localhost:5000/addcourse/', this.qs.stringify(data_post)).then((result) => { if (result.data.code === 200) { this.$toast.success('课程添加成功'); this.cid = result.data.cid; } else { this.$toast.fail(result.data.msg); } }); }, //获取数据 get_data: function () { //发送请求 this.axios.get( 'http://localhost:5000/catelist/').then((result) => { console.log(result); // 声明根节点 var mytree = {'id': 0, name: ""}; mytree['children'] = result.data; this.mydata = mytree; console.log(this.mydata); }); } } } </script> <style scoped> ul { padding-left: 10rem; list-style: none; } </style>
小结
简单的来说,就是我们在添加课程的时候选择分类,会以表单的形式动态展示出该分类下面我们必传的参数,用户添加课程,提高效率。