Vue3基础看这一篇就够了(万字长篇,附实例代码及效果演示)

目录

前言

概述

Vue3组合式api  VS  Vue2选项式api

基础部分

setup

选项式api的风格

组合式api的风格

区别

 响应式数据

ref

reactive

shallowReactive 与 shallowRef 

 计算属性和监听

 computed 函数

 watch 函数

 watchEffect

生命周期

 响应式数据只读

toRaw 返回代理的源

markRaw 标记对象拒绝代理

provide 与 inject 跨组件传值

判断是否为响应式数据

toRef 和 toRefs 解构响应式数据

 新组件

Fragment

Teleport 

Suspense

组合式函数 

全局的api及指令的变动

结语


前言

vue3已经出了好长一段时间了,最近闲来无事简单学习了一下,新增的东西还是挺多的,写一篇文章来记录一下。

概述

Vue3组合式api  VS  Vue2选项式api

谈到 vue3,首先想到的就是组合式api,很大程度的解决了vue2选项式api的缺点,那有啥缺点?当文件中的业务代码非常多的时候,阅读修改代码的时候是非常痛苦的,data,method,watch还有计算属性之间来回跳转, 我已经准备拔刀了。

下面这些图被疯转,很形象的展现了vue2和vue3的区别,可以看到组合式api就是将单个功能的状态,方法,计算属性等等需要用到的东西都组合在一起抽离成一个hook,也就是对应图4的function,最终再统一引入组合到一起。这样做的好处就是单个功能的代码都在一起,方便调式修改。

 

 

基础部分

setup

setup是vue3的一个新的配置项,只在初始化的时候执行一次,所有的组合式函数都在此使用。setup可以在选项式api的风格中使用也可以通过组合式api的风格 。通过代码简单对比一下。vue3推荐使用组合式。

选项式api的风格

<script>
import { ref } from 'vue'
export default {
  setup() {
    const sum = ref(1)
    return {
      sum,
    }
  },
}
</script>

<template>
  <div>
    <h1>v3</h1>
    <h3>{
  { sum }}</h3>
    <button @click="sum++">+1</button>
  </div>
</template>

<style scoped></style>

组合式api的风格

<script setup>
import { ref } from 'vue'
const sum = ref(1)
</script>

<template>
  <div>
    <h1>v3</h1>
    <h3>{
  { sum }}</h3>
    <button @click="sum++">+1</button>
  </div>
</template>

<style scoped></style>

区别

  1. <script setup>中的导入和顶层变量/函数都能够在模板中直接使用, 选项式则需要导出
  2. <script setup>打包出来的体积更小
  3. <script setup>对ts更友好

官网介绍的比较详细,感兴趣可以查看组合式 API 常见问答 | Vue.js 

 响应式数据

vue2中 data 函数返回的对象就是响应式的数据,但是在增加删除对象属性时不是响应式的,当然vue2中也有对应的解决方法,this.$set(), this.$delete(), 其实这也能够理解,毕竟vue2的响应式式基于 Object.defineProperty 实现的,这个函数只提供了 get 和 set 以及一些描述符 descriptor,并没有提供 add 和 delete 方法。

vue3中的响应式包含了两种形态, ref(底层还是Object.defineProperty进行数据劫持, 处理简单数据类型)reactive(使用es6的Proxy进行数据劫持,处理复杂数据类型),完全修复了vue2响应式的痛点,vue3的响应式更加的友好。

ref

ref 接受一个值,返回一个响应式对象,一般用来处理简单数据类型的响应式,但如果传入的值是对象 ref 会求助 reactive,返回RefImpl的实例简称ref对象。 此时可能会有疑惑,既然ref是一个响应式的对象,为什么模板中能正常解析。这是因为在解析templete时遇到ref对象会自动取其value属性,但是如果要在方法中修改ref创建的响应式数据,你的写法应该是这样的 state.value = xxx

<script setup>
import { ref } from 'vue'
const sum = ref(1)
function add() {
  sum.value++
}
</script>

<template>
  <div>
    <h1>v3</h1>
    <h3>{
  { sum }}</h3>
    <button @click="add">+1</button>
  </div>
</template>

<style scoped></style>

reactive

为对象做深层!!!!响应式代理, 也就是如果对象有多层依旧是响应式的,返回一个Proxy实例, 如果传入一个字符串或者数字,它将不是响应式的。Proxy 对象用于创建一个对象的代理,从而实现基本操作的拦截和自定义(如属性查找、赋值、枚举、函数调用等)Proxy - JavaScript | MDN。Vue使用 Proxy 进行数据劫持, Reflect 进行反射修改 Reflect - JavaScript | MDN

<script setup>
import { reactive } from 'vue'
const person = reactive({
  name: '张三',
  age: 12,
  job: {
    j1: {
      jname: '前端开发',
    },
  },
})

function add() {
  person.hobby = ['唱', '跳', 'rap']
}
function deleteHB() {
  delete person.hobby
}
</script>

<template>
  <div>
    <h1>v3</h1>
    <h1>{
  { sum }}</h1>
    <h3>姓名:{
  { person.name }}</h3>
    <h3>年龄:{
  { person.age }}</h3>
    <h3>工作:{
  { person.job.j1.jname }}</h3>
    <h3 v-if="person.hobby">爱好: {
  { person.hobby }}</h3>
    <button @click="person.name += '-'">修改姓名</button>
    <button @click="person.age++">修改年龄</button>
    <button @click="person.job.j1.jname += '!'">修改工作</button>
    <button @click="add">增加爱好</button>
    <button @click="deleteHB">删除爱好</button>
  </div>
</template>

<style scoped></style>

shallowReactive 与 shallowRef 

shallowRef 直译过来意思是浅层的 ref,shallowRef 传入对象不会求助 reactive,仅仅对ref对象的 value 属性具有响应式。

shallowReactive 只处理对象第一层的响应式,  如果修改了深层的数据页面是不会响应的,但是会在下次页面更新中渲染出来。

<script setup>
import { shallowReactive, shallowRef, ref, reactive } from 'vue'
const shallowRef_jack = shallowRef({ name: 'jack', sex: '女' })
const shallowReactive_ben = shallowReactive({
  name: 'ben',
  sex: '女',
  child: {
    son: {
      name: '张三',
    },
  },
})

const ref_jack = ref({ name: 'jack', sex: '女' })
const reactive_ben = reactive({
  name: 'ben',
  sex: '女',
  child: {
    son: {
      name: '张三',
    },
  },
})
</script>

<template>
  <div>
    <h1>v3</h1>
    <h3>
      shallowRef_jack: {
  { shallowRef_jack }}
      <button @click="shallowRef_jack = {}">修改整个对象</button>
      <button @click="shallowRef_jack.name += '!'
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值