根据配置生成组件

这个想法很久之前就有了,也用多种方式实现过,AST实现比较复杂,各位有兴趣可以自己查看各类资料

为什么有这个想法了:

  • 每次使用其他ui框架时避免不了和设计师的ui图不一致需要修改源代码或者修改样式,没法做到真正的自定义组件

我这里只教大家用最简单的方式实现,本人也觉得这种方式最好

读以下内容必须要会 express      ejs      axios

下面一步一步的来实现

所需的npm包

  • express
  • ejs
  • body-parser

这是基本目录结构


  • 生成的组件放在 components 文件夹里面
  • template 文件夹是存放组件模板
  • router 文件夹是路由文件
  • app.js 文件是服务器入口文件

app.js文件内容

下面代码都是node的基本操作就不再此讲解了

const express = require('express')
const bodyParser = require('body-parser')
const router = require('./router')
const app = express()
var allowCrossDomain = function (req, res, next) {
  res.header('Access-Control-Allow-Origin', '*')
  res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE')
  res.header('Access-Control-Allow-Headers', 'Content-Type')
  next()
}
app.use(allowCrossDomain)
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())
app.use(router)
app.listen(8000, () => {  console.log('服务器已启动~~~~~~~')})复制代码

在template文件夹创建badge.txt文件

这里是重点这里实际是ejs模板

看不懂的请移步ejs

<%#
height: 高度
background: 背景色
padding: 左右两边的大小
fontSize: 字体大小
dotSize: 小圆点的大小
%>
<template>
  <div class="min-badge">
    <slot></slot>
    <div class="min-badge-dot" v-if="dot"></div>
    <div class="min-badge-count" v-else-if="count">{{finalCount}}</div>
  </div>
</template>

<script>
export default {
  name: 'min-badge',
  props: {
    count: {
      type: Number,
      default: 0
    },
    maxCount: {
      type: Number,
      default: 99
    },
    dot: {
      type: Boolean,
      default: false
    }
  },
  computed: {
    finalCount () {
      return this.count > this.maxCount ? `${this.maxCount}+` : this.count
    }
  }
}
</script>

<style scoped>
.min-badge {
  position: relative;
  display: inline-block;
  line-height: 1;
  vertical-align: middle;
}
.min-badge-count {
  position: absolute;
  transform: translateX(50%);
  top: -12rpx;
  right: 0;
  height: <%= height %>rpx;
  border-radius: 1000px;
  min-width: 30rpx;
  background: <%= background %>;
  color: #fff;
  line-height: <%= height %>rpx;
  text-align: center;
  padding: 0 <%= padding %>rpx;
  font-size: <%= fontSize %>rpx;
  white-space: nowrap;
  z-index: 10;
  box-shadow: 0 0 0 1px #fff;
  box-sizing: border-box;
}
.min-badge-dot {
  position: absolute;
  transform: translateX(-50%);
  top: -<%= dotSize / 2 %>rpx;
  right: -<%= dotSize %>rpx;
  height: <%= dotSize %>rpx;
  width: <%= dotSize %>rpx;
  border-radius: 100%;
  background: <%= background %>;
  z-index: 10;
  box-shadow: 0 0 0 1px #fff;
}
</style>复制代码

创建路由文件index.js

const express = require('express')
const router = express.Router()
const fs = require('fs')
const path = require('path')
const ejs = require('ejs')
function renderFile (path, data) {
  return new Promise((reslove, reject) => {
    ejs.renderFile(path, data, (error, data) => {
      if (error) {
        reject(error)
      }
      reslove(data)
    })
  })
}
function writeFile (path, data) {
  return new Promise((reslove, reject) => {
    fs.writeFile(path, data, (err) => {
      if (err) {
        reject(err)
      }
      reslove(null)
    })
  })
}
// 徽章组件
router.post('/badge', (req, res) => {
  renderFile(path.join(__dirname, '../template/badge.txt'), req.body).then(data => {
    return writeFile(path.join(__dirname, '../components/badge.vue'), data)
  }).then(() => {
    res.send({code: 0, msg: '创建成功'})
  }).catch(err => {
    console.log(err)
    res.send({code: 1, msg: '创建失败'})
  })
})
module.exports = router复制代码

在create-components-data创建badge.js文件

const badge = {
  // 小圆点的大小
  dotSize: 16,
  // 高度
  height: 30,
  // 背景色
  background: '#dd524d',
  // 左右两边的大小
  padding: 10,
  // 字体大小
  fontSize: 20
}

module.exports = badge复制代码

在客服端发送请求

本来是想放服务器上面的,让大家可以直接访问的,可奈何本人太穷买不起服务器

在这里有无限可能,像什么可以拖拽生成页面都可以使用这种方式

这张图只是表示badge的配置可以是ui互动产生的结果


badge可以是ui互动产生的结果,也可以是json可视化生成的结果

const badge = {
  // 小圆点的大小
  dotSize: 16,
  // 高度
  height: 30,
  // 背景色
  background: '#dd524d',
  // 左右两边的大小
  padding: 10,
  // 字体大小
  fontSize: 20
}
// 发送请求
axios.post('/badge', badge)复制代码

本地测试

创建test文件夹在里面创建testBadge.js文件

const fs = require('fs')
const path = require('path')
const ejs = require('ejs')
const badge = require('../create-components-data/badge')
function renderFile (path, data) {
  return new Promise((reslove, reject) => {
    ejs.renderFile(path, data, (error, data) => {
      if (error) {
        reject(error)
      }
      reslove(data)
    })
  })
}
function writeFile (path, data) {
  return new Promise((reslove, reject) => {
    fs.writeFile(path, data, (err) => {
      if (err) {
        reject(err)
      }
      reslove(null)
    })
  })
}
renderFile(path.join(__dirname, '../template/badge.txt'), badge).then(data => {
  return writeFile(path.join(__dirname, '../components/badge.vue'), data)
}).then(() => {
  console.log('创建成功')
}).catch(err => {
  console.log(err)
})复制代码

在项目下执行node ./test/testBadge.js测试生成badge组件


上面生成的组件可以用在mpvue uni-app上面,当然这里也打开了新大陆,可以发散思维在其他框架上也可以使用这种方式


如果想学AST方法的话我只提供思路

欢迎评论、点赞

项目地址github


转载于:https://juejin.im/post/5d22a7a5f265da1bbd4b985c

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐