Vue 全家桶 - 基础命令
约 3160 字大约 11 分钟
2026-05-25
一直想做一些自己的产品,记录下对前端知识的学习
Vue 是用于构建用户界面的 JavaScript 框架。
它基于标准 HTML、CSS 和 JavaScript 构建,并提供了一套声明式的、组件化的编程模型,帮助你高效地开发用户界面。
Vue
创建Vue项目
在创建 Vue 项目以前,我们需要先安装 Node.js。
基于 Vite 创建
Vue 官网推荐使用 Vite 创建项目
## 1.创建命令
npm create vue@latest
## 2.具体配置
## 配置项目名称
√ Project name: vue3_test
## 是否添加TypeScript支持
√ Add TypeScript? Yes
## 是否添加JSX支持
√ Add JSX Support? No
## 是否添加路由环境
√ Add Vue Router for Single Page Application development? No
## 是否添加pinia环境
√ Add Pinia for state management? No
## 是否添加单元测试
√ Add Vitest for Unit Testing? No
## 是否添加端到端测试方案
√ Add an End-to-End Testing Solution? » No
## 是否添加ESLint语法检查
√ Add ESLint for code quality? Yes
## 是否添加Prettiert代码格式化
√ Add Prettier for code formatting? No启动项目
cd <your-project-name>
npm install
npm run dev构建项目(当你准备将应用发布到生产环境时,运行)
npm run build基于 CLI 创建
备注:目前
vue-cli已处于维护模式,官方推荐基于Vite创建项目。
## 查看@vue/cli版本,确保@vue/cli版本在4.5.0以上
vue --version
## 安装或者升级你的@vue/cli
npm install -g @vue/cli
## 执行创建命令
vue create vue_test
## 随后选择3.x
## Choose a version of Vue.js that you want to start the project with (Use arrow keys)
## > 3.x
## 2.x
## 启动
cd vue_test
npm run serveAPI
Vue 的组件可以按两种不同的风格书写:选项式 API 和 组合式 API。
选项式 API (Options API)
使用选项式 API,我们可以用包含多个选项的对象来描述组件的逻辑,例如 data、methods 和 mounted。选项所定义的属性都会暴露在函数内部的 this 上,它会指向当前的组件实例。
<script>
export default {
// data() 返回的属性将会成为响应式的状态
// 并且暴露在 `this` 上
data() {
return {
count: 0
}
},
// methods 是一些用来更改状态与触发更新的函数
// 它们可以在模板中作为事件处理器绑定
methods: {
increment() {
this.count++
}
},
// 生命周期钩子会在组件生命周期的各个不同阶段被调用
// 例如这个函数就会在组件挂载完成后被调用
mounted() {
console.log(`The initial count is ${this.count}.`)
}
}
</script>
<template>
<button @click="increment">Count is: {{ count }}</button>
</template>组合式 API (Composition API)
通过组合式 API,我们可以使用导入的 API 函数来描述组件逻辑。在单文件组件中,组合式 API 通常会与 <script setup> 搭配使用。这个 setup attribute 是一个标识,告诉 Vue 需要在编译时进行一些处理,让我们可以更简洁地使用组合式 API。比如,<script setup> 中的导入和顶层变量/函数都能够在模板中直接使用。
下面是使用了组合式 API 与 <script setup> 改造后和上面的模板完全一样的组件:
<script setup>
import { ref, onMounted } from 'vue'
// 响应式状态
const count = ref(0)
// 用来修改状态、触发更新的函数
function increment() {
count.value++
}
// 生命周期钩子
onMounted(() => {
console.log(`The initial count is ${count.value}.`)
})
</script>
<template>
<button @click="increment">Count is: {{ count }}</button>
</template>响应式基础
ref 创建:基本类型的响应式数据
- 作用:定义响应式变量。
- 语法:
let xxx = ref(初始值)。 - 返回值:一个
RefImpl的实例对象,简称ref对象或ref,ref对象的value属性是响应式的。 - 注意点:
JS中操作数据需要:xxx.value,但模板中不需要.value,直接使用即可。- 对于
let name = ref('张三')来说, ame不是响应式的, ame.value是响应式的。
<template>
<div class="person">
<h2>姓名:{{name}}</h2>
<h2>年龄:{{age}}</h2>
<button @click="changeName">修改名字</button>
<button @click="changeAge">年龄+1</button>
<button @click="showTel">点我查看联系方式</button>
</div>
</template>
<script setup lang="ts" name="Person">
import {ref} from 'vue'
// name和age是一个RefImpl的实例对象,简称ref对象,它们的value属性是响应式的。
let name = ref('张三')
let age = ref(18)
// tel就是一个普通的字符串,不是响应式的
let tel = '13888888888'
function changeName(){
// JS中操作ref对象时候需要.value
name.value = '李四'
console.log(name.value)
// 注意:name不是响应式的,name.value是响应式的,所以如下代码并不会引起页面的更新。
// name = ref('zhang-san')
}
function changeAge(){
// JS中操作ref对象时候需要.value
age.value += 1
console.log(age.value)
}
function showTel(){
alert(tel)
}
</script>reactive 创建:对象类型的响应式数据
- 作用:定义一个响应式对象(基本类型不要用它,要用
ref,否则报错) - 语法:
let 响应式对象= reactive(源对象)。 - 返回值:一个
Proxy的实例对象,简称:响应式对象。 - 注意点:
reactive定义的响应式数据是“深层次”的。
<template>
<div class="person">
<h2>汽车信息:一台{{ car.brand }}汽车,价值{{ car.price }}万</h2>
<h2>游戏列表:</h2>
<ul>
<li v-for="g in games" :key="g.id">{{ g.name }}</li>
</ul>
<h2>测试:{{obj.a.b.c.d}}</h2>
<button @click="changeCarPrice">修改汽车价格</button>
<button @click="changeFirstGame">修改第一游戏</button>
<button @click="test">测试</button>
</div>
</template>
<script lang="ts" setup name="Person">
import { reactive } from 'vue'
// 数据
let car = reactive({ brand: '奔驰', price: 100 })
let games = reactive([
{ id: 'ahsgdyfa01', name: '英雄联盟' },
{ id: 'ahsgdyfa02', name: '王者荣耀' },
{ id: 'ahsgdyfa03', name: '原神' }
])
let obj = reactive({
a:{
b:{
c:{
d:666
}
}
}
})
function changeCarPrice() {
car.price += 10
}
function changeFirstGame() {
games[0].name = '流星蝴蝶剑'
}
function test(){
obj.a.b.c.d = 999
}
</script>ref 创建:对象类型的响应式数据
- 其实
ref接收的数据可以是:基本类型、对象类型。 - 若
ref接收的是对象类型,内部其实也是调用了reactive函数。
<template>
<div class="person">
<h2>汽车信息:一台{{ car.brand }}汽车,价值{{ car.price }}万</h2>
<h2>游戏列表:</h2>
<ul>
<li v-for="g in games" :key="g.id">{{ g.name }}</li>
</ul>
<h2>测试:{{obj.a.b.c.d}}</h2>
<button @click="changeCarPrice">修改汽车价格</button>
<button @click="changeFirstGame">修改第一游戏</button>
<button @click="test">测试</button>
</div>
</template>
<script lang="ts" setup name="Person">
import { ref } from 'vue'
// 数据
let car = ref({ brand: '奔驰', price: 100 })
let games = ref([
{ id: 'ahsgdyfa01', name: '英雄联盟' },
{ id: 'ahsgdyfa02', name: '王者荣耀' },
{ id: 'ahsgdyfa03', name: '原神' }
])
let obj = ref({
a:{
b:{
c:{
d:666
}
}
}
})
console.log(car)
function changeCarPrice() {
car.value.price += 10
}
function changeFirstGame() {
games.value[0].name = '流星蝴蝶剑'
}
function test(){
obj.value.a.b.c.d = 999
}
</script>ref 对比 reactive
宏观角度看:
ref用来定义:基本类型数据、对象类型数据;
reactive用来定义:对象类型数据。
- 区别:
ref创建的变量必须使用.value(可以使用volar插件自动添加.value)。
reactive重新分配一个新对象,会失去响应式(可以使用Object.assign去整体替换)。
- 使用原则:
- 若需要一个基本类型的响应式数据,必须使用
ref。- 若需要一个响应式对象,层级不深,
ref、reactive都可以。- 若需要一个响应式对象,且层级较深,推荐使用
reactive。
toRefs 与 toRef
- 作用:将一个响应式对象中的每一个属性,转换为
ref对象。 - 备注:
toRefs与toRef功能一致,但toRefs可以批量转换。 - 语法如下:
<template>
<div class="person">
<h2>姓名:{{person.name}}</h2>
<h2>年龄:{{person.age}}</h2>
<h2>性别:{{person.gender}}</h2>
<button @click="changeName">修改名字</button>
<button @click="changeAge">修改年龄</button>
<button @click="changeGender">修改性别</button>
</div>
</template>
<script lang="ts" setup name="Person">
import {ref,reactive,toRefs,toRef} from 'vue'
// 数据
let person = reactive({name:'张三', age:18, gender:'男'})
// 通过toRefs将person对象中的n个属性批量取出,且依然保持响应式的能力
let {name,gender} = toRefs(person)
// 通过toRef将person对象中的gender属性取出,且依然保持响应式的能力
let age = toRef(person,'age')
// 方法
function changeName(){
name.value += '~'
}
function changeAge(){
age.value += 1
}
function changeGender(){
gender.value = '女'
}
</script>基础指令
在Vue中,指令都是以v-开头的,每个指令都是 JavaScript 表达式
v-text 与 v-html
v-text 用于设置元素的文本内容,v-html 指令用于设置元素的HTML内容
<template>
<p>{{ msg }}</p>
<p v-text="msg"></p>
<p v-html="msg"></p>
</template>
<script setup>
import { ref } from 'vue';
const msg = ref('<a href="http://www.baidu.com"> Welcome </a>');
</script>v-text、v-html 与插值表达式的正确使用与区别
v-text 与 v-html 指令都可以更新页面元素的内容,不同的是,v-text 会将数据以字符串文本的形式更新,而 v-html 则会直接将数据作为 HTML 标签内容更新。
在更新数据时,{{ }} 表达式只会更新原本占位插值所在的数据内容,而 v-text 与 v-html 指令则更新整个标签内容。
v-model
v-model 指令用于实现双向数据绑定,它允许在表单元素(如输入框、选择框等)和数据之间进行双向绑定,从而实现数据的自动更新和显示。
v-model 的修饰符
.lazy 修饰符
在上面示例中默认情况下,v-model 指令在每次 input 事件触发后会将输入框的值与响应式的msg进行同步,添加 .lazy 以后,则转变为失去焦点同步。
<template>
{{ msg }}
<div>
双向绑定:<input v-model="msg" type="text"/>
</div>
<div>
失去焦点后双向绑定:<input v-model.lazy="msg" type="text"/>
</div>
</template>
<script setup>
import { ref } from 'vue';
const msg = ref('');
</script>.number 修饰符
将用户输入的数据自动转换为数值类型
<template>
<input v-model="num1" type="text"/>
<br/>
<input v-model="num2" type="text"/>
<br/>
{{ num1 + num2 }}
<br/>
<input v-model.number="num3" type="text"/>
<br/>
<input v-model.number="num4" type="text"/>
<br/>
{{ num3 + num4 }}
</template>
<script setup>
import { ref } from 'vue';
const num1 = ref('');
const num2 = ref('');
const num3 = ref('');
const num4 = ref('');
</script>以上示例中 .number 修饰符绑定的值会想加,而不是字符串拼接,如果不想要修饰符,可以使用以下方式
{{ parseInt(num1) + parseInt(num2) }}.trim 修饰符
将用户输入的数据自动去除首尾空格
<template>
<p>{{ msg }}</p>
<input type="text" v-model.trim="msg"/> <br/>
</template>
<script setup>
import { ref } from 'vue';
const msg = ref('');
</script>v-cloak
模板语法有一个缺点: 可能会出现闪烁问题,即页面数据可能还没加载渲染完成,就提前出现了两对{}。
实际应用中可能就是Vue实例中的数据。例如,通过发送异步请求获取来自网络(服务器)的数据,由于网络或者数据量大,需要一定的时间,这个时候Vue中的数据(Data)尚没有数据,就不会去渲染视图,那么在视图中会提前看到类似{{ msg }}的情况,这给用户的体验很不好,所以在数据尚未加载渲染完成时不要让类似{{ msg }}出现,那么如何解决呢?可以使用v-cloak 指令来解决。
使用 v-cloak 指令要配合CSS样式一起使用否则不会生效。 通过CSS样式先设置为不显示,在数据流染完成之后就会自动修改displs值为显示。
<template>
<div v-cloak>
{{ message }}
</div>
</template>
<script setup>
import { ref,onMounted } from 'vue';
const message = ref('123');
onMounted(()=>{
alert('挂载完毕')
})
</script>
<style>
[v-cloak] {
display: none;
}
</style>v-bind
v-bind 用来绑定标签上的属性( src、href、title 等等) 或样式(style、class )。
<img v-bind:src="imgUrl" alt="">v-bind 可以简写成 :
<img :src="imgUrl" alt="">修饰符
- camel - 将短横线命名的 attribute 转变为驼峰式命名。
- prop - 强制绑定为 DOM property (3.2+)。
- attr - 强制绑定为 DOM attribute (3.2+)。
示例
<!-- 绑定 attribute -->
<img v-bind:src="imageSrc" />
<!-- 动态 attribute 名 -->
<button v-bind:[key]="value"></button>
<!-- 缩写 -->
<img :src="imageSrc" />
<!-- 缩写形式的动态 attribute 名 (3.4+),扩展为 :src="src" -->
<img :src />
<!-- 动态 attribute 名的缩写 -->
<button :[key]="value"></button>
<!-- 内联字符串拼接 -->
<img :src="'/path/to/images/' + fileName" />
<!-- class 绑定 -->
<div :class="{ red: isRed }"></div>
<div :class="[classA, classB]"></div>
<div :class="[classA, { classB: isB, classC: isC }]"></div>
<!-- style 绑定 -->
<div :style="{ fontSize: size + 'px' }"></div>
<div :style="[styleObjectA, styleObjectB]"></div>
<!-- 绑定对象形式的 attribute -->
<div v-bind="{ id: someProp, 'other-attr': otherProp }"></div>
<!-- prop 绑定。“prop” 必须在子组件中已声明。 -->
<MyComponent :prop="someThing" />
<!-- 传递子父组件共有的 prop -->
<MyComponent v-bind="$props" />
<!-- XLink -->
<svg><a :xlink:special="foo"></a></svg>v-on
给元素绑定事件监听器。缩写:@
修饰符
- stop - 调用 event.stopPropagation()。
- prevent - 调用 event.preventDefault()。
- capture - 在捕获模式添加事件监听器。
- self - 只有事件从元素本身发出才触发处理函数。
- {keyAlias} - 只在某些按键下触发处理函数。
- once - 最多触发一次处理函数。
- left - 只在鼠标左键事件触发处理函数。
- right - 只在鼠标右键事件触发处理函数。
- middle - 只在鼠标中键事件触发处理函数。
- passive - 通过 { passive: true } 附加一个 DOM 事件。