代码的配置化

背景

我们都知道,业务数据可以通过后台API进行提交或者展示的,那么前端代码是否也可以通过后台API返回的方式进行动态的展示呢?

我们先来看看,后台给我们返回的是什么?后台返回给我们的无非就是对象或者数组,那么我们将表单的formItem,都写成数组模式呢?

简单的例子

我们以一个简单的表单为例子
插入

这是Vue的模板写法

<template>
  <div class="">
    <el-row>
      <el-col :span="5" :offset="10">
        <el-form ref="form" :model="form" label-width="80px">
          <el-form-item label="姓名">
            <el-input v-model="form.name"></el-input>
          </el-form-item>
          <el-form-item label="性别">
            <el-select v-model="form.region" placeholder="性别">
              <el-option label="男" value="1"></el-option>
              <el-option label="女" value="2"></el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="店时间">
            <el-col :span="11">
              <el-date-picker type="date" placeholder="选择日期" v-model="form.date1" style="width: 100%;"></el-date-picker>
            </el-col>
            <el-col class="line" :span="2">-</el-col>
            <el-col :span="11">
              <el-time-picker placeholder="选择时间" v-model="form.date2" style="width: 100%;"></el-time-picker>
            </el-col>
          </el-form-item>
          <el-form-item label="是否会员">
            <el-switch v-model="form.delivery"></el-switch>
          </el-form-item>
          <el-form-item label="意向商品">
            <el-checkbox-group v-model="form.type">
              <el-checkbox label="美食" name="type"></el-checkbox>
              <el-checkbox label="家具" name="type"></el-checkbox>
              <el-checkbox label="玩具" name="type"></el-checkbox>
              <el-checkbox label="美妆" name="type"></el-checkbox>
            </el-checkbox-group>
          </el-form-item>
          <el-form-item label="备注">
            <el-input type="textarea" v-model="form.desc"></el-input>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" >保存</el-button>
          </el-form-item>
        </el-form>
        </el-col>
    </el-row>
  </div>
</template>
<script>
  export default {
    data() {
      return {
        form: {
          name: '',
          region: '',
          date1: '',
          date2: '',
          delivery: false,
          type: [],
          resource: '',
          desc: ''
        }
      }
    },
    created(){
    
    },
    methods: {
     
    }
  }
</script>

在这个表单中,每一个输入内容均由一个el-form-item包裹起来,我们可以尝试通过for循环将代码渲染。

将前端代码放到data中,用数组装起来,通过v-for进行渲染:

<el-form-item :key="item.itemId" v-for="item in formItemList" :label="item.label">
	<component 
		:is="item.component"
		:codeFiled="item.code"
		:type="item.type"
		:proOptionData="item.proOptionData"
		:code="form[item.code]"
		@changeCode="getCode"
	/>
</el-form-item>
formItemList:[
          {
            itemId:'itemId1',
            label:'姓名',
            code:'name',
            component:() => import('@/components/input')
          },
          {
            itemId:'itemId2',
            label:'性别',
            code:'region',
            component:() => import('@/components/select'),
            proOptionData:[
              {
                value:'1',
                label:'男'
              },
              {
                value:'2',
                label:'女'
              },
            ]
          },
          {
            itemId:'itemId3',
            label:'入店日期',
            code:'date1',
            component:() => import('@/components/datePicker'),
          },
          {
            itemId:'itemId4',
            label:'是否会员',
            code:'delivery',
            component:() => import('@/components/switch')
          },
          {
            itemId:'itemId5',
            label:'意向商品',
            code:'type',
            component:() => import('@/components/checkBoxGroup'),
            proOptionData:[
              {
                value:'1',
                label:'美食'
              },
              {
                value:'2',
                label:'家具'
              },
              {
                value:'4',
                label:'玩具'
              },
              {
                value:'5',
                label:'美妆'
              },
            ]
          },
          {
            itemId:'itemId6',
            label:'备注',
            type:'textarea',
            code:'desc',
            component:() => import('@/components/input')
          },
        ],

src的代码路径结构
在这里插入图片描述
这样就能在数组中控制页面渲染的表单的多少了,但是我们可以发现,引入子组件的component是一个函数,它无法保存在数据中,所以我们需要把它改成字符串的形式。

formItemList: this.publicMethod.getFormItem([
          {
            itemId:'itemId1',
            label:'姓名',
            code:'name',
            component:'@/components/input'
          },
          {
            itemId:'itemId2',
            label:'性别',
            code:'region',
            component:'@/components/select',
            proOptionData:[
              {
                value:'1',
                label:'男'
              },
              {
                value:'2',
                label:'女'
              },
            ]
          },
          {
            itemId:'itemId3',
            label:'入店日期',
            code:'date1',
            component:'@/components/datePicker',
          },
          {
            itemId:'itemId4',
            label:'是否会员',
            code:'delivery',
            component:'@/components/switch'
          },
          {
            itemId:'itemId5',
            label:'意向商品',
            code:'type',
            component:'@/components/checkBoxGroup',
            proOptionData:[
              {
                value:'1',
                label:'美食'
              },
              {
                value:'2',
                label:'家具'
              },
              {
                value:'4',
                label:'玩具'
              },
              {
                value:'5',
                label:'美妆'
              },
            ]
          },
          {
            itemId:'itemId6',
            label:'备注',
            type:'textarea',
            code:'desc',
            component:'@/components/input'
          },
        ]),

编写一个构建component的公共函数:

export function getFormItem(formItemArr){
    let arr = formItemArr
    if(arr.length>0){
        for(let item of arr){
            let component = item.component.split('components/')[1]
            item['component'] = () => import(`@/components/${component}`)
        }
    }else{
        arr = []
        return []
    }
    return arr
}

在main.js中绑定到Vue原型上:

import * as publicMethod from './publicMethod/index'

Vue.prototype.publicMethod = publicMethod           //全局注册,公共方法

通过配置化编写前端代码的方法已经基本完成,接下来需要通过后台API来引入formItemList,先构建后台数据库:
组件的数据表:
在这里插入图片描述

下拉框数据表:
在这里插入图片描述
后台代码:(T.T不是专业的后台,忽喷,努力改进中)

var express = require('express');
var router = express.Router();
var mysql = require('mysql');
//把数据库的密码,账号,地址,端口,表格都连接上!!
var connection = mysql.createConnection({
  host: 'localhost',
  user: 'root',
  password: 'Yang1198432033.',
  port: '3306',
  database: 'peizhihua'//上文说的名字
});
connection.connect(); 


//查,数据库代码
var sql = 'SELECT * FROM itemlist WHERE view=?';
let sql1 = 'SELECT * FROM prooptiondata WHERE proOptionDataId=?'

async function connect(sql,req){
  let res = await connection.query(sql,req)
}

/* GET home page. */
router.post('/api', function(req, res, next) {
  let query = req.body
  let list = []
  connection.query(sql,query.view, function (err, queryRes) { //询问访问数据库,也就是去嫩那个数据库
    if (err) { //失败就报个错。
      return;
    }
    list = JSON.parse(JSON.stringify(queryRes));
    let length = list.filter((i)=> i.proOptionData == 1)
    length = length.length
    let index = 0
    for(let i in list){
      if(list[i].proOptionData){
        connection.query(sql1,list[i].proOptionDataId, function (err, queryRes) { //询问访问数据库,也就是去嫩那个数据库
          if (err) { //失败就报个错。
            return;
          }
          let arr = JSON.parse(JSON.stringify(queryRes));
          list[i].proOptionData = arr
          index+=1
          if(index == length){
          res.writeHead(200, {
                'content-type': 'text/html;charset=utf8'
            });
            res.end(JSON.stringify({result:'1',list:list}));
          }
        })
      }
    }
    
  });
});

module.exports = router;

在created中访问API:

created(){
      const that = this
       this.$axios({
        method: 'post',
        url: '/api',
        data: {view:'form'}
      }).then((res)=>{
        that.formItemList = this.publicMethod.getFormItem(res.data.list)
      }).catch((err) =>{
        that.formItemList = this.publicMethod.getFormItem(that.stateFormItemList)
        //静态数组
      })
    },

大功告成:
在这里插入图片描述
在这里插入图片描述
配置化写法可以设置一个控制台,根据用户需求增加、修改和删除具有相同特性的元素,比如表单、按钮、表格的列等,后续还可以用缓存的机制,以便不用每次进入页面都需要访问一次API。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值