能否在Vue组件内部嵌入CSS模板,无需外部引入样式文件?
答案
原生Vue没有内置cssTemplate这类配置项,但你可以通过动态注入样式的方式完全实现你的需求,不需要修改原有CSS的类、ID、动画等声明格式。
实现思路
- 在组件内定义存储CSS代码的字段,比如你想要的
cssTemplate - 组件初始化时判断当前样式是否已经注入到页面,避免重复创建style标签
- 把CSS内容封装为style标签插入到document.head中即可
完整实现代码
JS代码
var loading = new Vue({ el: "#loading_id", components:{ 'loading' : { template : ` <div> <div id="screenLoading" class="background"> <div class="loading"> <div class="obj"></div> <div class="obj"></div> <div class="obj"></div> <div class="obj"></div> <div class="obj"></div> <div class="obj"></div> <div class="obj"></div> <div class="obj"></div> </div> </div> </div> `, // 直接把原有CSS代码复制到这里即可,完全保留原有写法 cssTemplate: ` .background { width: 100vw; height: 100vh; background: rgba(0, 0, 0,.5); position: fixed; top: 0px; left: 0px; z-index: 2000; display: none; justify-content: center; align-items: center; } .background.show { display: flex; } .loading{ position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); height: 40px; display: flex; align-items: center; } .obj{ width: 12px; height: 70px; background: white; margin: 0 3px; border-radius: 10px; animation: loading 0.8s infinite; } .obj:nth-child(2){ animation-delay: 0.1s; } .obj:nth-child(3){ animation-delay: 0.2s; } .obj:nth-child(4){ animation-delay: 0.3s; } .obj:nth-child(5){ animation-delay: 0.4s; } .obj:nth-child(6){ animation-delay: 0.5s; } .obj:nth-child(7){ animation-delay: 0.6s; } .obj:nth-child(8){ animation-delay: 0.7s; } @keyframes loading{ 0%{ height: 0; } 50%{ height: 70px; } 100%{ height: 0; } } `, created() { // 避免重复注入样式 if (!document.getElementById('loading-component-style')) { const styleEl = document.createElement('style') styleEl.id = 'loading-component-style' styleEl.innerHTML = this.cssTemplate document.head.appendChild(styleEl) } }, methods: { startLoading: function() { const load = document.getElementById("screenLoading"); load.classList.add('show') }, stopLoading: function(){ const load = document.getElementById("screenLoading"); load.classList.remove('show') } } } } }); loading.$children[0].startLoading() setTimeout(() => { loading.$children[0].stopLoading() }, 3500);
HTML代码
和之前的用法完全一致,不需要额外引入CSS文件或者写全局style标签:
<script src="https://cdn.jsdelivr.net/npm/vue"></script> <loading id="loading_id"></loading>
说明
- 原有CSS代码不需要做任何修改,直接复制到
cssTemplate的模板字符串中即可,类、ID、动画、伪类选择器等所有写法都完全保留 - 加入了样式注入的去重逻辑,即使组件多次实例化也不会重复插入相同的样式代码
- 样式会全局生效,和你之前单独写在style标签或者CSS文件里的效果完全一致
内容的提问来源于stack exchange,提问作者raylight
相关产品推荐
相关产品推荐

