
在日常开发中随着用户需求的日益多样化,界面设计也日益复杂,如何在保持代码简洁的同时,实现界面的动态变化,是一项不小的挑战。动态样式作为实现界面动态变化的关键技术手段,不仅能够提升用户体验,还能为开发者提供更加丰富的设计空间。
动态样式在Vue中的应用,主要体现在通过数据绑定、计算属性、条件渲染等技术,使得界面元素的样式能够根据数据状态、用户交互等条件实时调整。这不仅能够实现界面的个性化展示,还能根据不同的使用场景提供更为直观、响应式的视觉反馈。
下面将总结几种动态样式常用的方法
内联样式绑定一个对象,
\:style 是一个动态绑定样式的指令,它允许你将样式应用到元素上,并且这些样式可以根据组件的状态或者数据动态变化。
<template>
  <div class="home">
    <button :style="{backgroundColor: backgroundColor[theme]}" @click="changeColor('default')">default</button>
    <button :style="{backgroundColor: backgroundColor[theme]}" @click="changeColor('new')">new</button>
  </div>
</template>
<script setup>
import { ref, reactive } from 'vue';
let theme = ref('default')
let backgroundColor = reactive({
  default: 'blue',
  new: 'red',
})
function changeColor(val) {
  theme.value = val
}
</script>
<style lang="scss">
.home{
  background-color: #fff;
  width: 80vw;
  height: 50vh;
  display: flex;
  align-items: center;
  justify-content: center;
  button{
   width: 100px;
   margin: 10px;
  }
}
</style><template>
  <div class="home">
    <button :class="theme" @click="changeColor('default')">default</button>
    <button :class="theme" @click="changeColor('new')">new</button>
  </div>
</template>
<script setup>
import { ref, reactive } from 'vue';
let theme = ref('default')
function changeColor(val) {
  theme.value = val
}
</script>
<style lang="scss">
.home{
  background-color: #fff;
  width: 80vw;
  height: 50vh;
  display: flex;
  align-items: center;
  justify-content: center;
  button{
   width: 100px;
   margin: 10px;
  }
  .default{
    background-color: blue;
  }
  .new{
    background-color: red;
  }
}
</style>动态class 动态style 效果

SCSS变量是指在SCSS(Sass的一种语法)中定义的变量,这些变量可以在整个项目中的任何SCSS文件中使用。这样做的好处是可以在一个地方集中管理项目的样式,便于统一修改和维护。
SCSS变量的优势
style标签中生命\$themeColor变量
<template>
  <div class="home">
    <button>按钮</button>
  </div>
</template>
<script setup>
</script>
<style lang="scss">
$themeColor: #2779e4;
.home{
  background-color: #fff;
  width: 80vw;
  height: 50vh;
  button{
    margin: 20vh auto;
    color: #fff;
    background-color: $themeColor;
  }
}
</style>在实际开发中往往 会将scss变量的定义统一放在一个公共scss文件里管理,
/scr/common 下创建 index.scss文件
然后 在 style标签中引入scss文件
index.scss
$themeColor: #2779e4;.vue
<style lang="scss">
@import "@/common/index.scss";
.home{
  background-color: #fff;
  width: 80vw;
  height: 50vh;
  button{
    margin: 20vh auto;
    color: #fff;
    background-color: $themeColor;
  }
}
</style>考虑到项目在实际开发中,各种组件都需要统一使用样式变量,每个页面引入是不现实的,最佳的解决方案就是,将scss中的变量在全局引入,所有页面都可以访问到.
安装 sass
npm install sassvite.config.ts文件中 设置css预处理器
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from 'path'
const pathResolve = (dir: string): any => {
  return resolve(__dirname, ".", dir)
}
const alias: Record<string, string> = {
  '@': pathResolve("src")
}
// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias
  },
  css: {
    // css预处理器
    preprocessorOptions: {
      scss: {
        // 引入 index.scss 这样就可以在全局中使用 index.scss中预定义的变量了
        // 给导入的路径最后加上; 
        additionalData: '@import "@/common/index.scss";'
      }
    }
  }
})有了以上配置,无需再单独引用index.scss,style标签中就可以直接使用 \$themeColor变量了,
<style lang="scss">
.home{
  background-color: #fff;
  width: 80vw;
  height: 50vh;
  button{
    margin: 20vh auto;
    color: #fff;
    background-color: $themeColor;
  }
}
</style>原理:提前设置好多种皮肤的对应的样式,然后 利用 css 自定义属性选择器和jsdom操作方法 setAttribute 动态修改 自定义属性 来匹配不同的样式
1.全局配置多种皮肤样式
index.scss
$themeColor: #2779e4;
$themes:(
  default: (
    backgroundColor: blue,
  ),
  new: (
    backgroundColor: red,
  )
);
@mixin themeify {
  @each $theme-name, $theme-map in $themes {
    $theme-map: $theme-map !global;
    [data-theme="#{$theme-name}"] & {
      @content;
    }
  }
}
@function themed($key) {
  @return map-get($theme-map, $key);
}
@mixin getBackgroundColor($color) {
  @include themeify {
    background-color: themed($color)!important;
  }
}
@mixin getColor($color) {
  @include themeify {
    background-color: themed($color)!important;
  }
}2 .vue文件中获取全局皮肤颜色设置对应样式,且提前初始化样式(这一步可以放到 App.vue中 全局出发一次)
<template>
  <div class="home">
    <select v-model="theme">
      <option value="default">default</option>
      <option value="new">new</option>
    </select>
    <button @click="changeTheme">修改主题</button>
  </div>
</template>
<script setup>
import { ref, onBeforeMount } from 'vue';
let theme = ref('default')
function changeTheme() {
  window.document.documentElement.setAttribute( "data-theme", theme.value );
}
onBeforeMount(() => {
  changeTheme(theme.value)
})
</script>
<style lang="scss">
.home{
  background-color: #fff;
  width: 80vw;
  height: 50vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  select{
    width: 100px;
    margin: 10px;
    @include getBackgroundColor("backgroundColor");
  }
  button{
    // background-color: $themeColor;
    @include getBackgroundColor("backgroundColor");
  }
}
</style>效果

在 Vue 3 中使用 SCSS 变量 来实现样式的一致性和可重用性是一个很好的做法。Vue 3 与 SCSS可以很好地协同工作,因为 Vue 的数据驱动的模板语法与 SCSS 的变量系统相兼容。
以下是在 scss中使用js变量 v-bind来实现
<template>
  <div class="home">
    <button class="btn" @click="changeColor('blue')">default</button>
    <button class="btn" @click="changeColor('red')">new</button>
  </div>
</template>
<script setup>
import { ref } from 'vue';
let color = ref('blue')
function changeColor(val) {
  color.value = val
}
</script>
<style lang="scss">
.home{
  background-color: #fff;
  width: 80vw;
  height: 50vh;
  display: flex;
  align-items: center;
  justify-content: center;
  button{
   width: 100px;
   margin: 10px;
  }
  .btn{
    background-color: v-bind(color);
  }
}
</style>然后是 js中使用scss定义的变量
新建 global.module.scss文件
$b: blue;
$r: red;
:export {
  BLUR: $b;
  RED: $r;
}页面中 import引入 global.module.scss 即可
<template>
  <div class="home">
    <button class="btn" @click="changeColor(config.BLUR)">default</button>
    <button class="btn" @click="changeColor(config.RED)">new</button>
  </div>
</template>
<script setup>
import config from '@/common/global.module.scss'
import { ref } from 'vue';
let color = ref('blue')
function changeColor(val) {
  color.value = val
}
</script>
<style lang="scss">
.home{
  background-color: #fff;
  width: 80vw;
  height: 50vh;
  display: flex;
  align-items: center;
  justify-content: center;
  button{
   width: 100px;
   margin: 10px;
  }
  .btn{
    background-color: v-bind(color);
  }
}
</style>效果

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。