在vue-cli中独立构建主题

2019-09-25  本文已影响0人  bigfacewo

前言

一般主题功能都会归类到一系列css中,通过文件名区分。这篇文章将手把手教你如何做一个属于你的主题功能,并且可以支持一定程度的热重载。理论上不需要和vue-cli或者webpack绑定。

动态加载主题

这一步很简单,当我切换主题的时候,移除旧的主题样式标签,然后添加新的主题样式标签即可。
首先,data中定义:

data(){
  return {
    theme:'theme1',
    linkId:'theme'  
  }
}

methods中加入以下方法:

    applyTheme() {
      this.removeStyle()
      this.addStyle()
    },
    removeStyle() {
      const style = document.getElementById(this.linkId)
      if (style) {
        style.remove()
      }
    },
    addStyle() {
      const link = document.createElement('link')
      link.href = `你的静态资源目录/${this.theme}.css`
      link.setAttribute('rel', 'stylesheet')
      link.setAttribute('media', 'all')
      link.setAttribute('type', 'text/css')
      link.id = this.linkId
      const head = document.getElementsByTagName('head')[0]
      head.appendChild(link)
    }

监听到theme变化之后调用applyTheme方法。

主题开发

主题采用less进行开发,当然你使用sass或者stylus都可以,但是不会直接使用css,这样效率会高一些。

开发构建脚本

理论上应该编写一个webpack插件来进行这项工作,但是由于我们的主题源码并未在项目中通过import或者require引入,所以修改主题不会触发重新编译。我没有在webpack上找到有效的解决办法,如果有,麻烦分享给我。

新建build.js放入主题源码目录下,脚本代码:


var fs = require('fs')
const _ = require('lodash')
const less = require('less')

var pathName = '主题源码目录'
var writePath = '编译后的主题css资源目录'
fs.readdir(pathName, async function(err, files) {
  if (err) {
    console.log(err)
    return
  }
  _.remove(files, function(o) {
    return o === 'build.js'
  })
  console.log(files)
  const csses = []
  for (var name of files) {
    var filePath = pathName + '/' + name
    var data = fs.readFileSync(filePath, 'utf-8')
    try {
      const r = await less.render(data, {})
      csses.push({
        name: name.split('.')[0],
        css: r.css
      })
    } catch (e) {
      console.log(e)
    }
  }
  for (var css of csses) {
    write(css)
  }
  console.log('写入CSS成功!')
})

function write(css) {
  const f = fs.writeFileSync(writePath + '/' + css.name + '.css', css.css)
  console.log(f)
}

package-jsonscripts中加入一行"build:theme":"node 主题源码路径/build.js"。接着运行npm run build:theme,就可以将源码编译为css

自动构建

直到上一步,主题功能就算是完成了,但是有一个问题,每次修改主题后需要主动运行npm run build:theme将主题编译成css,开发效率很受影响。所以考虑写一个监听文件改变的脚本和vue-cli结合起来。最先想到的是gulp,gulp可以方便地监听单个文件的改变,但是不是很想为这个功能引入gulp,于是使用fs.watch自己写,在vue.config.js顶部合适位置加入以下代码:

var fs = require('fs')
function resolve(dir) {
  return path.join(__dirname, dir)
}

const { exec } = require('child_process')

// 监听主题文件的修改
fs.watch(resolve('主题源码目录'),(event,trigger)=>{
  // 修改后重新执行构建主题
  exec('npm run build:theme', (error, stdout, stderr) => {
    if (error) {
      console.error(`exec error: ${error}`)
      return
    }
  })
})

接着重新把项目跑起来,修改主题文件,可以看到浏览器会重新加载页面,已经应用的主题会相应地被修改。

上一篇 下一篇

猜你喜欢

热点阅读