Vue3【style-scoped、style-module、类和内联样式、props、练习】

news2024/9/23 9:25:57

文章目录

    • style-scoped
    • style-module
    • 类和内联样式
    • props
    • 练习


style-scoped

  • 可以直接通过style标签来编写样式,
    • 如果直接通过style标签写样式,此时编写的样式是全局样式
    • 会影响到所有的组件

  • 可以为style标签添加一个scoped属性,
  • 这样样式将成为局部样式,只对当前组件生效
    如何实现的?
    • 当我们在组件中使用scoped样式时,
      vue会自动为组件中的所有元素生成一个随机的属性
      形如:data-v-7a7a37b1
      生成后,所有的选择器都会在最后添加一个 [data-v-7a7a37b1]
      h1 -> h1[data-v-7a7a37b1]
      .box1 -> .box1[data-v-7a7a37b1]

    • 注意:

      • 随机生成的属性,除了会添加到当前组件内的所有元素上,
        也会添加到当前组件引入的其他组件的根元素上,这样设计
        是为了,可以通过父组件来为子组件设置一些样式。如果要
        使引入的其他组件生效,引入的组件要为单根组件。
<script setup>
import MyBox from "./components/MyBox.vue"
</script>

<template>
    <div class="app">
        <h1>今天天气真不错!</h1>
        <div class="box1">App中的box1</div>
        <MyBox></MyBox>
    </div>
</template>

<!-- 
  可以直接通过style标签来编写样式,
    如果直接通过style标签写样式,此时编写的样式是全局样式
    会影响到所有的组件

-->
<!-- <style>
h1 {
    background-color: #bfa;
}

.box1 {
    width: 200px;
    height: 200px;
    background-color: yellowgreen;
}
</style> -->

<!-- 可以为style标签添加一个scoped属性,
  这样样式将成为局部样式,只对当前组件生效 
如何实现的?
  - 当我们在组件中使用scoped样式时,
    vue会自动为组件中的所有元素生成一个随机的属性
    形如:data-v-7a7a37b1
    生成后,所有的选择器都会在最后添加一个 [data-v-7a7a37b1]
      h1 -> h1[data-v-7a7a37b1]
      .box1 -> .box1[data-v-7a7a37b1]

  - 注意:
      - 随机生成的属性,除了会添加到当前组件内的所有元素上,
        也会添加到当前组件引入的其他组件的根元素上,这样设计
        是为了,可以通过父组件来为子组件设置一些样式。如果要
        使引入的其他组件生效,引入的组件要为单根组件。

-->
<style scoped>
h1 {
    background-color: orange;
}
.box1 {
    width: 200px;
    height: 200px;
    background-color: #bfa;
}

/* 
将组件中所有的 h2的字体颜色设置为黄色 
.app h2 --> .app h2[xxxxx]   此时子组件的h2不生效,因为 样式添加到了单根组件的div上了

.app h2[data-v-7a7a37b1] 没用deep

.app[data-v-7a7a37b1] h2 用了deep
*/
.app :deep(h2) {
    color: yellow;
}

/* 
  :global() 全局选择器
*/
:global(div) {
    border: 1px red solid;
}
</style>

<!-- <style>
div {
    border: 1px red solid;
}
</style> -->

style-module

  • 自动的对模块中的类名进行hash化来确保类名的唯一性
  • 在模板中可以通过(默认) $style.类名 使用
  • 也可以通过module的属性值来指定变量名
<script setup>
import MyBox from "./components/MyBox.vue"
</script>

<template>
    <div class="app">
        <h1>今天天气真不错!</h1>
        <div :class="classes.box1">App中的box1</div>
        <MyBox></MyBox>
    </div>
</template>
<!-- 
  css 模块
    - 自动的对模块中的类名进行hash化来确保类名的唯一性
    - 在模板中可以通过(默认) $style.类名 使用
    - 也可以通过module的属性值来指定变量名

-->
<style module="classes">
.box1 {
    background-color: #bfa;
}
</style>

类和内联样式

<script setup>
const arr = ["box1", "box2", "box3"]
const arr2 = [{ box1: true }, { box2: false }, { box3: true }]
const style = {
    color: "red",
    backgroundColor: "#bfa"
}
</script>
<template>
    <h1 class="header">我爱Vue</h1>
    <div :class="arr" :style="style">我是div</div> <!--相当于<div class="box1 box2 box3>" -->
    <div :class="arr2" :style="style">我是div</div>
</template>
<style scoped>
.header {
    background-color: orange;
}
</style>

props

  • 子组件中的数据通常不会在子组件中直接定义,这样会导致数据和视图发生耦合!
  • 子组件中的数据通常会在创建组件实例时确定!
  • 父组件可以通过 props 来将数据传递给子组件

  • 使用props
    • 先在子组件中定义props

  • 父组件可以通过props来向子组件传递数据
    • 注意:父组件传递给子组件的props都是只读的,无法在子组件修改
      即使可以修改,我们也尽量不要在子组件中去修改父组件的数据
      如果非得要改,具体方法后边再讲(自定义事件)
    • 属性名
      - 定义属性名时,属性名要遵循驼峰命名法

App.vue

<script setup>
import MyBox from "./components/MyBox.vue"
import { ref } from "vue"

const count = ref(0)
const obj = ref({
    count: 0
})
</script>
<template>
    <h1>我是App根组件</h1>
    <MyBox :count="123" :obj="obj" maxLength="1231"></MyBox>
    <button @click="obj.count++">点我一下</button>
</template>

Mybox.vue


<script setup>
/* 
        父组件可以通过props来向子组件传递数据
        注意:父组件传递给子组件的props都是只读的,无法在子组件修改
            即使可以修改,我们也尽量不要在子组件中去修改父组件的数据
            如果非得要改,具体方法后边再讲(自定义事件)

        属性名
            - 定义属性名时,属性名要遵循驼峰命名法
            
    */

// 定义props
// count = 0
// obj = {count = 0}
const props = defineProps(["count", "obj", "maxLength"])

const props = defineProps({
  count: Number,//类型限制,实际作用不大
  obj: Object,
  isCheck: Boolean,
  maxLength: {
    type: String,//maxLength的类型
    required: true,//maxLength是否必传
    default: "哈哈",
    validator (value) {//检查传过来的参数是否合法,返回false不合法
      return value !== "嘻嘻"
    }
  }
})

console.log(props)
</script>

<template>
  <div>
    <h1>{{ props.maxLength }}</h1>
    <h2>我是子组件 MyBox {{ props.obj.count }}</h2>
    <button @click="props.count++">MB的按钮</button> <!--无法修改-->
    <button @click="props.obj.count++">MB的按钮</button> <!--可以修改,obj不可修改,但属性可以修改。不建议这样操作-->
    <hr />
  </div>
</template>

<style scoped>
div {
  color: tomato;
}
</style>

练习

在这里插入图片描述
App.vue

<script setup>
import { reactive, ref } from 'vue'
import TabItem from './components/TabItem.vue'
import TabList from './components/TabList.vue'
import Tab from './components/Tab.vue'


const players = reactive([
  {
    name: '梅西',
    img: '/images/messi.png',
    rate: 1,
    hot: 437890
  },
  {
    name: 'C罗',
    img: '/images/ronaldo.png',
    rate: 2,
    hot: 397890
  },
  {
    name: '内马尔',
    img: '/images/neymar.png',
    rate: 3,
    hot: 367890
  }
])

const teams = reactive([
  {
    name: '巴西',
    img: '/images/巴西.jpg',
    rate: 1,
    hot: 437890
  },
  {
    name: '法国',
    img: '/images/法国.jpg',
    rate: 2,
    hot: 357890
  },
  {
    name: '荷兰',
    img: '/images/荷兰.jpg',
    rate: 3,
    hot: 267890
  }
])
// 获取最大热度,也就是排名第一人的热度
const playMaxHot = players[0].hot
const teamMaxHot = teams[0].hot
</script>

<template>
  <Tab>
    <template #0>
      <TabList :items="players" :maxHot="playMaxHot"></TabList>
    </template>
    <template #1>
      <TabList :items="teams" :maxHot="teamMaxHot"></TabList>
    </template>
  </Tab>
</template>


Tab.vue

<script setup>
import { ref } from 'vue'

//创建一个变量来记录选项卡的状态
const current = ref(0) //0 表示球员 1表示球队
</script>

<template>
  <!-- 选项卡的外部容器 -->
  <div class="tab-wrapper">
    <!-- 选项卡的头部 -->
    <header class="tab-head">
      <!-- 定义两个按钮 -->
      <div @click="current = 0" class="tab-button" :class="{active : current === 0}">热门球员</div>
      <div @click="current = 1" class="tab-button" :class="{ active: current === 1 }">热门球队</div>
    </header>
    <!-- 选项卡的主体 -->
    <div class="main">
      <div v-show="current === 0">
        <!-- 球员 -->
        <slot name="0"></slot>
      </div>
      <div v-show="current === 1">
        <!-- 球队 -->
        <slot name="1"></slot>
      </div>
    </div>
  </div>
</template>

<style scoped>
.tab-wrapper {
  box-sizing: border-box;
  width: 800px;
  padding: 20px;
  background-color: rgb(45, 83, 211);
  margin: 0 auto;
}

.tab-head {
  display: flex;
  border-radius: 10px;
  overflow: hidden;
}

.tab-button {
  background-color: #fff;
  font-style: 30px;
  padding: 10px 0;
  text-align: center;
  flex: auto;
  transition: 0.5s;
}

.tab-button:not(.active):hover {
  color: rgb(187, 3, 52)
}

.active {
  background-color: rgb(187, 3, 52);
  color: #fff;
}
</style>

TabList.vue

<script setup>
import TabItem from './TabItem.vue'

//定义参数
const props = defineProps(["items", "maxHot"])
</script>
<template>
  <div class="tab-list">
    <TabItem v-for="player in props.items" :item="player" :maxHot="props.maxHot"></TabItem>
  </div>
</template>

<style scoped>
.tab-list {
  margin: 30px
}
</style>

TabItem.vue

<script setup>
import Photo from './Photo.vue'
import HotBar from './HotBar.vue'
//创建一个响应式对象

const props = defineProps(['item'])
const item = props.item

</script>
<template>
  <div class="tab-item">
    <!-- 图片 -->
    <Photo :src="item.img" :alt="item.name" :rate="item.rate"></Photo>
    <!-- 描述 -->
    <div class="desc">
      <span class="name">{{ item.name }}</span>
      <HotBar :hot="item.hot" :maxHot="555555"></HotBar>
    </div>
  </div>
</template>

<style scoped>
.tab-item {
  display: flex;
  margin-bottom: 40px;
}


.desc {
  display: flex;
  flex-flow: column;
  justify-content: space-evenly;
  font-size: 30px;
  color: #fff;
  flex: auto;
  margin-left: 30px;
}
</style>

HotBar.vue

<script setup>
import { computed } from 'vue';

const props = defineProps(['hot', 'maxHot'])

const width = computed(() => {
  //计算百分比
  return props.hot / props.maxHot * 100 + '%'
})
</script>

<template>
  <div class="hot-bar">
    <div class="inner">{{ props.hot }}热度</div>
  </div>
</template>

<style scoped>
.hot-bar {
  background-color: rgb(3, 37, 103);
  border-radius: 20px;
  text-indent: 0.5em;
}

.inner {
  width: v-bind(width);
  border-radius: 20px;
  background-image: linear-gradient(90deg,
      rgba(187, 3, 52) 50%,
      rgba(66, 2, 12));

  white-space: nowrap;
  /*文字不换行 */
}
</style>

Photo.vue

<script setup>
import { computed } from 'vue'

const props = defineProps(["src", "alt", "rate"])
const color = computed(() => {
  //判断颜色
  if (props.rate == 1) {
    return "rgb(254,45,70)"
  } else if (props.rate == 2) {
    return "rgb(245,102,1)"
  } else {
    return "rgb(247, 169, 1)"
  }
})

</script>
<template>
  <!-- 图片 -->
  <div class="photo">
    <img :src="props.src" alt="props.alt">
    <span>{{ props.rate }}</span>
  </div>
</template>

<style scoped>
.photo {
  position: relative;

  width: 150px;
  background-color: #fff;
  border-radius: 20px;
  overflow: hidden;
}

.photo img {
  width: 100%;
  vertical-align: middle;
}

.photo span {
  position: absolute;
  left: 0;
  top: 0;
  width: 50px;
  height: 50px;
  background-color: v-bind(color);
  font-size: 20px;
  font-weight: bold;
  color: #fff;
  display: flex;
  justify-content: center;
  align-items: center;
  border-bottom-right-radius: 20px;
}
</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/176799.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

为什么会有右值引用?(移动构造、移动赋值)

目录 1、左值引用的缺陷 2、移动构造&#xff1a;解决临时对象的深拷贝 3、拓展&#xff1a;移动赋值 1、左值引用的缺陷 左值引用作为函数参数传递&#xff0c;减少了参数拷贝&#xff1b;但是作为函数返回值&#xff0c;并不适用于所有场景&#xff0c;比如要返回一个临…

Linux——innode

目录 回顾缓冲区 标准错误流的理解 文件系统 Inode VS 文件名 创建/删除/查看文件系统做了什么 软硬链接 动静态库 习题 回顾缓冲区 关掉1&#xff0c;log.txt中没文件是因为&#xff0c;字符串在缓冲区当中&#xff0c;缓冲区还没刷新&#xff0c;我们把fd给关了…

堆的实现及应用

下面用C语言介绍堆的实现以及应用 文章目录1. 堆的简介2. 堆的实现HeapInitHeapDestroyHeapPushHeapPop3. 堆的应用堆排序TopK问题1. 堆的简介 堆是一颗完全二叉树。这里所说的堆是一种非连续的数据结构&#xff0c;与操作系统内存分布的堆是两回事&#xff0c;它们没有任何联…

金融帝国实验室(Capitalism Lab)官方中文汉化包下载(v4.03)

<FCT汉化小组>Vol.001号作品 ————————————— ◎作品名称&#xff1a;金融帝国实验室&#xff08;CapLab&#xff09;官方汉化包 ◎汉化作者&#xff1a;FCT汉化小组&#xff08;Enlight Software认证&#xff09; ◎发布版本&#xff1a;CapLab Simplifi…

POJ 1845 Sumdiv题解(C++ 整数惟一分解定理+分治法求等比数列之和+快速幂)

文章目录整数惟一分解定理分治法求等比数列和完整代码传送门&#xff1a; POJ 1845 SumDiv 整数惟一分解定理 任何一个大于1的整数n都可以分解成若干个质因数&#xff08;素因数&#xff09;的连乘积&#xff0c;如果不计各个素因数的顺序&#xff0c;那么这种分解是唯一的&a…

王者荣耀入门技能树

前言 最近在学习技能树&#xff0c;我也试着写一写技能树&#xff0c;放松一下。 这里附上一张可爱的兔兔应景。仔细看&#xff0c;后边题目会提到&#xff0c;哈哈。 职业 以下哪个不属于王者荣耀中的职业&#xff1a; 射手法师辅助亚瑟 技能 以下哪个技能可以加快打野…

春节假期后,如何快速让员工恢复上班的元气和状态?

每当假期过后&#xff0c;总有一些员工无法快速恢复工作状态&#xff0c;团队的氛围也很难一下子热起来。而春节假期既是长假&#xff0c;又是过节氛围最浓厚的假期&#xff0c;节后返工的涣散问题自然更明显一些。但对于服装店铺来说&#xff0c;年后开工正处于旺季&#xff0…

【Vue】我的尚品汇项目笔记---20230109~20230120

014之前可参考官方笔记 https://blog.csdn.net/weixin_43424325/article/details/121684101 015-axios二次封装 api/index.js 设定 //当前模块&#xff0c;API进行统一管理&#xff0c;即对请求接口统一管理 import requests from "/api/request";//首页三级分类…

通达信插件获取并存储通达信商品指数的实时数据

一、引子 通达信商品指数一共有23个&#xff0c;如下图所示&#xff1a; 如果想获取历史数据&#xff0c;只需要通过通达信的数据下载和导出功能即可&#xff0c;现在我们需要获取这23个指数的实时数据&#xff0c;通过导出功能就没有办法了。 在最初的阶段&#xff0c;考虑的…

微服务自动化管理【IDEA使用Docker插件进行一键部署】

本章目标 IDEA使用Docker插件实现springboot项目的一键部署 要开两个虚拟机 server registry server上进行操作 Docker开启远程api端口(注意这种配置方式只适用于开发和学习&#xff0c;在公共网络中不要这样配置&#xff0c;容易引发安全问题) 默认情况下dokcer是不支持远程…

linux基本功系列之find命令实战

文章目录前言&#x1f680;&#x1f680;&#x1f680;一. find命令介绍二. find常用参数及语法格式三. 示范案例3.1 查找符合文件名规则的文件3.2 根据文件类型类查找文件3.3 按照更改时间或访问时间等查找文件3.4 查找并执行相应的命令3.5 按照文件大小来查找3.6 按照文件所有…

启动hive报错no hbase in

启动hive报错no hbase in 将hdfs和yarn都启动成功之后&#xff0c;启动hive&#xff0c;如下所示&#xff1a;[atguiguhadoop102 conf]$ cd /opt/module/hive/ [atguiguhadoop102 hive]$ bin/hive报错信息如下which: no hbase in (/usr/local/bin:/usr/bin:/usr/local/sbin:/us…

C++ · 类和对象 · 02 | 类的6个默认成员函数

啊我摔倒了..有没有人扶我起来学习.... &#x1f471;个人主页&#xff1a;《CGod的个人主页》\color{Darkorange}{《CGod的个人主页》}《CGod的个人主页》交个朋友叭~ &#x1f492;个人社区&#xff1a;《编程成神技术交流社区》\color{Darkorange}{《编程成神技术交流社区》…

【操作系统】—— 如何安装双系统与多系统(带你快速了解)

&#x1f4dc; “作者 久绊A” 专注记录自己所整理的Java、web、sql等&#xff0c;IT技术干货、学习经验、面试资料、刷题记录&#xff0c;以及遇到的问题和解决方案&#xff0c;记录自己成长的点滴。 &#x1f341; 操作系统【带你快速了解】对于电脑来说&#xff0c;如果说…

博客系统项目的自动化测试

作者&#xff1a;~小明学编程 文章专栏&#xff1a;测试开发 格言&#xff1a;热爱编程的&#xff0c;终将被编程所厚爱。 目录 博客界面 测试用例 界面测试 功能测试 性能测试 兼容性测试 易用性测试 安全性测试 ​编辑自动化测试 登录界面的测试 界面文字模块 测…

ubuntu使用教程与常用命令

ubuntu使用教程 一、 Ubuntu简介 Ubuntu&#xff08;乌班图&#xff09;是一个基于Debian的以桌面应用为主的Linux操作系统&#xff0c;据说其名称来自非洲南部祖鲁语或科萨语的“ubuntu”一词&#xff0c;意思是“人性”、“我的存在是因为大家的存在”&#xff0c;是非洲传…

Python爬虫之Scrapy框架系列(5)——项目实战【某瓣Top250电影所有信息的txt文本存储】

上篇文章已经成功解析提取到豆瓣Top250电影想要的所有数据。下一步就是将其交给管道进行存储。 目录&#xff1a;1. 编写items.py文件&#xff08;定义结构化数据字段&#xff09;2. 爬虫文件里将数据一一对应字段名&#xff1a;3. 将数据返回给管道&#xff1a;4. 编写pipelin…

MCAL系列介绍04-ICU

本文框架1. 前言2. 基本概念3. ICU采集过程3.1 获取周期占空比3.2 获取边沿数量3.3 获取时间戳4. Autosar系列文章快速链接1. 前言 ICU驱动器是使用Input Capture Uint模块&#xff08;ICU&#xff09;解调PWM信号、计数脉冲、测量频率和占空比、生成简单中断以及唤醒中断的模…

树莓派配置Python虚拟环境、安装PyQt5、安装PySide2

要从头设置好一台可用于开发的树莓派&#xff0c;可以参考树莓派 4B 无屏幕&#xff0c;连接WiFi、SSH、VNC&#xff0c;系统换源、pip换源&#xff0c;安装中文输入法 Python虚拟环境 树莓派&#xff08;或者说arm平台&#xff09;使用Python虚拟环境的正确方式是使用pipenv…

【手写 Vue2.x 源码】第三十九篇 - 组件部分 - 创建组件虚拟节点

一&#xff0c;前言 上篇&#xff0c;介绍了组件部分-组件的合并&#xff0c;主要涉及以下几个点&#xff1a; 组件初始化情况&#xff1b;组件合并的位置&#xff1b;组件合并的策略&#xff1b;组件合并后测试&#xff1b; 本篇&#xff0c;组件部分-组件的编译&#xff1…