vue3学习的第一天

400 阅读9分钟

Vue3第一天 初识级属性用法

1.vue3的优势以及发展趋势

  • 社区生态 - 逐步完善
  • 整体优化 - 性能优化/TS支持优化/组合式API加持
  • 市场使用 - 部分技术选型激进的公司已经在生产环境使用了vue3

社区生态

组件(插件)名称官方地址简介
ant-design-vueantdv.com/docs/vue/in…ant-design-vue 是 Ant Design 的 Vue 实现,组件的风格与 Ant Design 保持同步
element-pluselement-plus.gitee.io/#/zh-CNElement Plus,一套为开发者、设计师和产品经理准备的基于 Vue 3.0 的桌面端组件库
vantvant-contrib.gitee.io/vant/v3/#/z…有赞前端团队开源的移动端组件库,于 2016 年开源,已持续维护 4 年时间
Naive UIwww.naiveui.com/zh-CN/一个 Vue 3 组件库比较完整,主题可调,使用 TypeScript,不算太慢,有点意思
VueUsevueuse.org/基于composition组合api的常用集合,小兔仙项目会部分使用

整体优化

  1. 性能提升

    • 首次渲染更快
    • diff算法更快
    • 内存占用更少
    • 打包体积更小
  2. 更好的Typescript支持

  3. Composition API (重点)

相关阅读:

  1. Vue3 中文文档 vue3js.cn/docs/zh/
  2. Vue3 设计理念 vue3js.cn/vue-composi…

市场使用

​ 很多公司已经在生产环境投入使用,未来的趋势

2 Vue3开发环境搭建

在新建文件夹中的根路径输入cmd 打开黑窗口 输入命令 vue create 加上项目名字

vue3 是在vu2的基础上增加了更多的功能

3## 选项式和组合式API的关系

本节目标: 能够理清楚俩种API之间的关系

  1. 组合式API的目的是增强,不是取代选项式API,vue3.x对俩种API都支持
  2. 简单的场景使用选项式API更加简单方便
  3. 需要强烈支持TS的项目首选组合式API
  4. 需要大量逻辑复用的场景首选组合式API

4组合式APi

1.setup入口函数

本节目标: 能够理解setup函数的作用和调用时机

主要内容

  1. setup 函数是一个新的组件选项,作为组件中组合式API 的起点(入口)
  2. setup函数只会在组件初始化的时候执行一次
  3. setup函数在beforeCreate生命周期钩子执行之前执行,实例还没生成,没有this

代码示例

export default { setup (){ console.log('setup执行了') console.log(this) }, beforeCreate(){ console.log('beforeCreate执行了') console.log(this)

} }

2.响应式API - reactive

作用 reactive是一个函数,接收一个普通的对象传入,把对象数据转换成为响应式对象返回

使用步骤 1.从vue框架中导入reactive函数 2.在setup函数中调用reactive函数并将想要的响应式变成对象数据当成参数传入 3.在setup函数中把reactive函数调用完毕之后的返回值以对象的形式返回出去

注意事项: 1. 函数只能处理对象格式 2. 展开运算符 解构赋值都有可能破坏响应式结构 如果就是想展开需要使用toRefs函数包裹之后再展开.

3.响应式API-ref

**作用 **

ref 是一个函数,接受一个简单类型或者复杂类型的传入并返回一个响应式且可变的ref对象

使用步骤

1.从vue 框架中导出ref函数 2.在setup函数中调用ref函数并且传入数据(简单类型或者复杂类型) 3.在setup函数中把ref函数调用完毕的返回值以对象的形式返回出去 4.注意: 在setup函数中使用ref结果,需要通过.value访问,模板中使用不需要加.value

代码演示

注意事项: 1. 由ref函数产出的数据如果在setup中想做修改 必须加上.value 2. 为了避免忘记.value 可以在命名上 加一个ref标识 3. 模板(template)中使用会有一个叫做 ‘自动解套’的机制 不需要加.value

4.reative 对比 ref

本节目标: 知道俩个API的特定以及如何在项目中选择

  1. ref 函数可以接收一个简单类型的值,返回一个可改变的 ref 响应式对象,从而弥补reactive函数不支持简单类型的问题
  2. reactive和ref函数都可以提供响应式数据的转换,具体什么时候需要使用哪个API社区还没有最佳实践,大家暂时可以使用自己熟练的API进行转换
  3. 推荐写法 只有我们明确知道要转换的对象内部的字段名称我们才使用reactive,否则就一律使用ref,从而降低在语法选择上的心里负担。

5. 响应式API - computed

作用

根据现有响应式数据经过一定的计算得到全新的数据

使用步骤

  1. 从vue框架中导入computed 函数
  2. 在setup函数中执行computed函数,并传入一个函数,在函数中定义计算公式
  3. 把computed函数调用完的返回值放到setup函数return出去的对象中

计算属性 vue2 什么是计算属性? 依赖于一个已经存在的响应式数据 当这个数据发生变化时 会自动重新计算得到新值

      缓存特性?如果模板中用到了多次这个计算属性 第一次的时候执行函数进行计算
      剩下都是直接使用缓存之后的值 

      必须依赖的数据发生变化 才会重新计算

6.响应式API-Watch

作用

    基于响应式数据的变化执行回调逻辑,和vue2中的watch的功能一致
  1. 普通监听 数据变化之后才执行回调逻辑
  2. 立即执行 一上来先执行一次 不等数据变化
  3. 深度监听 对象嵌套的场景 监听整个对象的变化

使用步骤

  1. 从vue框架中导入watch函数

  2. 在setup函数中执行watch函数开启对响应式数据的监听

  3. watch函数接收三个常规参数

    1. 第一个参数为函数,返回你要监听变化的响应式数据
    2. 第二个参数为响应式数据变化之后要执行的回调函数
    3. 第三个参数为一个对象,在里面配置是否开启立刻执行或者深度监听

代码演示

1)普通监听

2)开启立刻执行

watch的效果默认状态下,只有监听的数据发生变化才会执行回调,如果你需要在一上来的时候就立刻执行一次,需要配置一下immediate属性

3)开启深度监听

当我们监听的数据是一个对象的时候,默认状态下,对象内部的属性发生变化是不会引起回调函数执行的,如果想让对象下面所有属性都能得到监听,需要开启deep配置

4)更好的做法

使用watch的时候,尽量详细的表明你到底要监听哪个属性,避免使用deep引起的性能问题,比如我仅仅只是想在state对象的age属性变化的时候执行回调,可以这么写

watch 监听实例属性的变化 然后变化之后执行一些逻辑

  立刻执行:在组件实例化的时候就先执行一次回调 
  深度监听:遇到监听的数据对象嵌套的层级比较深 就可以开启深度监听
            不管对象嵌套多深,只要修改某个属性 都会触发回调执行

关于深度监听 尽量避免使用深度监听 由于开启这个开关之后 vue自动递归处理整个对象 如果对象很大 有一定的性能损耗 如果要监听一个层级比较深的属性 建议直接精细的话书写 要监听谁就写到谁那里

7. 生命周期函数

使用步骤

  1. 先从vue中导入以on打头的生命周期钩子函数
  2. 在setup函数中调用生命周期函数并传入回调函数
  3. 生命周期钩子函数可以调用多次

代码演示

<template>
  <div>生命周期函数</div>
</template><script>
import { onMounted } from 'vue'
export default {
  setup() {
    // 时机成熟 回调函数自动执行
    onMounted(() => {
      console.log('mounted生命周期执行了')
    })
    onMounted(() => {
      console.log('mounted生命周期函数又执行了')
    })
  }
}
</script> 
选项式API下的生命周期函数使用组合式API下的生命周期函数使用
beforeCreate不需要(直接写到setup函数中)
created不需要(直接写到setup函数中)
beforeMountonBeforeMount
mountedonMounted
beforeUpdateonBeforeUpdate
updatedonUpdated
beforeDestroyedonBeforeUnmount
destroyedonUnmounted

生命周期钩子函数使用场景

生命周期钩子函数应用场景
created发送ajax请求 / 挂载共用属性
mounted发送ajax请求 / 依赖于dom的业务,比如地图,图表
destroyed销毁操作,比如定时器

生命周期钩子函数 如何理解?组件在初始化到销毁的整个过程中 到达某个阶段自动执行的函数 特点:不同阶段 自动触发 注意事项 1. 所有的钩子函数都是 一样的用法 onXXX
2. 每个钩子函数都可以执行n次 每次传入的回调会在实际成熟时依次执行

8. 父子通信

在vue3的组合式API中,父传子的基础套路完全一样,基础思想依旧为:父传子是通过prop进行传入,子传父通过调用自定义事件完成

实现步骤

  1. setup函数提供俩个参数,第一个参数为props,第二个参数为一个对象context
  2. props为一个对象,内部包含了父组件传递过来的所有prop数据,context对象包含了attrs,slots, emit属性,其中的emit可以触发自定义事件的执行从而完成子传父

代码演示

app.vue

components/Son.vue

注意:不是响应式可以使用解构赋值 组件父子通信 父传子 怎么办? prop 子传父 怎么办? 自定义事件 + $emit

  实现父传子  setup(props)
  实现子传父
  

9.provide 和 inject

1. 使用场景

通常我们使用props进行父子之间的数据传递,但是如果组件嵌套层级较深,一层一层往下传递将会变的非常繁琐,有没有一种手段可以把这个过程简化一下呢,有的,就是我们马上要学习的provide 和 inject,它们配合起来可以方便的完成从上层组件向任意下层组件传递数据的效果

2. 基础使用

实现步骤

  1. 顶层组件在setup方法中使用provide函数提供数据

    provide('key',数据)

  2. 任何底层组件在setup方法中使用inject函数获取数据

    const data = inject('key')

代码落地

孙组件 - components/Son.vue

事实上,只要是后代组件,都可以方便的获取顶层组件提供的数据

3. 传递响应式数据

provide默认情况下传递的数据不是响应式的,也就是如果对provide提供的数据进行修改,并不能响应式的影响到底层组件使用数据的地方,如果想要传递响应数据也非常简单,只需要将传递的数据使用ref或者reactive生成即可

10.TemplateRef

背景知识

​ 在模板中使用ref,我们都很清楚,它一般有三种使用场景

  1. ref + 普通dom标签 获取真实dom对象 <div ref="box"></div> this.$refs.box
  2. ref + 组件标签 获取组件实例对象 <Form ref="form"/> this.$refs.form.validate()
  3. ref + v-for 获取由dom对象(实例对象)组成的数组 (不经常使用

实现步骤 0. 使用ref函数传入null创建 ref对象 => const hRef = ref(null) 0. 模板中通过定义ref属性等于1中创建的ref对象名称建立关联 => <h1 ref="hRef"></h1> 0. 把hRefreturn出去 0. 使用 => hRef.value

代码落地

components/RefComponent.vue

app.vue

tempalteRef ref 获取一个真实的dom对象 获取一个组件实例对象

this.refs.div>dom兜底校验this.refs.div -> dom 兜底校验 this.refs.form -> 表单实例 validate 如何在setup中实现获取dom/组件实例对象?

  实现步骤:
    1. 导入一个ref函数
    2. 执行ref函数 传入一个null (固定的套路)
    3.ref函数生成的结果 return出去
    4. 在模板中需要获取的元素或者组件身上 通过ref标记即可

// setup 作用初始化的时候进行 ‘链接操作’ // 我只负责 把数据 / 回调函数 和模板进行链接 // 我也负责 帮你注册好在某个时机下要执行的钩子函数 // 具体什么时候数据有值了 什么时候时机成熟了要执行了 我不管 // 所有的入口只是一个初始化的动作

11. 语法兼容问题

vue3.0对于2.0版本的大部分语法都是可以兼容的,但是也有一些破坏性的语法更新,这个大家要格外注意

  1. 过滤器filter移除 (插值表达式里不能再使用过滤器 可以使用methods替代)
  2. .sync语法移除 (dialog) (和v-model语法合并)
  3. eventBus onemit