Vue 3 高级编程技巧
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
含义:provide
和 inject
用于在组件树中传递数据,适用父子组件,查找第一层父/子组件传递的数据
实例:
<!-- 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>