Vue是一款用于构建用户界面的 JavaScript 框架, 相较于几十年前以HTML+CSS+JS的开发方式, Vue提供了一系列的新语法, 使得我们可以声明式地描述最终输出的 HTML 和 JavaScript 状态之间的关系, 并且Vue框架会自动跟踪 JavaScript 状态并在其发生变化时响应式地更新 DOM.
为了实现上述效果, Vue框架做了大量的底层工作. 但幸运的是, 掌握Vue的基本使用并不需要理解底层的实现原理. 除了必要的时候, 本文将不涉及Vue的实现原理, 仅聚焦于Vue的使用.
大概2020年就学过了Vue的基本知识, 当时就计划写一个学习笔记, 但由于各种原因, 迟迟没有开始写. 过了几年以后, Vue发生了许多变化, 这下正好可以直接切换到Vue3了. 以前学的内容也可以抛弃掉了. 本文将基于Vue3的语法, 介绍Vue的基本内容.
创建项目
目前的前端框架基本上都依赖NodeJs, 因此在创建Vue项目前需要安装NodeJs环境. 对于大部分系统, 在官网上下载最新版安装包即可. 准备好安装环境后, 执行如下指令创建一个Vue项目
1 | npm create vue@latest |
执行该命令会在命令行中要求我们回答一些选项, 按需选择即可.
基础概念
一个Vue文件代表一个页面上的组件, Vue将HTML代码, JS代码和CSS代码聚集在一个文件之中. 例如
1 | <script setup> |
其中<script>
标签对应于这个组件的JS代码(或者说是TS代码), <template>
对应HTML代码, </style>
对应CSS代码.
模板语法
语法格式 | 示例 |
---|---|
基础文本插值 | <span>Message: {{ msg }}</span> |
绑定属性(普通) | <div :id="dynamicId"></div> |
绑定属性(布尔) | <button :disabled="isButtonDisabled">Button</button> |
绑定表达式 | <div :id="\ list-${id}`“>` |
调用函数 | <time :title="toTitleDate(date)" |
动态绑定多个属性
可以通过设置一个对象, 来一次性的绑定多个属性
1 | const objectOfAttrs = { |
1 | <div v-bind="objectOfAttrs"></div> |
响应式基础
在Vue框架中, 仅当一个变量声明为响应式变量时, 框架才会自动追踪其变化情况. Vue提供了两种声明方式, 分别是ref()
和reactive()
, 以下分别介绍这两种方式
使用ref()
ref用于基本类型, 包括JS内置的所有基本类型, 对象, 数组和Map. 例如以下语句将username变量声明为一个响应式变量.
1 | let username = ref("") |
ref函数返回一个带有value
属性的对象, 该对象就代表了此响应式对象的实际值. 在JS代码中, 使用username.value
的方式访问这个值. 在HTML模板中, 直接使用username
访问对象的值.
对于Vue3的这种割裂的使用方式表示非常难受. 因为模板是需要Vue框架编译的, 因此可以理解其简化了书写. 但既然模板都简化了, 为什么不把JS也简化一下呢.
使用reactive()
reactive作用于对象, 将对象本身变为一个响应式变量.
reactive()的局限性
- 只能用于对象类型(对象, 数组和集合类型)
- 不能直接替换整个对象
- 不能解构对象, 解构的变量会失去响应性
其中第二点尤为重要, 例如前端收到后端返回的数据后, 如果直接进行替换, 就会导致响应丢失, 产生不符合预期的表现.
计算属性
计算属性相当于一个带有缓存的函数. 使用computed
函数创建一个计算属性, 例如
1 | // 一个计算属性 ref |
之后可以当做一个普通的变量来使用. 并且当其引用的响应式变量发生变化时, 该变量会自动重新计算值, 并触发相应的页面变换.
条件渲染
条件渲染涉及两个指令v-if
和v-show
, 其中v-if
的用法和各类语言的if-else
语句类似, 例如
1 | <div v-if="type === 'A'"> |
v-show
语句相对更简单, 不支持与else的连用, 例如
1 | <h1 v-show="ok">Hello!</h1> |
v-if
和v-show
的区别在于, v-if
会真实的按照条件渲染, 而v-show
始终会渲染对应的元素, 仅决定该元素是否显示.
列表渲染
列表渲染的格式与JS的ForEach格式类似, 常用的写法有如下两种
1 | <li v-for="item in items"> |
v-for
既可以遍历数组, 也可以遍历一个对象, 例如
1 | <ul> |
Vue框架默认使用就地更新的方式刷新数组, 当数组中的元素的顺序发生变化时, 这种特性可能导致不正确的效果表现. 此时应该给每个元素指定一个key, 以便于Vue框架根据key追踪元素的顺序变换
1 | <div v-for="item in items" :key="item.id"> |
事件处理
使用@
来监听事件. @
既可以监听原生的事件, 也可以监听组件自定义的事件. 例如
1 | <button @click="count++">Add 1</button> |
上述代码既可以直接绑定一个JS表达式, 也可以绑定一个函数, 或者一个箭头函数表达式.
Vue提供了一些按键修饰符, 从而可以快速的绑定某些按键事件, 例如
1 | <!-- 仅在 `key` 为 `Enter` 时调用 `submit` --> |
高级特性
以下是一些高级特性, 可查阅如下文档进行了解
表单输入绑定
Vue使用v-model
指令提供表单元素与变量的双向绑定, 例如
1 | <input v-model="text"> |
则在页面上修改input的内容时, text变量的值会同步变化. 使用JS修改text变量的值时, input的内容也会同步变化.
表单组件的各类表现可直接查看官方的交互式示例
生命周期
Vue框架给组件的生命周期定义了多个阶段, 其中最常用的是onMounted
钩子, 其相当于各类语言中的init阶段, 可以做一些初始化工作.
1 | onMounted(() => { |
通常并不需要关注Vue的生命周期, 仅使用onMounted做初始化工作即可
侦听器
可以使用watch
函数在每次响应式状态发生变化时触发回调函数, 可以监听的对象包括响应式对象或者一个函数.
1 | // 单个 ref |
注意: props不属于响应式变量, 应该使用getter函数的方式进行监听
组件props
使用defineProps
宏来声明组件需要的props, 例如
1 | const props = defineProps<{ |
使用上述方式声明props可以附带变量的类型, 从而为后续使用相关变量提供语法检查和代码补全.
绑定多个值
如果想将一个对象的所有属性都当作 props 传入, 可以使用不指定参数名的绑定方式, 即
1 | const post = { |
1 | <BlogPost v-bind="post" /> |
单向数据流
当父元素修改props的值时, 子元素会自动的感知到props的变化, 并进行相应的更新. 这种变更机制是单向的, 即仅父元素可变更子元素, 而子元素不应该反向影响父元素. 通常, 如果子元素希望父元素发生改变, 应该抛出一个事件.
因此props可以直接声明为const变量. 这可以防止在子元素中修改props.
扩展特性
以下是一些高级特性, 可查阅如下文档进行了解
组件事件
在组件的模板表达式中, 直接使用$emit
触发事件, 在父组件中, 使用@
绑定事件处理逻辑, 例如
1 | <!-- MyComponent --> |
1 | <button @click="$emit('increaseBy', 1)"> |
在JS代码中, 需要通过defineEmits
宏, 声明涉及的事件, 例如
1 | <script setup> |
扩展特性
以下是一些高级特性, 可查阅如下文档进行了解
Vue路由
Vue Router
是Vue官方的路由插件. 通过该插件可以便捷的实现单页面应用. 单页面应用与传统的前端页面相比, 其主要区别在于页面交互时不发生跳转, 直接在当前页面上进行元素的重新渲染.
创建Vue项目时, 可选择是否包含Vue Router
, 选择包含时, 会自动添加相关的依赖. 仅需两步即可引入, 首先定义路由规则, 例如
1 | // 1. 定义路由组件. |
动态路由
如果路径中包含一些参数, 则可以使用动态路由特性, 该特性可将路径中的一部分内容匹配到变量之中, 例如对于如下的配置
1 | const routes = [ |
则无论是访问/users/233
还是/users/114514
都会匹配此规则, 并且在组件中, 还可以通过如下的方式获得具体的ID值
1 | const $router = useRouter(); |
Axios网络请求库
基础使用
在Vue框架中, 通常使用axios库发送请求. 通常使用如下的方式发送HTTP请求
1 | import axios from 'axios' |
通常情况下, 对于POST请求, 仅需要指定路径和参数接口.
注意, 对于TS代码, 在函数后通过泛型参数指定返回值类型, 可使得返回对象(即res)具有正确的数据结构, 从而获得代码补全和语法检查
全局拦截器
axios可配置全局拦截器, 使得在发送每个请求前和收到每个响应后, 统一执行一段代码, 例如
1 | // 设置统一的URL前瞻, 实际URL等于前缀+函数指定的路径, 例如 /api/item/back |
Vue其他相关知识
Vue引用静态资源
在Vue中, 静态资源也视为一个模块, 因此可以也可以导入, 例如
1 | import imgUrl from '../assets/test.png'; |
之后将该变量赋值给Vue的变量, 即可将其视为一种资源进行引用
Vue问题解决方案
最后更新: 2024年10月19日 22:36
版权声明:本文为原创文章,转载请注明出处
原始链接: https://lizec.top/2022/04/07/Web%E5%BC%80%E5%8F%91%E7%AC%94%E8%AE%B0%E4%B9%8BVue%E6%A1%86%E6%9E%B6/