删库在逃程序员的Blog
置顶

Vue3 快速上手指南

author
·
8
0

Vue3 快速上手指南

2020 年 9 月 18 日发布,代号 One Piece,带来 Composition API、Proxy 响应式等革命性更新。

一、Vue3 简介

1.1 版本信息

1.2 Vue3 带来了什么?

方面 改进
性能提升 打包大小减少 41%,初次渲染快 55%,更新渲染快 133%,内存减少 54%
源码升级 Proxy 替代 defineProperty,重写虚拟 DOM,支持 Tree-Shaking
TypeScript 更好的 TS 支持
新特性 Composition API、新内置组件、新生命周期钩子

二、创建 Vue3 工程

2.1 使用 Vue CLI

# 查看版本(确保 4.5.0+)
vue --version

# 安装/升级
npm install -g @vue/cli

# 创建项目
vue create vue_test

# 启动
cd vue_test
npm run serve

2.2 使用 Vite(推荐)

# 创建项目
npm init vite-app <project-name>

# 进入目录
cd <project-name>

# 安装依赖
npm install

# 运行
npm run dev

Vite 优势

  • 无需打包,快速冷启动
  • 轻量快速的热重载(HMR)
  • 真正的按需编译

三、Composition API 核心

3.1 setup 配置项

作用:所有 Composition API 的"表演舞台"

export default {
  setup() {
    // 数据、方法都配置在这里
    const count = ref(0)
    const increment = () => count.value++

    return { count, increment }
  }
}

注意点

  • 尽量不与 Vue2.x 配置(data、methods)混用
  • setup 中不能访问 Vue2.x 配置
  • 重名时 setup 优先
  • setup 不能是 async 函数

3.2 ref 与 reactive

API 用途 操作
ref() 基本类型数据 JS 中用 .value,模板中不用
reactive() 对象/数组类型 均不需要 .value
import { ref, reactive } from 'vue'

const count = ref(0)
const person = reactive({ name: '张三', age: 18 })

// JS 中操作
count.value++
person.age++

// 模板中直接使用
// {{ count }} {{ person.name }}

3.3 响应式原理对比

Vue2 Vue3
Object.defineProperty() Proxy
只能拦截属性读写 可拦截增删改查
数组需重写方法 原生支持数组
无法检测属性新增/删除 完美支持
// Vue3 Proxy 示例
new Proxy(data, {
  get(target, prop) {
    return Reflect.get(target, prop)
  },
  set(target, prop, value) {
    return Reflect.set(target, prop, value)
  },
  deleteProperty(target, prop) {
    return Reflect.deleteProperty(target, prop)
  }
})

3.4 computed 与 watch

computed

import { computed } from 'vue'

const fullName = computed(() => {
  return person.firstName + '-' + person.lastName
})

// 完整写法(可设置)
const fullName = computed({
  get() { return person.firstName + '-' + person.lastName },
  set(value) { /* 处理设置 */ }
})

watch

// 监视 ref
watch(sum, (newVal, oldVal) => {
  console.log('sum 变化了', newVal, oldVal)
})

// 监视 reactive(无法获取 oldValue)
watch(person, (newVal) => {
  console.log('person 变化了', newVal)
}, { deep: true })  // deep 强制开启

// 监视 reactive 的某个属性
watch(() => person.job, (newVal, oldVal) => {
  console.log('job 变化了', newVal, oldVal)
})

watchEffect(自动收集依赖):

watchEffect(() => {
  console.log(sum.value, person.age)
  // 自动监视 sum 和 person.age
})

3.5 生命周期钩子

Vue2 Vue3(Options) Vue3(Composition)
beforeCreate - setup()
created - setup()
beforeMount beforeMount onBeforeMount
mounted mounted onMounted
beforeUpdate beforeUpdate onBeforeUpdate
updated updated onUpdated
beforeDestroy beforeUnmount onBeforeUnmount
destroyed unmounted onUnmounted
import { onMounted, onUpdated, onUnmounted } from 'vue'

setup() {
  onMounted(() => console.log('mounted'))
  onUpdated(() => console.log('updated'))
  onUnmounted(() => console.log('unmounted'))
}

3.6 provide 与 inject

祖组件提供数据

import { provide, reactive } from 'vue'

setup() {
  const car = reactive({ name: '奔驰', price: '40 万' })
  provide('car', car)
}

后代组件注入数据

import { inject } from 'vue'

setup() {
  const car = inject('car')
  return { car }
}

四、其他重要 API

4.1 浅响应式

API 作用
shallowReactive() 只处理最外层属性响应式
shallowRef() 只处理基本类型响应式

4.2 只读代理

API 作用
readonly() 深只读
shallowReadonly() 浅只读

4.3 toRaw 与 markRaw

import { toRaw, markRaw } from 'vue'

// 响应式对象转普通对象
const raw = toRaw(reactiveObj)

// 标记永不转为响应式
const rawObj = markRaw({ /* ... */ })

4.4 响应式判断

isRef(value)        // 是否为 ref
isReactive(obj)     // 是否为 reactive 代理
isReadonly(obj)     // 是否为只读代理
isProxy(obj)        // 是否为 proxy

五、新组件

5.1 Fragment

Vue3 组件可以没有根标签,减少层级和内存占用。

5.2 Teleport

将组件 HTML 移动到指定位置(如弹窗):

<teleport to="body">
  <div class="modal">
    <h3>弹窗内容</h3>
  </div>
</teleport>

5.3 Suspense

等待异步组件时显示加载状态:

<Suspense>
  <template #default>
    <AsyncComponent />
  </template>
  <template #fallback>
    <h3>加载中...</h3>
  </template>
</Suspense>

六、全局 API 变化

Vue2 Vue3
Vue.component() app.component()
Vue.directive() app.directive()
Vue.mixin() app.mixin()
Vue.use() app.use()
Vue.prototype app.config.globalProperties
Vue.config.productionTip 已移除

七、其他重要变化

  • data 选项:必须声明为函数
  • 过渡类名v-enterv-enter-fromv-leavev-leave-from
  • 移除keyCode 修饰符、v-on.native、过滤器(filter)

参考资源

评论 (0)