簡體   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