Vue.js 基础知识(一)
·
Vue.js 基础知识(一)
基于 https://cn.vuejs.org/ 官方文档整理,以 组合式 API +
<script setup>为主要语法。
一、Vue 概述
Vue 是一款用于构建用户界面的渐进式 JavaScript 框架。核心特性:
- 声明式渲染:基于标准 HTML 拓展模板语法
- 响应性:自动跟踪 JS 状态并响应式更新 DOM
单文件组件 (SFC)
将逻辑、模板、样式封装在同一个 .vue 文件中:
<script setup>
import { ref, onMounted } from 'vue'
const count = ref(0)
function increment() { count.value++ }
onMounted(() => { console.log(`初始值: ${count.value}`) })
</script>
<template>
<button @click="increment">Count is: {{ count }}</button>
</template>
<style scoped>
button { font-weight: bold; }
</style>
API 风格选择
| 风格 | 适用场景 |
|---|---|
| 选项式 API | 低复杂度、无构建工具 |
组合式 API + <script setup> |
完整 SPA 项目(推荐) |
二、创建一个应用
import { createApp } from 'vue'
import App from './App.vue' // 从单文件组件导入根组件
const app = createApp(App) // 创建应用实例
app.mount('#app') // 挂载到 DOM
要点:
.mount()必须在所有应用配置和资源注册之后调用,返回根组件实例- 容器元素本身不属于应用,根组件内容渲染在其内部
- 根组件无
template时,Vue 自动使用容器的innerHTML作为模板
// 应用级配置
app.config.errorHandler = (err) => { /* 处理错误 */ }
// 全局注册组件
app.component('TodoDeleteButton', TodoDeleteButton)
// 同一页面可创建多个独立应用实例
const app1 = createApp({ /* ... */ })
app1.mount('#container-1')
三、模板语法
文本插值
<span>Message: {{ msg }}</span>
原始 HTML
<p v-html="rawHtml"></p>
安全警告:动态渲染任意 HTML 有 XSS 风险,永远不要使用用户提供的 HTML 内容。
v-html不能拼接组合模板。
Attribute 绑定
<div v-bind:id="dynamicId"></div>
<div :id="dynamicId"></div> <!-- 简写 -->
<div :id></div> <!-- 同名简写 (Vue 3.4+),等同于 :id="id" -->
<button :disabled="isButtonDisabled"></button> <!-- 布尔型 attribute -->
<!-- 动态绑定多个值 -->
<div v-bind="objectOfAttrs"></div>
const objectOfAttrs = {
id: 'container',
class: 'wrapper',
style: 'background-color:green'
}
v-bind 值为 null 或 undefined 时,该 attribute 从渲染元素上移除。
使用 JavaScript 表达式
{{ number + 1 }}
{{ ok ? 'YES' : 'NO' }}
{{ message.split('').reverse().join('') }}
<div :id="`list-${id}`"></div>
- 仅支持单一表达式,不支持语句和条件控制
- 表达式中的方法每次更新都会被重新调用,不应有副作用
- 表达式被沙盒化,仅能访问
Math、Date等有限全局对象
指令 (Directives)
指令是带 v- 前缀的特殊 attribute:
<a v-bind:href="url">...</a> <!-- :href 简写 -->
<a v-on:click="doSomething">...</a> <!-- @click 简写 -->
<a @[eventName]="doSomething">...</a> <!-- 动态参数 -->
<form @submit.prevent="onSubmit">...</form> <!-- 修饰符 -->
- 动态参数:值应为字符串或
null,避免空格和引号 - 修饰符:以
.指明的特殊后缀,如.prevent、.stop
四、响应式基础
ref()
ref() 是声明响应式状态的主要 API(推荐):
import { ref } from 'vue'
const count = ref(0)
console.log(count.value) // 0 — JS 中需要 .value
count.value++ // 触发响应式更新
- 模板中 ref 自动解包,无需
.value <script setup>中的顶层变量和函数可直接在模板中使用
reactive()
import { reactive } from 'vue'
const state = reactive({ count: 0 })
state.count++ // 无需 .value
reactive() 的三大局限性:
- 只能用于对象类型,不能持有原始值
- 不能替换整个对象(会丢失响应性)
- 对解构操作不友好(解构后丢失响应性)
推荐使用
ref()作为主要 API。
深层响应性
无论 ref() 还是 reactive(),嵌套对象/数组都自动具有深层响应性:
const obj = ref({ nested: { count: 0 }, arr: ['foo'] })
obj.value.nested.count++ // 深层修改也能被追踪
obj.value.arr.push('bar')
DOM 更新时机
DOM 更新不是同步的,Vue 在 “next tick” 中批量更新:
import { nextTick } from 'vue'
async function increment() {
count.value++
await nextTick() // DOM 已更新
}
ref 解包规则
| 场景 | 是否自动解包 |
|---|---|
| 模板中顶级属性 | 是 |
模板中嵌套属性 object.id |
仅作为插值最终值时解包 |
| reactive 对象的属性 | 是 |
| 数组 / 集合中的元素 | 否,需要 .value |
五、计算属性
基本用法
import { reactive, computed } from 'vue'
const author = reactive({ books: ['Vue 3 Guide', 'Vue 4 Mystery'] })
const publishedBooksMessage = computed(() => {
return author.books.length > 0 ? 'Yes' : 'No'
})
计算属性 vs 方法: 计算属性基于响应式依赖缓存,仅依赖变化时重新计算;方法每次重渲染都重新执行。
可写计算属性
const firstName = ref('John')
const lastName = ref('Doe')
const fullName = computed({
get() { return firstName.value + ' ' + lastName.value },
set(newValue) { [firstName.value, lastName.value] = newValue.split(' ') }
})
获取上一个值 (Vue 3.4+)
const count = ref(2)
const alwaysSmall = computed((previous) => {
return count.value <= 3 ? count.value : previous
})
最佳实践:
- Getter 不应有副作用(不做异步请求、不修改其他状态)
- 计算属性应视为只读的派生状态
更多推荐

所有评论(0)