更新于 

Vue3

开始

什么是 Vue

Vue 是一款用于构建用户界面的 JavaScript 框架

基于标准 HTML、CSS 和 JavaScript 构建

提供了一套声明式的、组件化的编程模型,帮助你高效地开发用户界面

渐进式框架

Vue被设计成具有灵活性和可逐步集成的特点,以适应不同需求场景。

  • 增强静态的 HTML 而无需构建步骤
  • 在任何页面中作为 Web Components 嵌入
  • 单页应用 (SPA)
  • 全栈 / 服务端渲染 (SSR)
  • Jamstack / 静态站点生成 (SSG)
  • 目标为桌面端、移动端、WebGL,甚至是命令行终端

单文件组件

单文件组件,也被称为 *.vue 文件,英文缩写 SFC

Vue 的单文件组件会将一个组件的逻辑 (JavaScript),模板 (HTML) 和样式 (CSS) 封装在同一个文件里

API 风格

选项式 API

  • 我们可以用包含多个选项的对象来描述组件的逻辑,例如 data、methods 和 mounted
  • 选项所定义的属性都会暴露在函数内部的 this 上
  • this指向当前的组件实例

组合式 API

  • 组合式 API 可以使用导入的 API 函数来描述组件逻辑
  • 在单文件组件中,组合式 API 通常会与 搭配使用
  • setup attribute 标识用于告诉 Vue 需要在编译时进行转换,来减少使用组合式 API 时的样板代码

选谁

  • 出于学习目的使用时,推荐采用自己更容易理解的方式

  • 出于生产目的使用时

    • 如果你不需要使用构建工具,或者只在低复杂度的场景中使用 Vue,可以采用选项式 API
    • 当你想用 Vue 构建更大更完整的应用时,推荐使用组合式 API 和单文件组

采用构建工具

线上构建

本地构建

命令行运行:

这一指令将会安装并执行 create-vue,它是 Vue 官方的项目脚手架工具,然后进入项目目录,分别执行npm installnpm run dev 。当你准备将应用发布到生产环境时,运行npm run build,此命令会在 ./dist 文件夹中为你的应用创建一个生产环境的构建版本

不使用构建工具

在 HTML 文件中引入

1
2
3
4
5
6
7
8
9
10
11
12
13
<script src='https://unpkg.com/vue@3'></script>

<div id='app'>{{ message }}</div>

<script>
Vue.createApp({
data() {
return {
message: 'Hello Vue!';
}
}
}).mount('#app'')
</script>

该版本的所有的API都暴露在了全局变量Vue上。

为保持一致性,可以直接在代码中导入 vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<script type='importmap'>
  {
    'imports': {
      'vue''https://unpkg.com/vue@3/dist/vue.esm-browser.js'
    }
  }
</script>

<div id='app'>{{ message }}</div>

<script type='module'>
  import { createApp } from 'vue'

  createApp({
    data() {
      return {
        message'Hello Vue!'
      }
    }
  }).mount('#app')
</script>
需要注意

importmap是浏览器原生功能,目前只有基于 Chromium 的浏览器支持导入映射表;不支持导入映射表的浏览器,使用 es-module-shims 来进行polyfill;基于导入映射表的配置仅用于学习。

通过 HTTP 提供服务

  • 我们可能需要将代码分割成单独的 JavaScript 文件,以便更容易管理
1
2
3
4
5
6
<script type='module'>
import { createApp } from 'vue'
import MyComponent from './my-component.js'

createApp(MyComponent).mount('#app')
</script>
1
2
3
4
5
6
7
// my-component.js
export default {
data() {
return { count: 0 }
},
template: `<div>count is {{ count }}</div>`
}

为了使其工作,需要通过 http:// 协议为你的 HTML 提供服务

  • 在 HTML 文件所在文件夹下运行 npx serve
  • 也可以使用其他任何可以基于正确的 MIME 类型服务静态文件的 HTTP 服务器

基础

创建Vue应用

应用实例

每个 Vue 应用都是通过 createApp 函数创建一个新的 应用实例

1
const app = createApp({/* 根组件选项 */})

根组件

传入 createApp 的对象实际上是一个“根组件”,其他组件将作为根组件的子组件

如果你使用单文件组件,根组件可从其他文件导入

1
2
import App from './App.vue'
const app = createApp(App)

挂载应用

应用实例必须在调用了 .mount() 方法后才会渲染出来

mount 接收一个“容器”参数

mount在整个应用配置和资源注册完成后被调用

返回值为根组件实例

DOM 中的根组件模板

在未采用构建流程的情况下使用 Vue 时,可以在挂载容器中直接书写根组件模板

1
{{ count }}

当根组件没有设置 template 选项时,Vue 将自动使用容器的 innerHTML 作为模板

应用配置

应用实例会暴露一个 .config 对象允许我们配置一些应用级的选项

例如定义一个应用级的错误处理器


1
2
3
app.config.errorHandler = (err) => {
/* 处理错误 */
}

应用实例还提供了一些方法来注册应用范围内可用的资源

例如注册一个组件

1
app.component('TodoDeleteButton', TodoDeleteButton)

多个应用实例

createApp API 允许多个 Vue 应用共存于同一个页面上,而且每个应用都拥有自己的用于配置和全局资源的作用域

1
2
3
4
5
6
7
8
9
const app1 = createApp({
/* ... */
})
app1.mount('#container-1')

const app2 = createApp({
/* ... */
})
app2.mount('#container-2')

模板语法

简介

Vue 使用一种基于 HTML 的模板语法

底层机制中,Vue 会将模板编译成高度优化的 JavaScript 代码

你也可以结合可选的 JSX 支持直接手写渲染函数而不采用模板,但这将不会享受到和模板同等级别的编译时优化

文本插值

文本插值使用“Mustache”语法 (即双大括号)

1
<span>Message: {{ msg }}</span>

双大括号标签会被替换为相应组件实例中 property 的值,同时具有响应式

原始 HTML

若想在模板中插入 HTML,需要使用 v-html 指令

1
<span v-html="rawHtml"></span>
注意

不能使用 v-html 来拼接组合模板
在网站上动态渲染任意 HTML 是非常危险的行为

Attribute 绑定

双大括号不能在 HTML attributes 中使用,但可以使用 v-bind 指令

  • 将元素的 id attribute 与组件的 dynamicId property 保持一致
  • 如果绑定的值是 null 或者 undefined,那么该 attribute 将会从渲染的元素上移除

以上例子可以缩写为

1
<div v-bind:id="dynamicId"></div>

布尔型 attribute

布尔型 attribute 就那些依据 true/false 值决定是否应该在该元素上存在的 attribute

例如:

1
<button :disabled="isButtonDisabled">Button</button>
注意

当isButtonDisabled为真值或一个空字符串 (即 <button disabled />) 时,元素会包含这个 disabled attribute。而当其为假值时 attribute 将被忽略。

动态绑定多个值

如果你有一个包含多个 attribute 的 JavaScript 对象,通过不带参数的 v-bind,你可以将它们绑定到单个元素上

1
<div v-bind="objectOfAttrs"></div>

使用 JS 表达式

Vue 在所有的数据绑定中都支持完整的 JavaScript 表达式

  • 这些表达式都会被作为 JavaScript ,以组件为作用域解析执行

模板中的应用:

  • 在文本插值中 (双大括号)
  • 在任何 Vue 指令 (以 v- 开头的特殊 attribute) attribute 的值中

注意点:

  • 仅支持表达式,不能是一个语句

  • 受限的全局访问

    • 模板中的表达式将被沙盒化,仅能够访问到有限的全局对象列表
    • 没有显式包含在列表中的全局对象将不能在模板内表达式中访问
    • 当然可以自行在 app.config.globalProperties 上显式地添加他们,供所有的 Vue 表达式使用

指令

简介:

  • 指令是带有 v- 前缀的特殊 attribute
  • 指令 attribute 的期望值为一个 JavaScript 表达式
  • 使用指令是为了在其表达式值变化时响应式地对 DOM 应用更新

参数:

某些指令会需要一个“参数”,使用冒号分隔

1
<a v-bind:href="url">...</a>
注意

这里 href 就是一个参数,它告诉 v-bind 指令将表达式 url 的值绑定到元素的 href attribute 上

动态参数

  • 在指令参数上也可以使用一个 JavaScript 表达式,但需要包含在一对方括号内
1
<a v-bind:[attributeName]="url">...</a>
  • 动态参数值的限制

    • 特殊值 null 意为显式移除该绑定
    • 任何其他非字符串的值都将触发一个警告
  • 动态参数语法的限制

    • 空格和引号,在 HTML attribute 名称中都是不合法的

修饰符

修饰符是以点开头的特殊后缀,表明指令需要以一些特殊的方式被绑定

完整语法

[完整语法]
[完整语法]