繁体   English   中英

CSS styles 未应用于 Vue 组件中的 HTML

[英]CSS styles not being applied to HTML within a Vue Component

我正在尝试使用 Vue.js 创建一个旋转文本Vue.js ,我用这个CodePen作为灵感。

  • 我把所有的HMTL元素都放在了适当的位置(即,正如在CodePen中提到的那样)。 简而言之:

    • 每个单词由几个<span>元素组成,每个元素包含一个字母。
    • 在特定的时间间隔之后,每个包含一个字母的<span>都会应用一个.in.out CSS class。 这种情况无限期地进行。
    • 这是它在DOM中的样子:

      在此处输入图像描述

  • 问题是,无论我使用什么CSS选择器,我都无法定位.in.out类,除非我通过Chrome中的Developer Tools进行操作:

    • 原装 output:

      在此处输入图像描述

    • output 在Developer Tools中添加类后:

      在此处输入图像描述

这是我的Vue Component的最低限度代码:

<template>
    <div id="app-loading">  
        <div class="words">
            <span v-for="setting in settings" v-html="setting.lettersHTML" :id="setting.id" class="word"></span>    
        </div>
    </div>
</template>


<script>
    export default {
        data() {
            return {
                settings: [
                    { word: 'WordOne', id: 1, lettersArray: null, lettersHTML: null },
                    { word: 'WordTwo', id: 2, lettersArray: null, lettersHTML: null }
                ],
                currentWord: 1
            }
        },

        created() {
            this.splitLetters();
        },

        mounted() {
            setInterval(this.changeWord, 1500);
        },

        methods: {
            splitLetters() {
                this.settings.forEach((setting) => {
                    let letters = [];
                    for (let i = 0; i < setting.word.length; i++) {
                        let letter = `<span class="letter">${ setting.word.charAt(i) }</span>`;
                        letters.push(letter);
                    }
                    setting.lettersArray = letters;
                    setting.lettersHTML = letters.join('');
                });
            },

            changeWord() {
                let current = document.getElementById(this.currentWord).getElementsByTagName('span');
                let next = (this.currentWord == this.settings.length) ? document.getElementById(1).getElementsByTagName('span') : document.getElementById(this.currentWord + 1).getElementsByTagName('span');
                // Animate the letters in the current word.
                for (let i = 0; i < current.length; i++) {
                    this.animateLetterOut(current, i);
                }
                // Animate the letters in the next word.
                for (let i = 0; i < next.length; i++) {
                    this.animateLetterIn(next, i);
                }
                this.currentWord = (this.currentWord == this.settings.length) ? 1 : this.currentWord + 1;
            },

            animateLetterOut(current, index) {
                setTimeout(() => {
                    current[index].className = 'letter out';
                }, index * 300);
            },

            animateLetterIn(next, index) {
                setTimeout(() => {
                    next[index].className = 'letter in';
                }, 340 + (index * 300));
            }
        }
    }
</script>


<style lang="scss" scoped>
    #app-loading {
        font-size: 4rem;
    }

    .words, .word {
        border: 1px solid rosybrown;
    }

    .letter {
        text-decoration: underline; // Not working.
    }

    .letter.in {
        color: red; // Not working.
    }

    .letter.out {
        color: blue; // Not working.
    }
</style>

是什么问题阻止了这些类的应用?

您正在使用v-html ,但这不适用于范围样式

使用v-html创建的 DOM 内容不受范围样式的影响,但您仍然可以使用深度选择器来设置它们的样式。

是的,

v-html

不适用于范围样式。

正如 Brock Reece 在他的文章Scoped Styles with v-html 中解释的那样,应该这样解决:

<template>   
    <div class="a" v-html="content"></div> 
</template>

<script>   
    export default { 
        data() {
           return {
              content: 'this is a <a class="b">Test</a>',
           }
        },
    } 
</script>

<style scoped>   
.a >>> .b {
color: red;   
}
</style>

这对我有用:

<template>   
    <div class="a" v-html="content"></div> 
</template>

<script>   
    export default { 
        data() {
           return {
              content: 'this is a <a class="b">Test</a>',
           }
        },
    } 
</script>

<style scoped>   
.a ::v-deep .b { 
     color: red;
 }
</style>

由于 Vue3 已经发布,大多数答案都已被弃用。 深度选择器的最新用法:

.letter{
  &:deep(.in) {
    color:blue;
  }
  &:deep(.out) {
    color:red;
  }
}

Vue3:在单文件组件中,作用域 styles 将不适用于 v-html 内的内容,因为 Vue 的模板编译器不会处理 HTML。

您可以在 Vue3 项目中使用:deep() 内部选择器。

这是一个例子:

<script setup lang="ts">

import {onMounted,ref } from 'vue'
const content = ref("")

onMounted(()=>{
    window.addEventListener('keydown',event =>{
        content.value = `
            <div class="key">
                <span class="content">${event.keyCode}</span>
                <small>event.keyCode</small>
            </div>
        `
    })
})

</script>

<template>
    <div class="container" v-html="content">
    </div>
</template>

<style lang="scss" scoped>  

.container{
    display: flex;
    
    :deep(.key){
        font-weight: bold;
        
        .content{
            font-size: 1.5rem;
        }
        
        small{
            font-size: 14px;
        }
    }
}
</style>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM