前端工程化–Vue-CLI自動生成頁面

  • 2020 年 4 月 10 日
  • 筆記

背景

我們的項目是基於vue-cli搭建的,每次需要新加一個頁面需要操作以下步驟:

  1. 在views文件夾下面新建一個文件夾,用來存放新頁面的.vue文件。
  2. 需要在routes.js文件裡面新添加一個路由。

按照上述操作以後,才可以正常訪問新添加的頁面,之後才開始對新頁面進行正常開發。但是這樣的機械化步驟我們完全可以用程式碼幫我們執行,更進一步,對於一些簡單的頁面,我們甚至可以一鍵生成頁面,包括從後端請求數據等操作。

接下來我就一步步講一下怎麼樣自動生成頁面。

自動生成頁面

我們可以按照模板的方式生成想要的頁面,我這裡說兩種頁面,

  • 一種是什麼都沒有的空白頁,生成空白頁就相當於是初始化一個新頁面然後接著開發。
  • 另一種是生成一些比較固定布局的簡單頁面,比如我們的業務中經常會有需求是寫一個頁面,就一個表格展示一下後端返回的數據,頂多就是再加個刪除,添加和編輯。像這種簡單的頁面,完全可以使用程式碼自動生成。

我這裡主要是使用配置文件的方式來設置我們的模板。

一、生成表格頁

為了操作方便,我們可以在項目根目錄新建一個auto-build-page文件夾用來存放我們之後要寫的所有程式碼和模板。

1. 編輯配置文件

我們在auto-build-page文件夾下新建一個addConfig.js文件,裡面存放我們定義的配置:

var addConfig = [    {      // 測試生成表格頁      open: true, // 參與生成 false表示改配置不參與生成頁面      helloworld: false, // 是否是空白頁      desc: '自動生成表格頁', // 頁面描述      name: 'autoTablepage', // 頁面名稱      getlist: {        // 表格數據請求相關        method: 'GET',        url: 'http://test.req/getlist',      },    },    {      // 測試生成空白頁      open: true,      helloworld: true,      desc: '自動生成空白頁面',      name: 'autoHellopage',    },  ]  module.exports = addConfig

配置的含義在注釋中已經詳細說明了。

2. 按照配置文件生成頁面.vue文件

我們在auto-build-page文件夾下新建一個template-table.vue文件,存放我們的表格頁模版,我們使用的是element-ui組件:

<template>    <div class="deduction">      <header>%title%</header>      <main>        <el-table :data="tableData" style="width: 100%">          <el-table-column type="expand">            <template v-slot="props">              <pre v-html="formatOther(props.row)"></pre>            </template>          </el-table-column>          <el-table-column v-for="(item,index) in tableDataHeader" :key="index" :prop="item.prop" :label="item.col">            <template slot-scope="scope">              {{scope.row[scope.column.property]}}              <!-- {{scope.row}}              {{scope.column.property}} -->              <!-- 渲染對應表格裡面的內容 -->            </template>          </el-table-column>        </el-table>      </main>    </div>  </template>    <script>  import axios from "axios";  const CONFIG={    method:"%method%",    geturl:"%geturl%",  };  export default {    data() {      return {        tableData: [],        tableDataHeader: [],        };    },    methods: {      formatOther(row) {        return JSON.stringify(row, null, 2);      },      getList(params={}) {        axios({          method: CONFIG.method,          url: CONFIG.geturl,          data: params        }).then(res=>{ // 後端返回的數據需要按照這種格式          console.log(res);          this.tableData=res.data.tableData;          this.tableDataHeader=res.data.tableDataHeader;        });      }    },    mounted(){      this.getList();    }  };  </script>

可以看見表格頁模板裡面有很多兩個%包起來的變數,這是等下我們需要按照配置文件進行替換的變數。

我們繼續在auto-build-page文件夾下新建一個build-page.js文件,裡面寫的是整個自動化操作的程式碼。

var addConfig = require('./addConfig')  var fs = require('fs')  var path = require('path')  var shell = require('shelljs')    shell.echo('>>>>>>')  shell.echo('開始新建頁面')  addConfig.forEach((ele) => {    if (ele.open) {      buildPage(ele)    }  })

我們循環配置文件裡面的配置,支援生成多個頁面。對文件的操作我們直接使用node的fs模組完成。 讀取模板文件,並根據配置文件,對模板文件裡面的變數進行替換:

function buildPage(config) {    var paths = path.resolve(`./src/views/${config.name}`)    shell.echo('頁面地址:' + paths)    mkdirSync(paths, function() {      var str = ''      if (config.helloworld) {        // 新建空白頁,讀取空白頁模版        str = handleStr(          readF(path.resolve('./template-helloworld.vue')),          config        )      } else {        str = handleStr(          readF(path.resolve('./template-table.vue')),          config        )      }      // 寫入文件      writeF(paths + '/index.vue', str)      shell.echo('開始新增路由……')      addRou(`./views/${config.name}/index.vue`, config)    })  }

根據配置文件替換%包起來的變數:

function handleStr(str, config) {    if (config.helloworld) {      return str    }    str = str.replace('%title%', config.desc)    str = str.replace('%method%', config.getlist.method)    str = str.replace('%geturl%', config.getlist.url)    return str  }

3. 添加路由

接下來是添加路由,在此之前我們還是需要添加一個路由的模板文件,在auto-build-page文件夾下新建一個template-route.txt文件:

{    path: '%path%',    component: Home,    name: '%name%',    redirect: { path: '%repath%' },    children: [      {        path: '%repath%',        component: (resolve) =>          require(['%requirepath%'], resolve),        name: '%name2%'      }    ]  },

裡面根據我們路由規則,寫入模板。

回到build-page.js文件,我們繼續書寫添加路由的操作,我們先讀取路由模板:

function addRou(paths, config) {    var templateStr = handleRouStr(      readF(path.resolve('./auto-build-page/template-route.txt')),      config,      paths    )    // 添加到路由文件    addToConf(templateStr)  }  function handleRouStr(str, config, paths) {    str = str.replace(/%path%/g, `/${config.name}`)    str = str.replace(/%name%/g, config.desc)    str = str.replace(/%name2%/g, `${config.desc}首頁`)    str = str.replace(/%repath%/g, `/${config.name}/index`)    str = str.replace(/%requirepath%/g, paths)    return str  }

將路由添加到vue項目src下的routes.js文件裡面:

function addToConf(str) {    str += '// add-flag' // 添加的位置標記    var confStr = handleConfRouStr(readF(path.resolve('./src/addRoute.js')), str)    writeF(path.resolve('./src/addRoute.js'), confStr)    shell.echo('路由添加成功!')    shell.echo('結束生成頁面')    shell.echo('>>>>>>')  }  function handleConfRouStr(ori, str) {    ori = ori.replace('// add-flag', str)    return ori  }

我這裡是為了避免原來的routes.js文件,我新建了一個addRoute.js文件,然後在routes.js文件中引入,和原來的合併以下即可。 routes.js

// 自動生成頁面--自動添加路由  import addRoute from './addRoute'    let routes = []  let lastRoute = routes.concat(addRoute)  export default lastRoute

addRoute.js

const addRoute = [      // add-flag    // 不能刪除  ]    export default addRoute

接下來我們需要在package.json文件裡面的scripts裡面添加運行的腳本,這樣,只需要執行npm run 命令就可以運行自動生成的操作:

"scripts": {      "dev": "vue-cli-service serve",      "build": "vue-cli-service build",      "bpage": "node ./auto-build-page/build-page.js"    },

現在執行npm run bpage 控制台輸出:

>>>>>>  開始新建頁面  頁面地址:./src/views/autoTablepage  頁面地址:./src/views/autoHellopage  開始新增路由……  路由添加成功!  結束生成頁面  >>>>>>

現在已經可以正常訪問這兩個頁面了。並且表格頁還可以看見後端返回的數據!

二、生成空白頁

只需要添加一個空白頁的模板就行,在auto-build-page文件夾下新建一個template-helloword.vue文件:

<template>    <div>      hello world    </div>  </template>    <script>  export default {    data() {      return {};    },    methods: {},    mounted() {}  };  </script>

後續需要其他頁面,只需要添加相應的模板,修改一下生成的函數即可。