如何在vue组件中动态的引入css文件?

问题描述

如标签描述的不准确,请见谅

我的需求是开发多套皮肤,打包的时候只加载其中某一种的皮肤(不需要动态换肤),因为css文件过大,后期配套的css文件过多,写在一起的话,一次全打包上去项目非常的大,又不可能复制多套代码,维护起来太痛苦了(js是一致的)

问题出现的环境背景及自己尝试过哪些方法

我目前想到的是全局定义一个变量,通过这个变量来加载css,然后维护对应的css文件即可,不知道可否实现?如各位有更好的做法,请告知,非常感谢!

相关代码

staticEnv.js
export const CSS = 'a';
.vue组件
<template>

</template>

<script>
  import {CSS}  from 'src/config/staticEnv'
  export default {
    name: "css",
    data() {
      return {
      
      }
    }
  }
</script>


<style scoped lang="stylus" type="text/stylus">
  @import "变量CSS.styl"

</style>

clipboard.png

单页面开发,有很多的组件,我想把css提出来放在对应的组件下,然后动态的加载,如变量是a 那么我就只需要加载 a.styl

你期待的结果是什么?实际看到的错误信息又是什么?

如本人描述的不够准确,欢迎各位大佬在回答中问,我将在第一时间回复,再次感谢

阅读 59.6k
5 个回答

我有个办法,你可以把你的样式文件动态的写入HTML中,通过link标签来搞,比如说你要加载a.css,就写个标签

<link rel="stylesheet" href="a.css">

你可以写个方法,传入你要加载的css的名字,然后document.head.appendChild(document.createElement('link').href="样式表名字(地址)")


组件动态引入不同css

首先你可以拿到webpack编译的时候的环境变量,怎么定义的去看这个博客
如果你是用的vue-cli脚手架生成的项目,应该会有这么两个文件去设置vue环境变量的,你加上一个A
clipboard.png
然后,你找到build文件夹下webpack.base.conf.js
clipboard.png
添加一个别名,你引入css的时候,就引入这个别名文件夹下的对应的文件,就行了

<template>
  <div id="app">
    <HelloWorld/>
  </div>
</template>

<script>
import HelloWorld from './components/HelloWorld'

import '~theme/a.css'

export default {
  name: 'App',
  components: {
    HelloWorld
  }
}
</script>

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

在构建npm run dev的时候,我试了,好像拿不到process.env.A,不过你可以手动在webpack.base.conf.js里面手动的去赋值一下process.env.A = xxx

给出ovensi大佬给出的思路实现的代码,给自己做个记录

在webpack.base.conf.js 里面 alias 下新增 'theme': ./${process.env.THEME}

参考
https://segmentfault.com/q/10...

 process.env.THEME = 'standard.styl'


  resolve: {
    extensions: ['.js', '.vue', '.json'],
    alias: {
      'vue$': 'vue/dist/vue.esm.js',
      // '@': resolve('src'),
      'src': resolve('src'),
      'api': resolve('/src/api'),
     // 'theme': `./standard.styl`,
      'theme': `./${process.env.THEME}`,
    }
  },

在config下的

clipboard.png

新增

clipboard.png

'use strict'
const merge = require('webpack-merge')
const prodEnv = require('./prod.env')

module.exports = merge(prodEnv, {
  NODE_ENV: '"development"',
  THEME:'"standard.styl"'
})

在vue组件里的style标签里


<style scoped lang="stylus" type="text/stylus">
  @import "~theme"
</style>

clipboard.png

文件结构如下,就重启项目就ok了

getSkinData () {

getSkin().then(resp\=> {

if (resp.code && resp.code === '200') {

letdata = resp.data

leturl = config.serverUrl()

letresult = url + '/skinFile/' + data.file

console.log(result)

this.cssLink = result

this.createCssLink(result)

        }

      })

    },

createCssLink (data) {

constlink = document.createElement('link')

link.type = 'text/css'

link.rel = 'stylesheet'

link.href = data

document.head.appendChild(link)

    }

第一个方法是请求后台上传的css路径
第二个方法是不路径添加的link上去,我看到页面上添加进去了
但是样式没有效果

新手上路,请多包涵

在vue组件的mounted中书写条件语句使用import('cssPath') 即可满足需求。

新手上路,请多包涵

非常感谢两位大佬的提问和答案,我需要导入的是字体(其实就是css,然后css用@font-face引入字体),用这个思路已经实现了,因为我所有的父节点都在一个app.vue文件里,所以我用store来控制加载哪个字体,然后在它的created钩子动态引用,功能完全正常,贴上代码:

clipboard.png

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题