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>

小结

简单的来说,就是我们在添加课程的时候选择分类,会以表单的形式动态展示出该分类下面我们必传的参数,用户添加课程,提高效率。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 详解Vue+Element的动态表单,动态表格(后端发送配置,前端动态生成)

    动态表单生成 ElementUI官网引导 Element表单生成 Element动态增减表单,在线代码 关键配置 template中,form和form-item的写法和绑定 data里的值为空 methods中,向后台获取数据的函数写法  1. form,form-item,input的写法[^code] <el-form :model="dynamicValidateForm" label-width="120px" ref="dynamicVa

  • 策略模式实现 Vue 动态表单验证的方法

    策略模式(Strategy Pattern)又称政策模式,其定义一系列的算法,把它们一个个封装起来,并且使它们可以互相替换.封装的策略算法一般是独立的,策略模式根据输入来调整采用哪个算法.关键是策略的 实现和使用分离 . 注意:本文可能用到一些编码技巧比如 IIFE(Immediately Invoked Function Expression, 立即调用函数表达式),ES6 的语法 let/const.箭头函数.rest 参数,短路运算符 等,如果还没接触过可以点击链接稍加学习 ~ 1. 你曾

  • 基于Vue+elementUI实现动态表单的校验功能(根据条件动态切换校验格式)

    前言 开发过程中遇到了一个需求,根据用户选择的联系方式,动态改变输入框的检验条件,并且整个表单是可以增加的 在线访问:动态表单校验 github(欢迎star): https://github.com/Mrblackant. .. 思考几个问题 1.整个表单是可新增的,所以要遍历生成: 2.联系方式(手机/座机)的切换,是要切换后边不同类型输入框还是只改变校验规则(本篇是动态改变校验规则) 实现 1.elementui的form表单实现校验的时候要给当前el-form-item加上prop属性,

  • Vue+Element实现动态生成新表单并添加验证功能

    首先有一个这样的需求,表单中默认有一个联系人信息,用户可以再添加新的联系人信息 点击添加更多联系人之后 官方文档中有写用v-for来实现新增表单,但是那是单表单的新增,现在多表单的新增,可以考虑的实现方法是先写死一个必须的表单,需要新增的两个表单放在一个div里,在div中使用v-for生成,达到同时新增的效果 代码如下 //必填一个联系人的表单 <el-form-item class="rules" label="通知对象:" prop="noti

  • vue2 中如何实现动态表单增删改查实例

    最近项目中遇到的需求是要操作大量的表单,之前的项目中有做过这方的研究,只不过是用jquery来操作. 项目A 先简单说说以前项目A中的应用场景,可能有小伙伴儿也遇到相同的需求.A项目是公司的OA系统中有的项目,是用java的jsp渲染的页面,需求是要改成:嵌入APP中显示,前后端分离, 后端返回的内容,还不能修改, 只是后端同事做了下接口处理,返回给前端的是一大堆的表单数据. 每个表单都有多个字段表示它的属性: 是否可编辑 表单类型 (text, textarea, select, radio,

  • Vue+ElementUI实现表单动态渲染、可视化配置的方法

    动态渲染就是有一个异步的数据,大概长这样: { "inline": true, "labelPosition": "right", "labelWidth": "", "size": "small", "statusIcon": true, "formItemList": [ { "type": "

  • vue 动态表单开发方法案例详解

    本文实例讲述了vue 动态表单开发方法.分享给大家供大家参考,具体如下: 概要 动态表单指的是我们的表单不是通过vue 组件一个个编写的,我们的表单是根据后端生成的vue模板,在前端通过vue构建出来的.主要的思路是,在后端生成vue的模板,前端通过ajax的方式加载后端的表单模板,权限数据和表单数据,在前端使用vue进行构建出来. 表单渲染过程. 实现步骤 1.在前端开发表单组件,比如用户组件,文本输入组件. 在平台中我们可以看到我们开发的组件. 组件的开发在第三篇有介绍. 我们定义的组件和后

  • vue构建动态表单的方法示例

    概述 后台管理系统里面有非常多的表单需求,我们希望能够通过写一个json格式的数据,通过vue的循环动态地去渲染动态表单.并且能够在外部得到渲染出来的表单的数据,可以对表单进行重置操作.我结合element ui的控件的下拉框,输入框,时间选择控件和vue-treeselect,做了一个动态表单. v-model的理解 先简单讲一下vue-model是怎么玩的.其实vue-model相当于给表单元素传递一个value,外部监听input事件.所以我们自己封装表单组件的时候也是可以传递一个valu

  • vue+element实现动态加载表单

    本文实例为大家分享了vue+element实现动态加载表单的具体代码,供大家参考,具体内容如下 一.问卷动态加载表单 //html <el-form :model="quesPaper" status-icon label-width="100px" label-position="top" size="small" v-loading="paperLoading" > <el-form-

  • 使用Vue生成动态表单

    开需求会了,产品说这次需求的表单比较多,目前有18个,后期的表单可能会有增加.修改.我作为这次的前端开发,看到这样的需求,心里知道要这样搞不得把自己累死,首先表单居多,还会有变更,以后维护起来也让人心力憔悴. 于是我提议做动态表单,做一个表单的配置系统,在系统里配置表单类型.表单得字段.以及对表单得管理.后来重新评审了需求,系统部分由后端自行开发,我要处理的部分是动态生成表单,展现提交的表单,以及对表单的处理情况. 数据接口设计 表单类型的接口就不用说了,这个比较简单.我跟后端约定了一个预备创建

随机推荐