Vue3相关学习记录
基础概念
Vue 3 是一个用于构建用户界面的渐进式 JavaScript 框架,尤其适合开发前端单页应用(SPA)。它的核心理念是通过声明式的方式将数据绑定到 DOM 上,并提供了便捷的工具来处理复杂的 UI 交互。
其主要涉及JavaScript(弱类型语言)/HTML(网页结构,标记语言)/CSS(样式属性)
JavaScript整个执行流程类似于一个QT的事件循环,是单线程的,因此异步实现需要使用Promise期约来避免阻塞主线程,其中:
async
关键字用于声明异步函数,函数内部可以使用await
来等待异步操作完成。await
用于暂停异步函数的执行,直到Promise
完成。async
函数总是返回一个Promise
,可以使用.then()
和.catch()
来处理成功或失败的结果。Promise
内部的执行器函数在Promise
对象创建时立即同步执行。
Vue3 应用的根组件实例可通过Vue.createApp()创建,其中:
- 定义
data
来存储数据; - 使用
methods
定义方法; - 使用
computed
计算属性; - 使用
mounted
、created
等生命周期钩子; - 通过
app.mount()
将应用挂载到 DOM(文档对象模型,即网页内容) 上。
1. data
:用于定义组件的数据(类似于 Vue 2)
- 这个函数返回一个对象,包含与应用相关的数据。Vue 会自动将这些数据与模板中的插值表达式进行绑定。
2. methods
:定义应用中的方法
methods
是一个对象,里面定义了在应用中可以调用的函数。例如changeMessage
是在点击按钮时触发的函数。
3. computed
:定义计算属性
- 计算属性是基于其他数据的值来计算的,它们具有缓存特性,只有当依赖的数据变化时才会重新计算。
4. mounted
/ created
等生命周期钩子
- 这些钩子函数会在组件生命周期的不同阶段执行。
created
在 Vue 实例被创建后立即执行,而mounted
在实例挂载到 DOM 后调用。
5. template
(可选)
- 可以直接在
createApp
对象内定义组件的模板,也可以在外部 HTML 中通过id
引用。template
是用来描述组件的视图结构的。
6. components
:局部注册组件
- 这里可以注册局部组件,将它们在当前应用内使用。
7. provide
/ inject
:用于父子组件间共享数据
provide
和inject
用于祖先和后代组件之间的依赖注入,帮助跨组件层次结构传递数据。
8. mount
:挂载 Vue 实例
mount()
方法告诉 Vue 应用实例,应该将应用渲染到哪个 DOM 元素上。你需要传入一个 CSS 选择器或实际的 DOM 节点来挂载应用。
Vue3 常用指令:
指令 |
实例 |
简写 |
描述 |
v-bind |
v-bind:attr="value" |
:attr="value" |
用于绑定动态属性 |
v-on |
v-on:event="handler" |
@event="handler" |
用于监听事件 |
v-model |
v-model="value" |
/ |
用于双向绑定表单元素的值 |
v-slot |
<template v-slot:name> |
<template #name> |
用于在父组件中插入子组件内容,支持插槽功能 |
v-if |
v-if="condition" |
/ |
根据条件渲染元素 |
v-else-if |
v-else-if="condition" |
/ |
根据条件渲染元素 |
v-else |
v-else |
/ |
根据条件渲染元素 |
v-show |
v-show="condition" |
/ |
通过 display 样式控制元素显示或隐藏 |
v-for |
v-for="item in list" |
/ |
用于列表渲染,遍历数组或对象 |
v-pre |
v-pre |
/ |
跳过编译,直接渲染原始内容 |
v-cloak |
v-cloak |
/ |
防止 Vue 加载期间内容闪烁 |
v-once |
v-once |
/ |
一次性渲染元素,提高性能 |
组件
一般组件为src/components
目录下的.vue文件,例如简单创建一个MyComponent.vue文件:
<template> <div> <h1>{{ title }}</h1> <p>{{ message }}</p> </div> </template> <script setup> import { ref } from 'vue'; const title = ref('Hello from MyComponent'); const message = ref('This is a simple Vue component.'); </script> <style scoped> h1 { color: blue; } </style>
<template>
部分定义了组件的 HTML 结构。<script setup>
中可以定义组件的逻辑,比如数据和方法。<style scoped>
用于定义组件的样式,scoped
确保样式只应用于该组件。
若想在父组件使用,则需要导入并注册它:
<template> <div id="app"> <MyComponent /> </div> </template> <script setup> import MyComponent from './components/MyComponent.vue'; </script> <style> /* 这里可以添加全局样式 */ </style>
在 <script setup>
中导入 MyComponent
,然后在模板中使用 <MyComponent />
标签。
Vite架构下,你也可以在App.vue同级目录下创建components.d.ts来扩展‘vue’的定义,使得组件能够被全局使用:
//这里使用 declare module 来扩展 Vue 的类型定义,使得你可以在 Vue 中使用全局组件,并且 TypeScript 能够识别这些组件的类型。 declare module 'vue' { //通过扩展 GlobalComponents 接口,你可以定义项目中所有全局注册的组件,使得它们在任何地方都可以被访问,并且 TypeScript 会为这些组件提供类型检查。 export interface GlobalComponents { //对于每个组件,使用 typeof import() 语法来引入组件的类型。这种方式确保 TypeScript 可以正确识别组件的类型,避免在使用时出现类型错误。 MyComponent: typeof import('./components/MyComponent.vue')['default'] } }
使用 Props
props可让组件从其父组件接收数据,修改 MyComponent.vue
使其接收一个 msg
属性:
<template> <div> <h1>{{ title }}</h1> <p>{{ msg }}</p> </div> </template> <script setup> import { ref, defineProps } from 'vue'; const props = defineProps(['msg']); const title = ref('Hello from MyComponent'); </script>
在父组件中使用:<MyComponent msg="This message is passed as a prop." />
Emit 事件
如果你希望组件向父组件发送消息,可以使用事件:
<template> <button @click="sendMessage">Send Message</button> </template> <script setup> import { defineEmits } from 'vue'; const emit = defineEmits(); const sendMessage = () => { emit('message-sent', 'Hello from MyComponent!'); }; </script>
在父组件中监听事件:
<MyComponent @message-sent="handleMessage" /> <script setup> const handleMessage = (msg) => { console.log(msg); // 处理来自 MyComponent 的消息 }; </script>
在 Vue 3 中,你可以通过模板语法轻松地绑定数据和事件。
数据绑定
Vue 提供了两种主要的数据绑定方式:插值绑定和指令绑定。
a. 插值绑定
插值绑定允许你在 HTML 模板中直接插入 Vue 实例中的数据。使用双大括号 {{ }}
进行绑定。
<template> <div> <h1>{{ title }}</h1> <p>{{ message }}</p> </div> </template> <script setup> import { ref } from 'vue'; const title = ref('Hello, Vue 3!'); const message = ref('This is a simple example of data binding.'); </script>
在这个例子中,title
和 message
的值会动态显示在页面上。
b. 指令绑定
指令是以 v-
前缀开头的特殊属性,用于动态地绑定数据。
<template> <div> <p v-if="isVisible">This paragraph is visible.</p> <button @click="toggleVisibility">Toggle Visibility</button> </div> </template> <script setup> import { ref } from 'vue'; const isVisible = ref(true); const toggleVisibility = () => { isVisible.value = !isVisible.value; }; </script>
在这个例子中,v-if
指令根据 isVisible
的值决定是否渲染段落。
事件绑定
事件绑定允许你在用户与界面交互时执行 JavaScript 代码。在 Vue 中,可以使用 @
符号(或 v-on
指令)来绑定事件。
<template> <div> <button @click="increment">Click me!</button> <p>You've clicked the button {{ count }} times.</p> </div> </template> <script setup> import { ref } from 'vue'; const count = ref(0); const increment = () => { count.value++; }; </script>
在这个例子中,@click
绑定了一个点击事件,当按钮被点击时,increment
函数会被调用,count
的值会增加。
事件修饰符
Vue 还提供了一些事件修饰符来处理常见的场景,如 .prevent
和 .stop
。
<template> <form @submit.prevent="handleSubmit"> <input type="text" v-model="inputValue" /> <button type="submit">Submit</button> </form> </template> <script setup> import { ref } from 'vue'; const inputValue = ref(''); const handleSubmit = () => { console.log('Form submitted with value:', inputValue.value); }; </script>
在这个例子中,.prevent
修饰符阻止了表单的默认提交行为。
响应式状态
在 Vue 3 中,ref
和 reactive
是用于创建响应式状态的主要 API,即用来在Vue中创建数据对象,类似于c++的指针。
通常使用 ref
来管理简单状态,使用 reactive
来管理复杂状态。
ref
ref
用于创建基本数据类型的响应式引用,如字符串、数字、布尔值等。当你使用 ref
创建一个响应式状态时,访问和修改值的方式稍有不同,你需要使用 .value
属性。
<template> <div> <h1>{{ count }}</h1> <button @click="increment">Increment</button> </div> </template> <script setup> import { ref } from 'vue'; const count = ref(0); // 创建一个响应式引用 const increment = () => { count.value++; // 修改值时需要使用 .value }; </script>
reactive
reactive
用于创建响应式对象,适合于复杂数据结构,如对象和数组。你可以直接访问和修改对象的属性,无需使用 .value
。
<template> <div> <h1>{{ state.title }}</h1> <p>{{ state.counter }}</p> <button @click="increment">Increment</button> </div> </template> <script setup> import { reactive } from 'vue'; const state = reactive({ // 创建一个响应式对象 title: 'Counter App', counter: 0, }); const increment = () => { state.counter++; // 直接修改对象属性 }; </script>
在这个例子中,state
是一个响应式对象,包含 title
和 counter
两个属性。