跳到主要内容

1.3-vue中的样式

Create by fall on 10 Mar 2022 Recently revised in 20 Sep 2023

Style

scope

如果在 <style scope> 标签内有 scope 表示该样式的作用域只在该组件内。

Vue 通过给 HTML 的一个节点添加不重复的 data 属性,保证该元素的唯一 [data-v-2311c06a]

在 CSS 语句的末尾,也添加该 data 属性,保证该 CSS 只作用在该作用域内

:deep(.className)  {} /*  vue 3 的写法 */
::v-deep .class {} /* vue 2 的写法 */
/* 其它古老的写法,主要是 vue 不推荐了 */
.content >>> .button{}
.content ::v-deep .button{}
/deep/ .button{}

当然还有用于其他指向的伪类

// 将属性应用到插槽中的内容,插槽中的内容被认为是父组件所持有并传递进来的。
:slotted(.red) {
color: red;
}
// 想让一个样式应用于全局,既可以创建一个新的 <style> 标签,也可以
:global(.red) {
color: red;
}

module

如果将 <style> 标签设置为 <style module> 就可以应用 module 模式

module 模式下,样式可以通过 $style.[className] 进行调用

<template>
<p :class="$style.red">This should be red</p>
<p :class="poker.pink">This should be red</p>
</template>
<script>
import {useCssModule} from 'vue'
useCssModule('TopModule')
</script>
<style module>
.red {
color: red;
}
</style>
<!-- 当然也可以为 module 设置名称 -->
<style module="poker">
.pink {
color: pink;
}
</style>

样式绑定

可以通过用 v-bind 将样式属性包裹起来,用来动态绑定行内样式,当值改变时,样式会改变

<script setup>
const theme = {
color: 'red'
}
</script>
<template>
<p>hello</p>
</template>
<style scoped>
p {
color: v-bind('theme.color');
}
</style>

动画

Vue 的动画,作用于用 vue-routerv-ifv-showcomponent 动态组件,使用 Transition,套住不同的 name 绑定不同的动画,使用 key 来确定是否为同一个组件。

一共有六个动画的类名,按照动画从开始到结束分别为:

  • v-enter:表示进入时的位置。
  • v-enter-active:表示进入,从位置移动后的动画
  • v-enter-to:表示进入,并且进入的动画执行结束后。
  • v-leave:离开开始时的状态
  • v-leave-active:表示动画开始执行离开,到离开的过程
  • v-leave-to:表示动画结束的位置

img

如果两个动画同时执行,比如说切换界面,既是一个页面的出现动画,也是另一个界面的消失动画。此时需要考虑如何实现不同动画的实现。

如果内容是一个组件,这个组件必须仅有一个根元素。

transition

// 如果 name 中没有值,那么 v 就是所有动画的默认 name
// 如果加上了 name 就在原有的基础上添加 name 的值而已
<!-- 也可以填入对应的 class -->
<template>
<transition name="page-change" enter-active-class="animate__tada">
<router-view ></router-view>
</transition>
</template>
<style>
.page-change-enter-active {
animation: change-page .5s;
}
.page-change-leave-active {
animation: change-page .5s reverse;
}
@keyframes change-page-in {
0% {
transform: translate(100%,-100%);
}
100% {
transform: translate(0,-100%);
}
}
</style>
<Transition name="slide-fade">
<p v-if="show">hello</p>
</Transition>
<style>
/* 进入和离开动画可以使用不同,持续时间和速度曲线 */
.slide-fade-enter-active {
transition: all 0.3s ease-out;
}
.slide-fade-leave-active {
transition: all 0.8s cubic-bezier(1, 0.5, 0.8, 1);
}
.slide-fade-enter-from,
.slide-fade-leave-to {
transform: translateX(20px);
opacity: 0;
}
</style>

transition 上携带的参数

// 参数 props:
name 动画的名称,可以为动态
duration 控制动画时间
css 不使用 CSS 动画
appear 节点初次渲染时应用一个过渡效果,你可以添加
mode="out-in" 表示,当一个组件所有动画完成后,才执行下一个动画,而不是同时执行第一个的退出,和第二个的进入
<template>
<div>
<Transition :duration="500" :css="false"></Transition>
<Transition :duration="{enter:550,leave:800}"></Transition>
</div>
</template>
// 事件 evnets
@before-enter
@enter
@after-enter
@enter-cancelled
@before-leave
@leave
@after-leave
@leave-cancelled

transition-group

也是 vue 内置组件,有和 transition 有基本相同的 props、css 过度、class、JavaScript 监听器。

区别:

  • 默认不会渲染一个容器元素,但可以传入 tag 指定 某个元素进行渲染,
  • 不支持一部分 mode,
  • 每一项必须有独一无二的 key
  • CSS 会被加入到列表内各项,而不是容器元素

参考文章

作者文章名称
Vue官方文档单文件组件 CSS 功能