vue3 快速上手,基础知识(一)

1 篇文章 0 订阅

前言

  • 创建一个vue3的项目
  • vue3相对于vue2都有哪些优化
  • vue3中组合式API的基础用法
  • 依赖注入

1、创建项目

# 安装脚手架
npm install -g @vue/cli
# OR
yarn global add @vue/cli

# 查看脚手架版本号
vue --version
# 图形化工具
vue ui

# 创建项目
vue create vue3
# 启动项目
cd vue3
npm run serve

2、vue3都有哪些升级

2-1. 性能
vite的优点
  • 打包大小减少
  • 启动服务变快,热更新渲染更快(存在一些缓存机制)
  • 内存占用减少
vite的缺点
  • 生态不足
  • prod环境构建,使用的 Rollup
  • 使用还不广泛,可能存在很多问题未被发现

2-2. 源码

  • 组合式API,Components API让组件抽离、逻辑代码复用更加灵活

  • 使用ES 6新增Proxy代替Object.defineProperty实现响应式

  • 更好的支持TypeScript

  • 移除一些冷门API

  • 引入 Tree shaking 按需编译,体积比vue2更小

    // 如果你的项目没有用到 watch,编译时就会 tree shaking 掉
    import { computed, watch } from 'vue';
    

3、生命周期

请添加图片描述

组合式API 生命周期引用及调用时机
// setup == beforeCreate & created
<scripte setup>
    import { onBeforeMount, onMounted, onBeforeUpdate, onUpdated, onBeforeUnmount, onUnmounted, onErrorCaptured, onRenderTracked, onRenderTriggered, onActivated, onDeactivated, onServerPrefetch } from 'vue';

    // 在组件DOM实际渲染安装之前调用,在这一步中,根元素还不存在
    onBeforeMount() {}
    // 在组件的第一次渲染后调用,该元素现在可用,允许直接DOM访问
    onMounted() {}
    
    // 数据更新时调用,发生在虚拟 DOM 打补丁之前,在更新前访问现有的DOM
    onBeforeUpdate() {}
    // DOM更新后
	onUpdated() {}
    
	// 在卸载组件实例之前调用。在这个阶段,实例仍然是完全正常的。可以卸载一些定时器等   
    onBeforeUnmount() {}
    // 卸载组件实例后调用。
    onUnmounted() {}
    
    // 被 keep-alive 缓存的组件激活时调用。
    onActivated() {}
    // 被 keep-alive 缓存的组件停用时调用。
    onDeactivated() {}
    
  	// 在捕获了后代组件传递的错误时调用。 
    onErrorCaptured() {}
    
    // 跟踪虚拟 DOM 重新渲染时调用 (只在开发环境起作用)
    onRenderTracked() {}
    // 在一个响应式依赖被组件触发了重新渲染之后调用 (只在开发环境起作用)
    onRenderTriggered() {}
    
    // 需要做SSR的生命周期,当组件实例在服务器上被渲染之前要完成的异步函数。
    onServerPrefetch() {}
<scripte>

4、响应式API

4-1. ref 函数

接受任意类型值返回一个响应式的数据

语法
let count = ref(0)
例子
<template>
	/* 在模板中使用ref响应式数据时不需要 .value 取值 */
	<div>{{count}}</div>
</template>

<script setup>
    import { ref } from 'vue'
    import type { Ref } from 'vue'

    let count = ref(0)
    // 通过.value的方式取值
    console.log(count.value) // 0
    // 通过.value的方式修改ref返回的响应式的值
    count.value ++
    console.log(count.value) // 1
    
    // 为 ref() 标注类型
    let year: Ref<string | number> = ref('2022')
    year.value = 2022
</script>
4-2. reactive 函数

定义一个对象类型响应式数据;返回一个响应式对象(Proxy 代理对象)

语法
const obj = reactive({ age: 18, sex: '男' })
例子
<template>
	/* 此处用法与 ref 一致 */
	<div>{{obj.age}}</div>
</template>

<script setup>
    import { reactive } from 'vue'
	
    const obj = reactive({ age: 18, sex: '男' })
    
    obj.age = 20
    obj.sex = '女'
    // 与 ref 不同可以直接访问和修改响应式数据的值 不需要通过 .value 获取
    console.log(obj) // { age: 20, sex: '女' }
</script>
4-3. reactive 和 ref 区别
  • ref 一般用于定义基础类型数据,如果使用 ref 定义对象或数组时 源码实际时调用 reactive
  • reactive 定义一个对象或数组返回一个响应式的 Proxy 实例
  • ref基于object.defineProperty实现响应式,reactive基于Proxy实现
4-4. computed函数

与vue2中的computed使用一致

4-5. watch函数

watch函数接受三个参数,第一个是响应式数据 第二个是更改后的回调函数 第三个是可选配置参数

语法
watch(
  () => state, // 需要监听的响应式数据
  (newValue, oldValue) => {
    // newValue === oldValue
  }, // 修改值后的回调
  { deep: true } // 执行时机,debugger 等配置
)
例子
<script setup>
    import { reactive, watch } from 'vue'    
    const state = reactive({ count: 0 })
    watch(() => state.count, (count, prevCount) => {
        /* ... */
    }, {
        immediate?: boolean, // 默认:false 是否立即监听。
        deep?: boolean, // 默认:false 是否深度监听。
        flush?: 'pre' | 'post' | 'sync', // 调用时机 pre > dom更新前;post > dom;更新后 sync > 同步调用
        onTrack?: (event: DebuggerEvent) => void,  // 会在某个响应式 property 或 ref 作为依赖被追踪时调用。
        onTrigger?: (event: DebuggerEvent) => void // 会在侦听回调被某个依赖的修改触发时调用。
    })
    
    console.log(state.count) // 访问 state.count,触发onTrack
    state.count ++ // 修改 state.count,触发onTrigger
</script>
4-6. watchEffect

用于自动收集响应式数据的依赖

语法
// 传入的函数会立即执行一次,在执行的过程中收集依赖,只有收集的依赖发生变化时 函数才会执行
// 第二个参数的三个配置项与 watch 的配置项用法一致
watchEffect(() => {
    /*  */
}, {
  flush: 'post',
  onTrack(e) {
    debugger
  },
  onTrigger(e) {
    debugger
  }
})
例子
<script setup>
import { reactive, ref, watchEffect } from "vue";
let num = ref(0)
let obj = reactive({ name: '张三' })

const stop = watchEffect(() => {
  console.log(obj.name);
})

setTimeout(() => {
  num.value ++ // watchEffect 不执行
}, 1000)
    
setTimeout(() => {
  obj.name = '李四' // watchEffect 执行
  stop() // 停止监听器
}, 3000)
    
setTimeout(() => {
  obj.name = '可鲁可' // watchEffect 不再执行
}, 5000)
</script>
清除副作用

开发中需要在侦听函数中执行网络请求,但是在网络请求还没有达到的时候停止了侦听器,或者侦听器侦听函数被再次执行了,那么上一次的网络请求应该被取消掉,这个时候可以清除上一次的副作用;

<template>
  <div>
    <p>{{name}}</p>
    <button @click="changeName">改变</button>
  </div>
</template>

<script setup>
	import { ref, watchEffect } from 'vue';

    const name = ref('张三')
    const num = ref(0)
    
    watchEffect(onInvalidate => {
        // 模拟值发生变化是需要发的一些网络请求
        const timer = setTimeout(() => {
            console.log("请求成功");
        }, 2000);
        // 上一次请求未完成再次发生变化时,取消上一次的请求
        onInvalidate(() => {
            clearTimeout(timer);
        });
        console.log('name === ', name.value);
        console.log('num === ', num.value)
    });
    const changeName = () => {
      name.value = '李四'
      num.value ++ 
    };
</script>
4-7. readonly()

接受一个对象(响应式/非响应式对象),返回一个只读状态的 Proxy 代理对象

语法
const copy = readonly(obj) 
例子
import { reactive, watchEffect, readonly } from "vue";

const original = reactive({ count: 0 })
const copy = readonly(original)

watchEffect(() => {
  // 用来做响应性追踪
  console.log(original.count)
})
watchEffect(() => {
  // 用来做响应性追踪
  console.log(copy.count)
})
setTimeout(() => {
    // 更改源属性会触发其依赖的侦听器
    original.count++

    // 更改该只读副本将会失败,并会得到一个警告
    copy.count++ // warning!
}, 2000)

5、依赖注入

实现跨层级传值

  • provide 接受两个值,第一个参数是要注入的key<string | symbol>,第二个是需要注入的值。
  • inject 接受三个值,第一个是注入的 key,第二个参数是可选参,如果没有匹配到key时使用默认值,如果默认值本身时一个函数则需要将第三个参数设置为false,表明第二个默认值就是函数而不是工厂函数。
语法
provide('foo', 'bar')
inject('foo', () => '如果没有找到foo,则使用默认值')
例子
// 父组件
<script setup>
import { ref, provide } from 'vue'

// 提供静态值
provide('foo', 'bar')

// 提供响应式的值
const count = ref(0)
provide('count', count)
</script>

// 子孙组件
<script setup>
import { inject } from 'vue'

// 接收静态数据,当foo没有被找到时使用 new foo
const inject = inject('foo', 'new foo')

// 接收响应式的值
const count = inject('count')
// 修改接收的响应式值
count.value ++
</script>
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

可鲁可的人生导师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值