新的知识进入大脑

索引签名和Record

在你需要频繁动态增加属性的场景下,**Record<string, any> 是 Vue3 + TS 里最简洁、最实用、最无坑的写法**,比接口索引签名更省事。


为什么我强烈推荐 Record?

1. 代码极简,不用写 interface

你原本要写:

1
2
3
4
5
interface DynamicData {
a: number
[key: string]: any
}
const re = reactive<DynamicData>({ a:1 })

Record 一行搞定:

1
const re = reactive<Record<string, any>>({ a: 1 })

2. 完美支持频繁新增属性

1
2
3
4
re.b = 2
re.name = "test"
re.list = [1,2,3]
re.obj = { id: 10 }

✅ TS 不报错
✅ 响应式完全正常
✅ 想加什么加什么


3. 最关键:响应式没问题

很多人担心:动态加属性会不会不响应?

只要你用 reactive<Record<string, any>>
Vue 的 Proxy 会自动监听所有新增的属性,完全不用担心。


4. 如果你想要严格一点(不推荐 any)

可以用:

1
2
3
4
// 值只能是 string | number | boolean
const re = reactive<Record<string, string | number | boolean>>({
a: 1
})

最佳实践(直接复制用)

1
2
3
4
5
6
7
8
9
10
11
12
import { reactive } from 'vue'

// 🔥 最推荐:支持任意动态属性 + 响应式 + TS无警告
const re = reactive<Record<string, any>>({
a: 1
})

// 随便加
re.b = 2
re.c = 'hello'
re.user = { name: 'zs' }
re.flag = true

总结

频繁增加属性 → 必须用 Record<string, any>

  • 代码最短
  • TS 最友好
  • 响应式最稳
  • 维护成本最低

这是 Vue3 + TS 动态对象的行业标准写法

withDefaults

withDefaults 是 Vue 3 <script setup> 中配合 TypeScript 使用的一个编译时宏(Compiler Macro),主要作用是为通过 TypeScript 类型声明的 props 提供默认值


核心作用

<script setup> 中,当你使用 TypeScript 的泛型参数来定义 props 类型时,只能定义类型,无法直接设置默认值。withDefaults 就是为了解决这个问题,它允许你在保持类型安全的同时,为 props 指定默认值。


基本用法示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<script setup lang="ts">
import { withDefaults } from 'vue'

// 1. 定义 Props 的 TypeScript 接口
interface Props {
msg: string
count?: number // 可选属性
labels: string[]
}

// 2. 使用 withDefaults 包裹 defineProps
const props = withDefaults(defineProps<Props>(), {
// 为可选属性设置默认值
count: 0,
// 注意:对象或数组的默认值必须使用函数返回
labels: () => ['a', 'b']
})
</script>

关键点解析

  1. 无需手动导入:虽然上面的示例写了 import,但实际上 withDefaultsdefineProps 一样,是编译时宏,在 <script setup> 中可以直接使用,不导入也不会报错。
  2. 类型安全:它会确保你提供的默认值与你定义的 TypeScript 类型相匹配,如果类型不匹配,编译时会报错。
  3. 对象/数组默认值:和 Vue 2/3 的普通 props 规则一样,如果默认值是对象数组,必须通过一个函数返回(如上面的 labels: () => ['a', 'b'])。

总结

withDefaults 让你在享受 TypeScript 类型带来的安全感的同时,又能方便地给 props 设置默认值,是 Vue 3 + TypeScript 开发中的常用工具。

@vueuse/core 至全屏功能

文档地址:
https://vueuse.org/
https://vueuse.org.cn/guide/best-practice

有的,@vueuse/core 提供了 useFullscreen 函数来处理全屏功能。

基本用法

1
2
3
import { useFullscreen } from '@vueuse/core'

const { isFullscreen, enter, exit, toggle } = useFullscreen()

核心 API

  • isFullscreen: 响应式布尔值,表示当前是否处于全屏状态。
  • enter(): 进入全屏。
  • exit(): 退出全屏。
  • toggle(): 切换全屏状态。

示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
<script setup>
import { useFullscreen } from '@vueuse/core'

const { isFullscreen, toggle } = useFullscreen()
</script>

<template>
<div>
<button @click="toggle">
{{ isFullscreen ? '退出全屏' : '进入全屏' }}
</button>
</div>
</template>

进阶用法

你也可以指定要全屏的元素:

1
2
const el = ref(null)
const { enter } = useFullscreen(el) // 仅对 el 元素全屏

flex 的用法

flex: 0 1 和 flex:1 0 的核心区别

先记住flex 是三个属性的简写
flex: flex-grow flex-shrink flex-basis
默认值:flex: 0 1 auto


1. 逐字拆解对比

写法 flex-grow (放大) flex-shrink (缩小) flex-basis (基准尺寸) 核心行为
flex: 0 1 0 → 不放大 1 → 允许缩小 auto 只缩小,不放大
flex: 1 0 1 → 可以放大 0 → 禁止缩小 0% 只放大,不缩小

2. 直白解释(最关键)

flex: 0 1

  • 父容器有多余空间:子元素不抢占,保持自身大小
  • 父容器空间不足:子元素会被压缩变小
  • 适用场景:按钮、标签、固定大小的元素

flex: 1 0

  • 父容器有多余空间:子元素自动占满剩余空间
  • 父容器空间不足:子元素绝不缩小,会撑破父容器
  • 适用场景:自适应内容区、需要占满空间的模块

3. 代码演示(一眼看懂)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<style>
.box {
display: flex;
width: 300px;
border: 2px solid #000;
margin: 20px 0;
}
.item {
border: 1px solid red;
}
</style>

<!-- flex: 0 1 → 不放大,会缩小 -->
<div class="box">
<div class="item" style="flex:0 1">A(0 1)</div>
<div class="item" style="flex:0 1">B(0 1)</div>
</div>

<!-- flex: 1 0 → 会放大,不缩小 -->
<div class="box">
<div class="item" style="flex:1 0">C(1 0)</div>
<div class="item" style="flex:1 0">D(1 0)</div>
</div>

4. 最常用的等价写法

  • flex: 1 = flex: 1 1 0%(可放大+可缩小,最常用)
  • flex: none = flex: 0 0 auto(固定大小,完全不伸缩)

总结

  1. flex: 0 1 = 不放大 + 会缩小(默认行为)
  2. flex: 1 0 = 会放大 + 不缩小
  3. 核心看前两个值:第一个管放大,第二个管缩小

flex: 1

1. 核心原因:flex 简写的默认规则

flex 是三个属性的简写:
flex: flex-grow flex-shrink flex-basis

当你省略部分值时,浏览器会按以下规则自动补全

写法 补全后完整值 说明
flex: 1 flex: 1 1 0% 只写1个数值 → 补全 1 0%
flex: 1 1 flex: 1 1 0% 写2个数值 → 补全 0%

2. 逐属性对比验证

属性 flex: 1 flex: 1 1 结果
flex-grow 1 1 一致
flex-shrink 1 1 一致
flex-basis 0% 0% 一致

所以两者100% 等价,效果完全一样。


3. 最常用的 flex 简写速查表

为了方便你记忆,整理了最常用的几种:

简写写法 完整值 核心行为
flex: 1 flex: 1 1 0% 可放大+可缩小(最常用)
flex: none flex: 0 0 auto 固定大小,完全不伸缩
flex: auto flex: 1 1 auto 可放大+可缩小(基于内容宽度)

总结

flex: 1 = flex: 1 1 = flex: 1 1 0%
🌟 日常开发直接写 flex: 1 就行,更简洁!


新的知识进入大脑
https://cszy.top/20250325-Learn-Css/
作者
csorz
发布于
2025年3月25日
许可协议