You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 17:54:03