2025年 Vue 开发必备的25个超实用技巧!

开发 前端
在 Vue.js 中,默认情况下,切换组件时会卸载当前组件。使用 <KeepAlive> 可以缓存组件状态。

本文来分享 25 个 Vue 开发必备的实用技巧!

使用 defineModel() 实现双向数据绑定

在 Vue 3.4 中,推荐使用 defineModel() 宏来实现双向数据绑定,这大大简化了代码。

<!-- 使用 defineModel 之前 -->
<script setup>
const props = defineProps(['modelValue'])
const emit = defineEmits(['update:modelValue'])
</script>

<template>
  <input
    :value="props.modelValue"
    @input="emit('update:modelValue', $event.target.value)"
  />
</template>

<!-- 使用 defineModel 之后 -->
<script setup>
const model = defineModel();
</script>

<template>
  <input v-model="model" />
</template>

避免滥用 ref()

在 Vue 中,不需要为每个变量都使用 ref(),只有在需要响应性时才使用。

<script setup>
  // 不需要响应性,不需要使用 ref()
  const links = [
    {
      name: 'about',
      href: '/about'
    },
    {
      name: 'terms of service',
      href: '/tos'
    },
    {
      name: 'contact us',
      href: '/contact'
    }
  ]

  // 需要响应性,使用 ref()
  const tabs = ref([
    {
      name: 'Privacy',
      url: '/privacy',
      isActive: true
    },
    {
      name: 'Permissions',
      url: '/permissions',
      isActive: false
    }
  ])
</script>

使用 v-bind 同名简写

Vue 3.4 引入了 v-bind 同名简写,进一步简化了代码。

<template>
  <!-- 之前 -->
  <img :id="id" :src="src" :alt="alt">

  <!-- 现在 -->
  <img :id :src :alt>
</template>

使用 shallowRef 优化性能

对于不需要深度响应性的大型数据结构,可以使用 shallowRef 来优化性能。

const state = shallowRef({ count: 1 })

// 不会触发更新
state.value.count = 2

// 会触发更新
state.value = { count: 2 }

类型化组件 emits

通过类型化 emits,可以获得更好的错误处理和编辑器支持。

const emit = defineEmits<{
  change: [id: number]
  update: [value: string]
}>()

在 <style> 中使用 v-bind

Vue 允许在 <style> 中使用 v-bind 来绑定动态值,并且它是完全响应式的。

<style scoped>
  button {
    background-color: v-bind(backgroundColor);
  }
</style>

使用 Tanstack Query 简化数据获取

Tanstack Query(Vue Query)可以大大减少数据获取的样板代码,并提供自动缓存、自动重新获取等强大功能。

// 之前的数据获取模式
const posts = ref([]);
const isLoading = ref(false);
const isError = ref(false);

async function fetchPosts() {
  isLoading.value = true;
  isError.value = false;
  try {
    const response = await fetch('someurl');
    posts.value = await response.json();
  } catch(error) {
    isError.value = true;
  } finally {
    isLoading.value = false;
  }
}

onMounted(() => {
  fetchPosts();
})

// 使用 Tanstack Query 简化
const {data: posts, isLoading, isError} = useQuery({
  queryKey: ['posts'],
  queryFn: fetchPosts
})

async function fetchPosts() {
  const response = await fetch('someurl');
  const data = await response.json();
  return data;
}

使用 :global 伪类应用全局样式

在 Vue 中,使用 :global 伪类可以在局部样式中应用全局样式。

<style scoped>
  :global(.red) {
    color: red;
  }
</style>

使用 withDefaults 设置默认值

即使在使用类型声明的 defineProps 时,也可以使用 withDefaults 宏来设置默认值。

<script setup lang="ts">
  export interface Props {
    variant?: 'primary' | 'secondary'
    disabled?: boolean
  }

  const props = withDefaults(defineProps<Props>(), {
    variant: 'primary',
    disabled: false
  })
</script>

自定义指令

在 Vue 中,可以通过创建一个包含生命周期钩子的对象来注册自定义指令。

<script setup>
  // 在模板中启用 v-focus
  const vFocus = {
    mounted: (el) => el.focus()
  }
</script>

<template>
  <input v-focus />
</template>

使用 :deep() 伪类影响子组件样式

在局部样式中,使用 :deep() 伪类可以影响子组件的样式。

<style scoped>
  .a :deep(.b) {
    /* ... */
  }
</style>

使用 :slotted 伪类针对插槽内容

默认情况下,局部样式不会影响通过 <slot/> 渲染的内容。使用 :slotted 伪类可以显式地针对插槽内容。

<style scoped>
  :slotted(div) {
    color: red;
  }
</style>

使用 <KeepAlive> 缓存组件状态

在 Vue.js 中,默认情况下,切换组件时会卸载当前组件。使用 <KeepAlive> 可以缓存组件状态。

<template>
  <KeepAlive>
    <component :is="activeComponent" />
  </KeepAlive>
</template>

传递多个具名插槽

在 Vue.js 中,可以向子组件传递多个具名插槽。

<!-- 子组件 / Input.vue -->
<template>
  <div class="input-wrapper">
    <label>
      <slot name="label" />
    </label>
    <input />
    <div class="input-icon">
      <slot name="icon" />
    </div>
  </div>
</template>

<!-- 父组件 -->
<template>
  <Input>
    <template #label>
      Email
    </template>
    <template #icon>
      <EmailIcon />
    </template>
  </Input>
</template>

使用 Suspense 处理异步依赖

通过实验性的 Suspense 组件,可以在组件树中协调异步依赖,并在等待多个嵌套异步依赖解析时渲染加载状态。

<template>
  <Suspense>
    <!-- 包含嵌套异步依赖的组件 -->
    <Dashboard />
    <!-- 通过 #fallback 插槽显示加载状态 -->
    <template #fallback>
      Loading...
    </template>
  </Suspense>
</template>

使用 Teleport 传送模板部分

在 Vue 中,可以使用内置的 Teleport 组件将模板的一部分传送到组件 DOM 层次结构之外的 DOM 节点。

<template>
  <Teleport to="body">
    <div v-if="open" class="modal">
      <p>Hello from the modal!</p>
      <button @click="open = false">Close</button>
    </div>
  </Teleport>
</template>

启用性能追踪

在 Vue 中,可以在浏览器开发者工具的性能/时间线面板中启用性能追踪。这仅在开发模式下有效。

const app = createApp(App);
app.config.performance = true;
app.mount('#app');

动态渲染组件

在 Vue 中,可以使用内置的 <Component> 组件动态渲染组件。

<script setup>
  import UserSettings from './Foo.vue'
  import UserNotifications from './Bar.vue'
  const activeComponent = ref(UserSettings);
</script>

<template>
  <component :is="activeComponent" />
</template>

布尔类型 prop 的简写

在 Vue 中,当传递布尔类型的 prop 且值为 true 时,可以使用简写形式。

<template>
  <!-- 可以使用这种形式 -->
  <BlogPost is-published />
  <!-- 而不是这种形式 -->
  <BlogPost :is-published="true" />
</template>

使用 v-model 修饰符

默认情况下,v-model 在每次 input 事件后同步数据。可以使用 lazy 修饰符改为在 change 事件后同步。

<!-- 在 "change" 事件后同步 -->
<input v-model.lazy="msg" />

自动类型转换

如果希望用户输入自动转换为数字,可以在 v-model 上添加 number 修饰符。

<input v-model.number="age" />

自动修剪空格

如果希望自动修剪用户输入的空格,可以在 v-model 上添加 trim 修饰符。

<input v-model.trim="msg" />

使用 defineExpose 暴露属性

在 <script setup> 组件中,默认是关闭的。使用 defineExpose 编译器宏可以显式暴露属性。

<script setup>
  import { ref } from 'vue'
  
  const a = 1
  const b = ref(2)
  
  defineExpose({
    a,
    b
  })
</script>

合并类和样式

在 Vue 中,当组件模板中有一些类,并且在父组件中也添加了一些类时,这些类会自动合并。

<!-- 父组件 -->
<template>
  <Table class="py-2"></Table>
</template>

<!-- 子组件 Table.vue -->
<template>
  <table class="border-solid border-2 border-sky-500">
    <!-- ... -->
  </table>
</template>

<!-- 合并后的类 -->
<template>
  <table class="border-solid border-2 border-sky-500 py-2">
    <!-- ... -->
  </table>
</template>

启用自定义格式化器

在 Vue 中,启用自定义格式化器可以在控制台中更好地查看响应式数据。可以在 Chrome 浏览器的开发者工具中启用自定义格式化器,选择 Console -> custom formatters。

图片

参考:https://vuejstips.com/

责任编辑:武晓燕 来源: 前端充电宝
相关推荐

2024-04-29 09:02:46

Vue页面动画样式

2022-10-11 08:00:47

多线程开发技巧

2020-03-09 10:31:58

vue前端开发

2012-03-07 14:46:29

2024-03-28 08:15:09

Spring技巧配置

2024-05-22 09:29:43

2009-12-21 15:50:39

2020-12-03 18:38:19

iPhoneiOS功能

2022-03-23 09:18:10

Git技巧Linux

2009-09-04 10:27:28

Linux实用技巧linux操作系统linux

2022-12-07 10:21:19

谷歌搜索技巧

2021-01-21 08:00:00

开发工具VS Code

2024-11-26 14:18:44

Python代码技巧

2021-11-15 10:02:16

Python命令技巧

2023-07-24 07:11:43

2023-04-26 00:34:36

Python技巧程序员

2024-09-11 16:30:55

Python函数编程

2021-04-12 15:54:45

Android 开发技巧

2024-01-08 18:05:19

PyCharm技巧功能

2010-10-08 15:44:17

vim
点赞
收藏

51CTO技术栈公众号