当前位置:   article > 正文

Vue3 官方文档速通_vue3.0官方文档

vue3.0官方文档

前言:参考Vue 官方文档,本文档主要学习组合式 API。

一 开始

1. 简介

1.1 什么是 Vue

一款 JS 框架,并有两个核心功能:声明式渲染、响应性。

 1.2 渐进式框架

根据不同的需求场景,使用不同方式的 Vue,比如:

        无需构建步骤,直接引入 vuejs。

        在任何页面中作为 Web Components 嵌入

        使用构建步骤,单页应用 (SPA)

        全栈 / 服务端渲染 (SSR)

        Jamstack / 静态站点生成 (SSG)

        开发桌面端、移动端、WebGL,甚至是命令行终端中的界面

Vue 为什么可以称为“渐进式框架”:它是一个可以与你共同成长、适应你不同需求的框架。

 1.3 单文件组件

单文件组件是 Vue 的标志性功能。*.vue、SFC 就是单文件组件:将一个组件的逻辑 (JS),模板 (HTML) 和样式 (CSS) 封装在同一个文件里。

 1.4 API 风格

选项式 API(Options API):包含多个选项的对象来描述组件的逻辑,例如 data、methods 和 mounted。

组合式 API(Composition API):使用导入的 API 函数来描述组件逻辑。通常会与 <script setup> 搭配使用。

综上:两种 API 是同一个底层系统构建的。选项式 API 是在组合式 API 的基础上实现的!

 2. 快速上手

2.1 创建一个 Vue 应用

  1. // 安装并执行 create-vue,它是 Vue 官方的项目脚手架工具。
  2. npm create vue@latest

2.2 通过 CDN 使用 Vue

可以用于增强静态的 HTML 或与后端框架集成。但将无法使用单文件组件 (SFC) 语法:

  1. <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
  2. <div id="app">{{ message }}</div>
  3. <script>
  4. const { createApp, ref } = Vue;
  5. createApp({
  6. setup() {
  7. const message = ref("Hello vue!");
  8. return {
  9. message,
  10. };
  11. },
  12. }).mount("#app");
  13. </script>

 通过 CDN 以及原生 ES 模块使用 Vue:

  1. <div id="app">{{ message }}</div>
  2. <script type="module">
  3. import {
  4. createApp,
  5. ref,
  6. } from "https://unpkg.com/vue@3/dist/vue.esm-browser.js";
  7. createApp({
  8. setup() {
  9. const message = ref("Hello Vue!");
  10. return {
  11. message,
  12. };
  13. },
  14. }).mount("#app");
  15. </script>

使用导入映射表 (Import Maps) 来告诉浏览器如何定位到导入的 vue:

  1. <script type="importmap">
  2. {
  3. "imports": {
  4. "vue": "https://unpkg.com/vue@3/dist/vue.esm-browser.js"
  5. }
  6. }
  7. </script>
  8. <div id="app">{{ message }}</div>
  9. <script type="module">
  10. import { createApp, ref } from "vue";
  11. createApp({
  12. setup() {
  13. const message = ref("Hello Vue!");
  14. return {
  15. message,
  16. };
  17. },
  18. }).mount("#app");
  19. </script>

分割代码成单独的 JS 文件,以便管理。

  1. <!-- index.html -->
  2. <div id="app"></div>
  3. <script type="module">
  4. import { createApp } from "vue";
  5. import MyComponent from "./my-component.js";
  6. createApp(MyComponent).mount("#app");
  7. </script>
  1. // my-component.js
  2. import { ref } from "vue";
  3. export default {
  4. setup() {
  5. const count = ref(0);
  6. return { count };
  7. },
  8. template: `<div>count is {{ count }}</div>`,
  9. };

注意:直接点击 index.html,会抛错误,因为 ES 模块不能通过 file:// 协议工作。只能通过 http:// 协议工作。需要启动一个本地的 HTTP 服务器,通过命令行在 HTML 文件所在文件夹下运行 npx serve。

 二 基础

1. 创建一个 Vue 应用

1.1 应用实例

通过 createApp 函数创建 Vue 应用实例:

  1. import { createApp } from "vue";
  2. const app = createApp({
  3. /* 根组件选项 */
  4. });

1.2 根组件

createApp 需要传入一个根组件,其他组件将作为其子组件:

  1. import { createApp } from "vue";
  2. // 从一个单文件组件中导入根组件
  3. import App from "./App.vue";
  4. const app = createApp(App);

1.3 挂载应用

调用 .mount() 方法,传入一个 DOM 元素或是 CSS 选择器。它的返回值是根组件实例而非应用实例:

<div id="app"></div>
  1. import { createApp } from "vue";
  2. // 从一个单文件组件中导入根组件
  3. import App from "./App.vue";
  4. const app = createApp(App);
  5. app.mount("#app");

1.4 应用配置

注意:确保在挂载应用实例之前完成所有应用配置!

  1. import { createApp } from "vue";
  2. // 从一个单文件组件中导入根组件
  3. import App from "./App.vue";
  4. const app = createApp(App);
  5. // 应用实例的 .config 对象可以进行一些配置,例如配置错误处理器:用来捕获所有子组件上的错误:
  6. app.config.errorHandler = (err) => {
  7. /* 处理错误 */
  8. };
  9. // 全局挂载组件
  10. app.component("TodoDeleteButton", TodoDeleteButton);
  11. // 全局属性的对象。
  12. app.config.globalProperties.msg = "hello";
  13. app.mount("#app");

1.5 多个应用实例

每个应用都拥有自己的用于配置和全局资源的作用域:

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

2. 模板语法

2.1 文本插值

最基本的数据绑定是文本插值,使用“Mustache”语法 (即双大括号):

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

2.2 原始 HTML

双大括号会将数据解释为纯文本,若想插入 HTML,需要使用 v-html 指令。

安全警告:动态渲染 HTML 是很危险的,容易造成 XSS 漏洞。仅在内容安全可信时再使用 v-html,并且永远不要使用用户提供的 HTML 内容。

  1. <p>Using text interpolation: {{ rawHtml }}</p>
  2. <p>Using v-html directive: <span v-html="rawHtml"></span></p>

2.3 Attribute 绑定

绑定 attribute,使用 v-bind 指令:

  1. <div v-bind:id="dynamicId"></div>
  2. <!-- 简写 -->
  3. <div :id="dynamicId"></div>

绑定多个值,通过不带参数的 v-bind。

  1. const objectOfAttrs = {
  2. id: "container",
  3. class: "wrapper",
  4. };
<div v-bind="objectOfAttrs"></div>

2.4 使用 JS 表达式

数据绑定都支持完整的 JS 表达式,也就是一段能够被求值的 JS 代码。一个简单的判断方法是是否可以合法地写在 return 后面:

  1. {{ number + 1 }}
  2. {{ ok ? 'YES' : 'NO' }}
  3. {{ message.split('').reverse().join('') }}
  4. <div :id="`list-${id}`"></div>

可以在绑定的表达式中使用一个组件暴露的方法:

  1. <time :title="toTitleDate(date)" :datetime="date">
  2. {{ formatDate(date) }}
  3. </time>

2.5 指令 Directives

指 v- 前缀的特殊 attribute。它的值为 JS 表达式(v-for、v-on、v-slot 除外),指令值变化时响应式的更新 DOM,比如 v-if:

<p v-if="seen">Now you see me</p>

带参数的指令,用':'隔开:

  1. <a v-bind:href="url"> ... </a>
  2. <!-- 简写 -->
  3. <a :href="url"> ... </a>

指令的参数,也可以动态绑定,用 '[ ]' 包裹:

  1. <a v-bind:[attributeName]="url"> ... </a>
  2. <!-- 简写 -->
  3. <a :[attributeName]="url"> ... </a>

带修饰符的指令,用 '.' 隔开:

  1. <!-- 触发的事件调用 event.preventDefault() -->
  2. <form @submit.prevent="onSubmit">...</form>

3. 响应式基础

3.1 声明响应式状态

官方推荐使用 ref() 函数来声明响应式状态:

  1. import { ref } from "vue";
  2. const count = ref(0);

ref() 接收参数,并返回一个带有 .value 属性的 ref 对象:

  1. const count = ref(0);
  2. console.log(count); // { value: 0 }
  3. console.log(count.value); // 0
  4. count.value++;
  5. console.log(count.value); // 1

在模板中使用 ref 变量,不需要添加 .value。ref 会自动解包。也可以直接在事件监听器中改变一个 ref:

<button @click="count++">{{ count }}</button>

通过单文件组件(SFC),使用 <script setup> 来大幅度地简化代码:

  1. <script setup>
  2. import { ref } from "vue";
  3. const count = ref(0);
  4. function increment() {
  5. count.value++;
  6. }
  7. </script>
  8. <template>
  9. <button @click="increment">
  10. {{ count }}
  11. </button>
  12. </template>

为什么使用 ref,而不是普通的变量。这是因为 Vue 需要通过.value 属性来实现状态响应性。基础原理是在 getter 中追踪,在 setter 中触发:

  1. // 伪代码,不是真正的实现
  2. const myRef = {
  3. _value: 0,
  4. get value() {
  5. track();
  6. return this._value;
  7. },
  8. set value(newValue) {
  9. this._value = newValue;
  10. trigger();
  11. },
  12. };

要等待 DOM 更新完成后再执行额外的代码,可以使用 nextTick() 全局 API:

  1. import { nextTick } from "vue";
  2. async function increment() {
  3. count.value++;
  4. await nextTick();
  5. // 现在 DOM 已经更新了
  6. }

3.2 reactive()

reactive(),参数只能是对象类型,返回的是一个原始对象的 Proxy,它和原始对象是不相等的:

  1. const raw = {};
  2. const proxy = reactive(raw);
  3. // 代理对象和原始对象不是全等的
  4. console.log(proxy === raw); // false

reactive() 局限性包括:只能用于对象类型(对象,数组,Map,Set)、不能替换整个对象、对结构操作不友好:

  1. let state = reactive({ count: 0 });
  2. // 上面的 ({ count: 0 }) 引用将不再被追踪
  3. // (响应性连接已丢失!)
  4. state = reactive({ count: 1 });
  5. // 对解构不友好
  6. const state = reactive({ count: 0 });
  7. // 当解构时,count 已经与 state.count 断开连接
  8. let { count } = state;
  9. // 不会影响原始的 state
  10. count++;
  11. // 该函数接收到的是一个普通的数字
  12. // 并且无法追踪 state.count 的变化
  13. // 我们必须传入整个对象以保持响应性
  14. callSomeFunction(state.count);

reactive() API 有一些局限性,官方建议使用 ref() 作为声明响应式状态的主要 API。博主个人还是喜欢 ref,reactive 混着用,注意那些局限性就可以了。

 3.3 额外的 ref 解包细节

一个 ref 会在作为响应式对象的属性被访问或修改时自动解包:

  1. const count = ref(0);
  2. const state = reactive({
  3. count,
  4. });
  5. console.log(state.count); // 0
  6. state.count = 1;
  7. console.log(count.value); // 1

 4. 计算属性

4.1 基础示例

computed() 方法期望接收一个 getter 函数,返回为一个计算属性 ref:

  1. <script setup>
  2. import { reactive, computed } from "vue";
  3. const author = reactive({
  4. name: "John Doe",
  5. books: [
  6. "Vue 2 - Advanced Guide",
  7. "Vue 3 - Basic Guide",
  8. "Vue 4 - The Mystery",
  9. ],
  10. });
  11. // 一个计算属性 ref
  12. const publishedBooksMessage = computed(() => {
  13. return author.books.length > 0 ? "Yes" : "No";
  14. });
  15. </script>
  16. <template>
  17. <p>Has published books:</p>
  18. <span>{{ publishedBooksMessage }}</span>
  19. </template>

4.2 计算属性缓存 vs 方法

计算属性值会基于其响应式依赖被缓存。方法调用则总会在重新渲染时再次执行。

 4.3 可写计算属性

计算属性默认是只读的。但可以通过设置 get 和 set 函数变成可读可写:

  1. <script setup>
  2. import { ref, computed } from "vue";
  3. const firstName = ref("John");
  4. const lastName = ref("Doe");
  5. const fullName = computed({
  6. // getter
  7. get() {
  8. return firstName.value + " " + lastName.value;
  9. },
  10. // setter
  11. set(newValue) {
  12. // 注意:我们这里使用的是解构赋值语法
  13. [firstName.value, lastName.value] = newValue.split(" ");
  14. },
  15. });
  16. </script>

4.4 最佳实践

使用计算属性,不要在里面做异步请求和修改 DOM。并且尽量保持只读。

5. 类与样式绑定

5.1 绑定 HTML class

通过对象来动态切换 class:

<div :class="{ active: isActive }"></div>

可以直接绑定一个对象:

  1. const classObject = reactive({
  2. active: true,
  3. "text-danger": false,
  4. });
<div :class="classObject"></div>

通过数组渲染多个 class:

  1. const activeClass = ref("active");
  2. const errorClass = ref("text-danger");
<div :class="[activeClass, errorClass]"></div>

数组中也可以使用 JS 表达式:

  1. <div :class="[isActive ? activeClass : '', errorClass]"></div>
  2. <!-- 等于 -->
  3. <div :class="[{ activeClass: isActive }, errorClass]"></div>

如果组件有多个根元素,透传的 class 需要通过组件的 $attrs 属性来实现指定:

<MyComponent class="baz" />
  1. <!-- MyComponent 模板使用 $attrs 时 -->
  2. <p :class="$attrs.class">Hi!</p>
  3. <span>This is a child component</span>
  1. <p class="baz">Hi!</p>
  2. <span>This is a child component</span>

5.2 绑定内联样式

值为对象,对应的是 style 属性:

  1. const activeColor = ref("red");
  2. const fontSize = ref(30);
<div :style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>

直接绑定一个样式对象使模板更加简洁:

  1. const styleObject = reactive({
  2. color: "red",
  3. fontSize: "13px",
  4. });
<div :style="styleObject"></div>

还可以绑定一个包含多个样式对象的数组:

<div :style="[baseStyles, overridingStyles]"></div>

6. 条件渲染

6.1 v-if、v-else、v-else-if

v-if 指令用于条件性地渲染内容。当值为真时才被渲染:

<h1 v-if="awesome">Vue is awesome!</h1>

v-else 为 v-if 添加一个“else 区块”。并且必须跟在一个 v-if 或者 v-else-if 元素后面:

  1. <button @click="awesome = !awesome">Toggle</button>
  2. <h1 v-if="awesome">Vue is awesome!</h1>
  3. <h1 v-else>Oh no 本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
    推荐阅读