Vue 3 高级编程技巧

发布于:2025-06-27 ⋅ 阅读:(16) ⋅ 点赞:(0)

Vue 3 高级编程技巧

1. 计算属性 (Computed Properties)

含义:计算属性在依赖变化时会自动更新。以下是一个示例,展示当 firstName 或 lastName 变化时,fullName 也会更新。

实例

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

const firstName = ref('John');
const lastName = ref('Doe');

// 计算属性
const fullName = computed(() => {
  return `${firstName.value} ${lastName.value}`;
});

const reversedFullName = computed(() => {
  return fullName.value.split('').reverse().join('');
});

const fullNameLength = computed(() => {
  return fullName.value.length;
});
</script>

<template>
  <div>
    <input v-model="firstName" placeholder="First Name" />
    <input v-model="lastName" placeholder="Last Name" />
    <p>Full Name: {{ fullName }}</p>
    <p>Reversed Full Name: {{ reversedFullName }}</p>
    <p>Full Name Length: {{ fullNameLength }}</p>
  </div>
</template>
2. 插槽 (Slots)

含义:插槽允许组件接收模板内容,并在组件内部渲染这些内容。它们提供了灵活的布局和内容分发机制。使用 #header 或 v-slot 语法来定义插槽内容。

实例

<!-- ParentComponent.vue -->
<script setup>
import ChildComponent from './ChildComponent.vue';
</script>

<template>
  <ChildComponent>
    <template #header>
      <h1>Header Content</h1>
    </template>
    <p>Default Slot Content</p>
  </ChildComponent>
</template>

<!-- ChildComponent.vue -->
<script setup>
</script>

<template>
  <div>
    <slot name="header"></slot>
    <slot></slot>
  </div>
</template>
3. 动态组件 (Dynamic Components)

含义:动态组件允许在运行时根据需要切换不同的组件。结合 component 标签和 is 属性实现。

实例

<script setup>
import { ref } from 'vue';
import ComponentA from './ComponentA.vue';
import ComponentB from './ComponentB.vue';

const currentComponent = ref('ComponentA');
</script>

<template>
  <component :is="currentComponent" />
  <button @click="currentComponent = 'ComponentA'">Show Component A</button>
  <button @click="currentComponent = 'ComponentB'">Show Component B</button>
</template>
4. 自定义指令 (Custom Directives)

含义:自定义指令用于直接操作 DOM 元素,可以用于添加事件监听器、修改样式等。

实例

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

const vFocus = {
  mounted(el) {
    el.focus();
  }
};

const vHighlight = {
  mounted(el) {
    el.style.backgroundColor = 'yellow';
  }
};

const vLog = {
  mounted(el) {
    console.log('Element mounted:', el);
  }
};
</script>

<template>
  <input v-focus />
  <div v-highlight>Highlighted Text</div>
  <div v-log>This element logs to console on mount.</div>
</template>
5. watch

含义watch 用于观察和响应 Vue 实例上的数据变动。当数据发生变化时,watch 可以执行异步操作或开销较大的操作,并获取变化前后的值。

实例

<script setup>
import { ref, watch } from 'vue';

const message = ref('Hello Vue!');
const count = ref(0);
const items = ref(['apple', 'banana', 'cherry']);
const user = ref({ name: 'Alice', age: 30 });

// 监听单个响应式变量
watch(message, (newVal, oldVal) => {
  console.log(`message changed from ${oldVal} to ${newVal}`);
});

// 监听对象属性
watch(
  () => user.value.name,
  (newName, oldName) => {
    console.log(`user name changed from ${oldName} to ${newName}`);
  }
);

// 监听数组的单个元素
watch(
  () => items.value[0],
  (newVal, oldVal) => {
    console.log(`First item changed from ${oldVal} to ${newVal}`);
  }
);

// 监听多个响应式变量
watch([message, count], ([newMessage, newCount], [oldMessage, oldCount]) => {
  console.log(`message changed from ${oldMessage} to ${newMessage}`);
  console.log(`count changed from ${oldCount} to ${newCount}`);
});

// 监听数组的多个元素
watch(
  [() => items.value[0], () => items.value[1]],
  ([newFirst, newSecond], [oldFirst, oldSecond]) => {
    console.log(`First item changed from ${oldFirst} to ${newFirst}`);
    console.log(`Second item changed from ${oldSecond} to ${newSecond}`);
  }
);

// 深度监听对象
watch(
  user,
  (newVal) => {
    console.log('user changed:', newVal);
  },
  { deep: true }
);
</script>

<template>
  <div>
    <input v-model="message" placeholder="Message" />
    <button @click="count++">Increment Count: {{ count }}</button>
    <button @click="items[0] = 'orange'">Change First Item</button>
    <button @click="items[1] = 'grape'">Change Second Item</button>
    <button @click="user.name = 'Bob'">Change User Name</button>
  </div>
</template>
6. provide + inject

含义provideinject 用于在组件树中传递数据,适用父子组件,查找第一层父/子组件传递的数据

实例

<!-- ParentComponent.vue -->
<script setup>
import { provide, ref } from 'vue';
import ChildComponent from './ChildComponent.vue';

const theme = ref('dark');
provide('theme', theme);
</script>

<template>
  <ChildComponent />
</template>

<!-- ChildComponent.vue -->
<script setup>
import { inject } from 'vue';

const theme = inject('theme');
</script>

<template>
  <div :class="theme">
    Current theme: {{ theme }}
  </div>
</template>

网站公告

今日签到

点亮在社区的每一天
去签到