Vue 基础知识
声明式渲染
Vue 的核心功能是声明式渲染:通过扩展于标准 HTML 的模板语法,我们可以根据 JavaScript 的状态来描述 HTML 应该是什么样子的。当状态改变时,HTML 会自动更新。
单文件组件(Single-File Component)
Vue 的单文件组件相当于把 HTML、CSS、JavaScript 封装在同一个 .vue 后缀的文件中,方便进行复用。
响应式
能在改变时触发更新的状态被称作是响应式的。
Vue 提供了 ref() 和 reactive() 函数来声明响应式状态。
这两个函数会创建一个 JS Proxy 对象,比如 const cnt = ref(0) 得到 cnt = {value: 0} 这样一个 JS 对象,Vue 能够追踪 cnt.value 属性的变化,来更新 HTML 页面。
两者的区别,ref() 是追踪值的变化,而 reactive() 则是追踪对象的变化。
属性绑定
指令是由
v-开头的一种特殊属性。
给属性绑定一个动态的值,使用 v-bind 指令,可以简写为 : 。
例如
<div v-bind:id="dynamicId"></div>可以写成
<div :id="dynamicId"></div>事件监听
Vue 使用 v-on 指令监听 DOM 事件,可以简写为 @。
例如
<button v-on:click="increment">{{ count }}</button>可以写成
<button @click="increment">{{ count }}</button>表单绑定
Vue 使用 v-bind 和 v-on 来在表单的输入元素上创建双向绑定。
<input :value="text" @input="onInput" />Vue 使用 v-model 作为语法糖,可以简化为
<input v-model="text" />将被绑定的值与 <input> 的值自动同步。
条件渲染
v-if 指令可以进行条件渲染。
<h1 v-if="awesome">Vue is awesome!</h1>其中 awesome 是一个变量,当它为真的时候这个 h1 HTML标签才会被渲染。
当然有 v-else-if 和 v-else 也作为条件渲染指令。
<h1 v-if="awesome">Vue is awesome!</h1>
<h1 v-else>Oh no 😢</h1>列表渲染
Vue 使用 v-for 指令来渲染一个基于数组的列表。
const todos = ref([ { id: id++, text: 'Learn JavaScript' }, { id: id++, text:
'Learn HTML' }, { id: id++, text: 'Learn Vue' } ])
<ul>
<li v-for="todo in todos" :key="todo.id">
{{ todo.text }}
</li>
</ul>如果想要更新列表,可以
- 在源数组上调用变更方法
todos.value.push(newTodo);- 使用新数组代替原数组
todos.value = todos.value.filter(/* ... */);计算属性
computed 是一个自动更新的函数。输入是依赖的响应式数据,输出是一个新的响应式值。可以用来作为“派生数据”。
import { ref, computed } from "vue";
const price = ref(100);
const count = ref(2);
const total = computed(() => price.value * count.value);生命周期和模板引用
为了手动操作 DOM,Vue 使用模板引用——指向模板中一个 DOM 元素的 ref。
通过同名的 ref 来访问引用,通过生命周期钩子在 DOM 的不同生命周期进行不同的操作。
<script setup>
import { ref, onMounted } from "vue";
const pElementRef = ref(null);
onMounted(() => {
pElementRef.value.textContent = "mounted!";
});
</script>
<template>
<p ref="pElementRef">Hello</p>
</template>组件的生命周期如图所示。

侦听器
Vue 用 watch() 来侦听数据源,比如 ref。
import { ref, watch } from "vue";
const count = ref(0);
watch(count, (newCount) => {
console.log(`new count is: ${newCount}`);
});组件
父组件可以在模板中渲染另一个组件作为子组件。
<script setup>
import ChildComp from './ChildComp.vue'
</script>
<template>
<ChildComp />
</template>Props
子组件可以通过 props 从父组件接受动态数据。
// ChildComp.vue
<script setup>
const props = defineProps({
msg: String
})
</script><ChildComp :msg="greeting" />Emits
子组件可以向父组件触发事件。
<script setup>
// 声明触发的事件
const emit = defineEmits(["response"]);
// 带参数触发
emit("response", "hello from child");
</script>父组件可以使用 v-on 监听子组件触发的事件。
<ChildComp @response="(msg) => (childMsg = msg)" />插槽
除了通过 props 传递数据外,父组件还可以通过插槽 (slots) 将模板片段传递给子组件。
// ChildComp.vue
<template>
<slot>Fallback content</slot>
</template><script setup>
import { ref } from "vue";
import ChildComp from "./ChildComp.vue";
const msg = ref("from parent");
</script>
<template>
<ChildComp>Message: {{ msg }}</ChildComp>
</template>