v-bind动态绑定样式 - Vue3新手基础教程

VUE的动态绑定样式详解

数据绑定的一个常见需求场景是操纵元素的 CSS class 列表和内联样式。

因为 class 和 style 都是 attribute,我们可以和其他 attribute 一样使用 v-bind 将它们和动态的字符串绑定。

但是,在处理比较复杂的绑定时,通过拼接生成字符串是麻烦且易出错的。

因此,Vue 专门为 class 和 style 的 v-bind 用法提供了特殊的功能增强。

除了字符串外,表达式的值也可以是对象或数组。

能动态的修改各类样式

提要:

  • v-bind:指令会将普通属性的值变为表达值
  • 使用v-bind指令的class属性值不再是字符串,而是表达式。 表达式里的className不是一个普通的字符,而是一个变量,Vue实例data属性中的数据。
  • v-bind 在处理 class 和 style 时, 表达式除了可以使用字符串之外,还可以是对象或数组。
  • v-bind:class 可以简写为 :class

v-bind 指令可以让我们将属性值关联到Vuedata数据中,这样的属性,我们称作为属性的动态绑定
属性的动态绑定比较符合vue以数据为驱动的模式,如果需要修改那个属性值,就可以直接通过修改Vue数据即可。

注意:

动态属性绑定, 在我们需要的时候在使用,如果一个属性的是是固定的,并不会在未来发生改变,就没有必要动态绑定属性.

但在属性动态绑定过程中有两个属性比较特殊,这两个属性就是class 和style属性,

在将 v-bind 用于 classstyle 时,Vue.js 做了专门的增强。

表达式结果的类型除了字符串之外,还可以是对象或数组。

用法示例

<h2 :class="msg">Hello World</h2>

使用动态绑定指令, 那么此时class后面的引号不再是字符串,而是一个JavaScript表达式。

 msg也就成为了一个变量,因此此时h2标签的类名不是字符串msg, 而是data数据中msg中的值、

演示代码

    <script src="https://unpkg.com/vue@next"></script>
    <div id="app">

        <!-- 未使用动态绑定的class属性 -->
        <div class="msg">hello world</div>

        <!-- 使用v-bind 动态绑定class属性 -->
        <div :class="msg">你好! Vue</div>
    </div>

    <script>
        const App = {
            data() {
                return {
                    msg: 'nbox',
                }
            },
        }
        const app = Vue.createApp(App);
        app.mount("#app");
    </script>
    <style>
        .nbox {
            color: red;
        }
    </style>

浏览器执行效果

hello world
你好! Vue
v-bind动态绑定样式 - Vue3新手基础教程

💛Class

属性绑定

我们可以为 v-bind:class 设置一个对象,从而动态的切换 class:

<div :class="{ 'active': isActive }"></div>

如果isActive为真,则在浏览器中渲染如下

<div class="active"></div>

语法说明:

  1. 上面的语法表示: active 这个 类名是否存在 将取决于数据属性isActive 的 布尔特性。
  2. 如果 isActive的值为true, 那么div 将有类名active 否则, div没有box类名
  3. 需要注意,此时active就是一个类名,并不是vue中的数据属性

多个对象

<div :class="{'active' : isActive, 'text-danger' : hasError}"></div>

浏览器渲染

<div class="active text-danger"></div>

与普通的 class 属性共存

<div class="static" :class="{ 'active' : isActive, 'text-danger' : hasError }"> </div>

浏览器渲染

<div class="static active text-danger"></div>

错误示例,下列两个代码不会生效

<h2 :class="msg box">Hello World</h2>
<h2 
    :class="isTrue ? msg : ''"
    :class="flag ? 'haha' : ''"
>你好</h2>

class绑定对象

如果您的class属性较多,我推荐您绑定对象,以便您的操作和代码的整洁性

<div id="app">
    <div  :class="classObject"></div>
</div>
const app = {
    data() {
      return {
         classObject: {
            'active': false,
            'text-danger': true
         }
      }
   }
}

浏览器渲染

<div class="text-danger"></div>

绑定一个返回对象的计算属性。这是一个常用且强大的模式

<div id="app">
    <div  :class="classObject"></div>
</div>
        const app = {
            data() {
                return {
                    isActive: true,
                    error: false,
                }
            },
            computed: {
                classObject() {
                    return {
                        active: this.isActive,
                        'text-danger': !this.error,
                    }
                }
            }
        }

浏览器渲染

<div class="active text-danger"></div>

class绑定数组(方法一)

<div id="app">
    <div class="static" :class="[activeClass, errorClass]"></div>
</div>
const app = {
    data() {
        return {
            activeClass: 'active',
            errorClass: 'text-danger'
        }
    }
}

class绑定数组(方法二)

<div :class="classObject"></div>
        const App = {
            data() {
                return {
                    classObject: ["static", "active", { "text-danger": true }],
                }
            },
        }

以上两种方法,浏览器渲染均为

<div class="static active text-danger"></div>

使用三元表达式来切换列表中的 class

<div id="app">
    <div :class="[isActive ? activeClass : '', errorClass]"></div>
</div>
const app = {
    data() {
        return {
            isActive: false,
	    activeClass: 'active',
	    errorClass: 'text-danger'
        }
    }
}

浏览器渲染为

<div class="text-danger"></div>

在代码isActive ? activeClass : ''中,因为isActive是假,表达式的值为第三个,为空值,当isActive为真时,表达式的值为第二个,即为activeClass

💛style(内联样式)

动态绑定style属性说明:

  1. 如果使用动态绑定属性方法绑定行内样式,那么style属性值将不再是字符串,而是表达式,
  2. 动态绑定style的值既然是表达式,那么就可以在表达式中使用对象.
  3. 如果值为对象,那么对象的属性名则为CSS样式属性, 值为样式的值。
  4. 注意,此时对象中的属性值,可以是确定的样式值,也可以是vue的数据变量,
  5. 因此有些值不能再像style标签中一样书写,例如50px,以前使用不加引号,现在必须加引号

对象写法关于值的问题

如果使用动态绑定属性style里的对象值不加引号, 就会有如下的问题:

<h2 :style="{color:red,font-size:30px}">Hello World</h2>

上面的这种写法就会报错, red30px会被当做变量去Vue data属性中找对应的数据, 但是找不到就报错

正确的写法应该是这样的

<h2 :style="{color:'red',fontSize:'30px'}">Hello World</h2>

也能正确显示结果, 但是要注意字符串嵌套问题

v-bind动态绑定样式 - Vue3新手基础教程

对象写法的属性问题:

相信通过刚才的例子,你也发现了,我们发font-size 的写法改为了fontSize.

因为CSS 属性名可以用驼峰式 (camelCase) 或短横线分隔 (kebab-case) 都可以:

因此,在普通的style属性中一下两种写法都可以

<!-- 驼峰式 (camelCase) 写法 --->
<h2 style="color:red;fontSize:30px;">Hello World</h2>

<!-- 短横线分隔 (kebab-case --->
<h2 style="color:red;font-size:30px;">Hello World</h2>

两种处理方法:

  1. 驼峰式 (camelCase)
  2. 如果要使用连字符, 就需要添加双引号, 将属性变成字符串的写法

因此动态绑定需要如下写法

<!-- 驼峰式 (camelCase) 写法 --->
<h2 :style="{color:'red', fontSize:'30px'}">Hello World</h2>

<!-- 短横线分隔 (kebab-case) 但是要加引号 --->
<h2 :style="{color:'red', 'font-size' :'30px'}">Hello World</h2>

推荐用驼峰写法, 对象的值也可以是变量

示例代码

<div id="app">
    <div :style="{ color: activeColor, fontSize: fontSize + 'px' }">菜鸟教程</div>
</div>

<script>
const app = {
    data() {
        return {
            activeColor: 'red',
	    fontSize: 30
        }
    }
}

Vue.createApp(app).mount('#app')
</script>

浏览器渲染

<div style="color: red; font-size: 30px;">菜鸟教程</div>

style绑定对象(推荐)

代码

<div id="app">
    <div :style="styleObject">菜鸟教程</div>
</div>

<script>
const app = {
    data() {
        return {
		styleObject: {
                color: "red",
	        fontSize: "30px"
			}
        }
    }
}

Vue.createApp(app).mount('#app')

浏览器渲染

<div style="color: red; font-size: 30px;">菜鸟教程</div>

同样的,如果样式对象需要更复杂的逻辑,也可以使用返回样式对象的计算属性。

动态修改样式

代码

    <script src="https://unpkg.com/vue@next"></script>
    <div id="app">
        <h2 :style="styleObject">Hello World</h2>
        <button @click="changColor">点击切换颜色</button>
    </div>

    <script>
        const App = {
            data() {
                return {
                    styleObject: {
                        color: "red",
                        fontSize: "30px"
                    }
                }
            },
            methods: {
                changColor() {
   this.styleObject.color = this.styleObject.color == "red" ? "skyblue" : "red"
                }
            }
        }
        const app = Vue.createApp(App);
        app.mount("#app");
    </script>

浏览器运行效果

Hello World

style绑定数组

可以扩展对象的用法,给动态属性的值绑定为数组,数组中就可以使用多组样式对象来绑定CSS样式。

这些对象会被合并后渲染到同一元素上:

代码

<div id="app">
    <div :style="[baseStyles, overridingStyles]">菜鸟教程</div>
</div>

<script>
const app = {
    data() {
        return {
		baseStyles: {
                color: 'green',
                fontSize: '30px'
            },
	        overridingStyles: {
                'font-weight': 'bold'
            }
        }
    }
}

Vue.createApp(app).mount('#app')

浏览器渲染

<div style="color: green; font-size: 30px; font-weight: bold;">菜鸟教程</div>

注意:

当 v-bind:style 使用需要特定前缀的 CSS 属性时,如 transform ,Vue.js 会自动侦测并添加相应的前缀。

自动前缀

当你在 :style 中使用了需要浏览器特殊前缀的 CSS 属性时,Vue 会自动为他们加上相应的前缀。Vue 是在运行时检查该属性是否支持在当前浏览器中使用。如果浏览器不支持某个属性,那么将测试加上各个浏览器特殊前缀,以找到哪一个是被支持的。

多重值

可以为 style 绑定中的 property 提供一个包含多个值的数组,常用于提供多个带前缀的值,例如:

<div :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }"></div>

这样写只会渲染数组中最后一个被浏览器支持的值。在本例中,如果浏览器支持不带浏览器前缀的 flexbox,那么就只会渲染 display: flex。

💛组件

单个根元素的自定义组件

当你在带有单个根元素的自定义组件上使用 class 属性时,这些 class 将被添加到该元素中。此元素上的现有 class 将不会被覆盖。

<div id="app">
    <runoob class="classC classD"></runoob>
</div>
app.component('runoob', {
    template: '<h1 class="classA classB">I like runoob!</h1>'
})

浏览器渲染

<h1 class="classA classB classC classD">I like runoob!</h1>

带数据绑定此元素上的现有 class 将不会被覆盖。

<my-component :class="{ active: isActive }"></my-component>

渲染(isActive为真)

<p class="active">Hi</p>

多个根元素

如果你的组件有多个根元素,你需要定义哪些部分将接收这个类。可以使用 $attrs 组件属性执行此操作:

<script src="https://unpkg.com/vue@next"></script>
<style>
.classA {
    color: red;
	font-size:30px;
}
</style>

<div id="app">
    <runoob class="classA"></runoob>
</div>
 
<script>
const app = Vue.createApp({})
 
app.component('runoob', {
  template: `
    <p :class="$attrs.class">I like runoob!</p>
    <span>这是一个子组件</span>
  `
})
 
app.mount('#app')
</script>

注意:template 中 ` 是反引号,不是单引号 '

浏览器渲染

<div id="app">
<p class="classA">I like runoob!</p>
<span>这是一个子组件</span></div>

拓展想象

若是配合CSS变量,岂不是有无限可能

v-bind动态绑定样式 - Vue3新手基础教程-Npcink
v-bind动态绑定样式 - Vue3新手基础教程-Npcink

通过element的ColorPicker 颜色选择器修改文本颜色

参考文档

默认分类

通过element的ColorPicker 颜色选择器修改文本颜色

2022-8-13 14:48:11

默认分类

var - CSS自定义变量

2022-8-16 18:13:40

⚠️
Npcink上的部份代码及教程来源于互联网,仅供网友学习交流,若您喜欢本文可附上原文链接随意转载。
无意侵害您的权益,请发送邮件至 1355471563#qq.com 或点击右侧 私信:Muze 反馈,我们将尽快处理。
0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索