Vue3 学习记录
VUE3 学习记录
模板语法
绑定文本值
<p>Using text interpolation: {{ rawHtml }}</p>
<p>Using v-html directive: <span v-html="rawHtml"></span></p>
绑定 Attribute
<div v-bind:id="dynamicId"></div>
<div :id="dynamicId">简写</div>
动态绑定多个值
const objectOfAttrs = {
id: 'container',
class: 'wrapper'
}
通过不带参数的 v-bind
,你可以将它们绑定到单个元素上:
<div v-bind="objectOfAttrs"></div>
在 Vue
模板内,JavaScript 表达式可以被使用在如下场景上:
- 在文本插值中 (双大括号)
- 在任何
Vue
指令 (以v-
开头的特殊 attribute) attribute 的值中
可以在绑定的表达式中使用一个组件暴露的方法:
<span :title="toTitleDate(date)">
{{ formatDate(date) }}
</span>
参数 Arguments
<a v-bind:href="url"> ... </a>
<!-- 简写 -->
<a :href="url"> ... </a>
<a v-on:click="doSomething"> ... </a>
<!-- 简写 -->
<a @click="doSomething"> ... </a>
动态参数
<!--
注意,参数表达式有一些约束,
参见下面“动态参数值的限制”与“动态参数语法的限制”章节的解释
-->
<a v-bind:[attributeName]="url"> ... </a>
<!-- 简写 -->
<a :[attributeName]="url"> ... </a>
这里的 attributeName
会作为一个 JavaScript 表达式被动态执行,计算得到的值会被用作最终的参数。举例来说,如果你的组件实例有一个数据属性 attributeName
,其值为 "href"
,那么这个绑定就等价于 v-bind:href
。
相似地,你还可以将一个函数绑定到动态的事件名称上:
<a v-on:[eventName]="doSomething"> ... </a>
<!-- 简写 -->
<a @[eventName]="doSomething">
在此示例中,当 eventName
的值是 "focus"
时,v-on:[eventName]
就等价于 v-on:focus
。
修饰符 Modifiers
修饰符是以点开头的特殊后缀,表明指令需要以一些特殊的方式被绑定。例如 .prevent
修饰符会告知 v-on
指令对触发的事件调用 event.preventDefault()
:
<form @submit.prevent="onSubmit">...</form>
响应式基础
我们可以使用 reactive()
函数创建一个响应式对象或数组:
import { reactive } from 'vue'
const state = reactive({ count: 0 })
reactive()
API 有两条限制:
- 仅对对象类型有效(对象、数组和
Map
、Set
这样的集合类型),而对string
、number
和boolean
这样的 原始类型 无效。 - 因为 Vue 的响应式系统是通过属性访问进行追踪的,因此我们必须始终保持对该响应式对象的相同引用。这意味着我们不可以随意地“替换”一个响应式对象,因为这将导致对初始引用的响应性连接丢失:
Vue 提供了一个 ref()
方法来允许我们创建可以使用任何值类型的响应式 ref
计算属性
<script setup>
import { reactive, computed } from 'vue'
const author = reactive({
name: 'John Doe',
books: [
'Vue 2 - Advanced Guide',
'Vue 3 - Basic Guide',
'Vue 4 - The Mystery'
]
})
// 一个计算属性 ref
const publishedBooksMessage = computed(() => {
return author.books.length > 0 ? 'Yes' : 'No'
})
</script>
<template>
<p>Has published books:</p>
<span>{{ publishedBooksMessage }}</span>
</template>
我们在这里定义了一个计算属性 publishedBooksMessage
。computed()
方法期望接收一个 getter 函数,返回值为一个计算属性 ref。和其他一般的 ref 类似,你可以通过 publishedBooksMessage.value
访问计算结果。计算属性 ref 也会在模板中自动解包,因此在模板表达式中引用时无需添加 .value
。
Vue 的计算属性会自动追踪响应式依赖。它会检测到 publishedBooksMessage
依赖于 author.books
,所以当 author.books
改变时,任何依赖于 publishedBooksMessage
的绑定都会同时更新。
计算属性值会基于其响应式依赖被缓存。一个计算属性仅会在其响应式依赖更新时才重新计算。 方法调用总是会在重渲染发生时再次执行函数。
默认是只读的,但是可以设计可以写入,但基本用不到
类与样式绑定
我们可以给 :class
(v-bind:class
的缩写) 传递一个对象来动态切换 class:
<div :class="{ active: isActive }"></div>
上面的语法表示 active
是否存在取决于数据属性 isActive
的真假值。
这也会渲染出相同的结果。我们也可以绑定一个返回对象的计算属性。这是一个常见且很有用的技巧:
const isActive = ref(true)
const error = ref(null)
const classObject = computed(() => ({
active: isActive.value && !error.value,
'text-danger': error.value && error.value.type === 'fatal'
}))
<div :class="classObject"></div>
绑定数组
我们可以给 :class
绑定一个数组来渲染多个 CSS class:
const activeClass = ref('active')
const errorClass = ref('text-danger')
<div :class="[activeClass, errorClass]"></div>
渲染的结果是:
<div class="active text-danger"></div>
如果你也想在数组中有条件地渲染某个 class,你可以使用三元表达式:
<div :class="[isActive ? activeClass : '', errorClass]"></div>
errorClass
会一直存在,但 activeClass
只会在 isActive
为真时才存在。
然而,这可能在有多个依赖条件的 class 时会有些冗长。因此也可以在数组中嵌套对象:
<div :class="[{ active: isActive }, errorClass]"></div>
组件上也可使用
绑定内联样式
:style
支持绑定 JavaScript 对象值,对应的是 HTML 元素的 style
属性:
const activeColor = ref('red')
const fontSize = ref(30)
<div :style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
尽管推荐使用 camelCase
,但 :style
也支持 kebab-cased 形式的 CSS 属性 key (对应其 CSS 中的实际名称),例如:
<div :style="{ 'font-size': fontSize + 'px' }"></div>
直接绑定一个样式对象通常是一个好主意,这样可以使模板更加简洁:
const styleObject = reactive({
color: 'red',
fontSize: '13px'
})
<div :style="styleObject"></div>
同样的,如果样式对象需要更复杂的逻辑,也可以使用返回样式对象的计算属性。
:style 可以添加自动前缀。此外 可以绑定数据,style或内多值会渲染最后一个属性
条件渲染
//v-if
//v-else
//v-else-if
<div v-if="type === 'A'">
A
</div>
<div v-else-if="type === 'B'">
B
</div>
<div v-else-if="type === 'C'">
C
</div>
<div v-else>
Not A/B/C
</div>
v-if
也是惰性的:如果在初次渲染时条件值为 false,则不会做任何事。条件区块只有当条件首次变为 true 时才被渲染。
相比之下,v-show
简单许多,元素无论初始条件如何,始终会被渲染,只有 CSS display
属性会被切换。
列表渲染
我们可以使用 v-for
指令基于一个数组来渲染一个列表。v-for
指令的值需要使用 item in items
形式的特殊语法,其中 items
是源数据的数组,而 item
是迭代项的别名:
const items = ref([{ message: 'Foo' }, { message: 'Bar' }])
<li v-for="item in items">
{{ item.message }}
</li>
<template v-for="todo in todos" :key="todo.name">
<li>{{ todo.name }}</li>
</template>
Vue 能够侦听响应式数组的变更方法,并在它们被调用时触发相关的更新。这些变更方法包括:
push()
pop()
shift()
unshift()
splice()
sort()
reverse()
事件处理
我们可以使用 v-on
指令 (简写为 @
) 来监听 DOM 事件,并在事件触发时执行对应的 JavaScript。用法:v-on:click="handler"
或 @click="handler"
。
function say(message) {
alert(message)
}
<button @click="say('hello')">Say hello</button>
<button @click="say('bye')">Say bye</button>
事件修饰符 大概率用不上 先mark下
按键修饰符
<!-- 仅在 `key` 为 `Enter` 时调用 `submit` -->
<input @keyup.enter="submit" />
别名
.enter
.tab
.delete
(捕获“Delete”和“Backspace”两个按键).esc
.space
.up
.down
.left
.right
.ctrl
.alt
.shift
.meta
举例:
<!-- Alt + Enter -->
<input @keyup.alt.enter="clear" />
<!-- Ctrl + 点击 -->
<div @click.ctrl="doSomething">Do something</div>
.exact
修饰符
.exact
修饰符允许控制触发一个事件所需的确定组合的系统按键修饰符。
<!-- 当按下 Ctrl 时,即使同时按下 Alt 或 Shift 也会触发 -->
<button @click.ctrl="onClick">A</button>
<!-- 仅当按下 Ctrl 且未按任何其他键时才会触发 -->
<button @click.ctrl.exact="onCtrlClick">A</button>
<!-- 仅当没有按下任何系统按键时触发 -->
<button @click.exact="onClick">A</button>
鼠标按键修饰符
.left
.right
.middle
表单输入绑定
<input v-model="text">
- 文本类型的
<input>
和<textarea>
元素会绑定value
property 并侦听input
事件; <input type="checkbox">
和<input type="radio">
会绑定checked
property 并侦听change
事件;<select>
会绑定value
property 并侦听change
事件。
复选框
<input type="checkbox" id="checkbox" v-model="checked" />
<label for="checkbox">{{ checked }}</label>
单选
<div>Picked: {{ picked }}</div>
<input type="radio" id="one" value="One" v-model="picked" />
<label for="one">One</label>
<input type="radio" id="two" value="Two" v-model="picked" />
<label for="two">Two</label>
选择器
<div>Selected: {{ selected }}</div>
<select v-model="selected">
<option disabled value="">Please select one</option>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
多选
<div>Selected: {{ selected }}</div>
<select v-model="selected" multiple>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
v-for
渲染选择器
const selected = ref('A')
const options = ref([
{ text: 'One', value: 'A' },
{ text: 'Two', value: 'B' },
{ text: 'Three', value: 'C' }
])
<select v-model="selected">
<option v-for="option in options" :value="option.value">
{{ option.text }}
</option>
</select>
<div>Selected: {{ selected }}</div>
值绑定 感觉也用不到
修饰符
.lazy
在change
后更新input
数据
.number
将输入转数字
.trim
去除两端空格
生命周期钩子
注册周期钩子
onMounted
举例来说,onMounted
钩子可以用来在组件完成初始渲染并创建 DOM 节点后运行代码:
<script setup>
import { onMounted } from 'vue'
onMounted(() => {
console.log(`the component is now mounted.`)
})
</script>
onUpdated
注册一个回调函数,在组件因为响应式状态变更而更新其 DOM 树之后调用。
function onUpdated(callback: () => void): void
onUnmounted
注册一个回调函数,在组件实例被卸载之后调用。
侦听器
计算属性允许我们声明性地计算衍生值。然而在有些情况下,我们需要在状态变化时执行一些“副作用”:例如更改 DOM,或是根据异步操作的结果去修改另一处的状态。
在组合式 API 中,我们可以使用 watch
函数在每次响应式状态发生变化时触发回调函数:
<script setup>
import { ref, watch } from 'vue'
const question = ref('')
const answer = ref('Questions usually contain a question mark. ;-)')
// 可以直接侦听一个 ref
watch(question, async (newQuestion, oldQuestion) => {
if (newQuestion.indexOf('?') > -1) {
answer.value = 'Thinking...'
try {
const res = await fetch('https://yesno.wtf/api')
answer.value = (await res.json()).answer
} catch (error) {
answer.value = 'Error! Could not reach the API. ' + error
}
}
})
</script>
<template>
<p>
Ask a yes/no question:
<input v-model="question" />
</p>
<p>{{ answer }}</p>
</template>
watch
的第一个参数可以是不同形式的“数据源”:它可以是一个 ref (包括计算属性)、一个响应式对象、一个 getter 函数、或多个数据源组成的数组:
即时回调的侦听器
watch
默认是懒执行的:仅当数据源变化时,才会执行回调。但在某些场景中,我们希望在创建侦听器时,立即执行一遍回调。举例来说,我们想请求一些初始数据,然后在相关状态更改时重新请求数据。
我们可以通过传入 immediate: true
选项来强制侦听器的回调立即执行
简单会用即可,具体可能不太用到
组件基础
动态组件
通过 Vue 的 <component>
元素和特殊的 is
attribute 实现的:
<!-- currentTab 改变时组件也改变 -->
<component :is="tabs[currentTab]"></component>
在上面的例子中,被传给 :is
的值可以是以下几种:
- 被注册的组件名
- 导入的组件对象
你也可以使用 is
attribute 来创建一般的 HTML 元素。
当使用 <component :is="...">
来在多个组件间作切换时,被切换掉的组件会被卸载。我们可以通过 `` 组件强制被切换掉的组件仍然保持“存活”的状态。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!