120.《vue3.0 最全详细总结+案例》

文章目录

  • 一、创建Vue3.0工程
    • 1.使用 vue-cli 创建
    • 2.使用 vite 创建
  • 二.常用 Composition API
    • 1.ref函数
    • 2.reactive函数
    • 3.vue2.0响应式原理
    • 4.vue3的响应式原理
    • 5.reactive 和 ref 区别
    • 6. setup的注意点
    • 7.计算属性与监听器
      • 1.computed
      • 2.watch
      • 3.watchEffect函数
    • 8.vue3 生命周期
    • 9.自定义hook函数
    • 10.toRef 和 toRefs
      • 1.toRef
      • 2.toRefs
  • 三.其它 Composition API
    • 1.shallowReactive 与 shallowRef
    • 2.readonly 和 shallowReadonly
    • 3.toRaw 与 markRaw
    • 4.customRef
    • 5.Provide Inject 通信
    • 6.响应式数据的判断
  • 四、Composition API 的优势
    • 1.Options API 存在的问题
    • 2.Composition API 的优势
  • 五.新的内置组件
    • 1.Fragment
    • 2.Teleport
  • 六、其他
    • 1.全局API的转移
    • 2.其他改变

一、创建Vue3.0工程

1.使用 vue-cli 创建

官方文档:vue-cli

## 查看@vue/cli版本,确保@vue/cli版本在4.5.0以上
vue --version
## 安装或者升级你的@vue/cli
npm install -g @vue/cli
## 创建
vue create vue_test
## 启动
cd vue_test
npm run serve

2.使用 vite 创建

官方文档:https://v3.cn.vuejs.org/guide/installation.html#vite

vite官网:https://vitejs.cn

  • 什么是vite?—— 新一代前端构建工具。
  • 优势如下:
    • 开发环境中,无需打包操作,可快速的冷启动。
    • 轻量快速的热重载(HMR)。
    • 真正的按需编译,不再等待整个应用编译完成。
  • 传统构建 与 vite构建对比图
    120.《vue3.0 最全详细总结+案例》_第1张图片120.《vue3.0 最全详细总结+案例》_第2张图片
## 创建工程
npm init vite-app 
## 进入工程目录
cd 
## 安装依赖
npm install
## 运行
npm run dev

二.常用 Composition API

1.理解:vue3.0中的一个新的配置项,值为一个函数

2.setup是所有组合API(composition)的基础

3.组件所用到的 数据 方法 ,都配置在setup中

4.setup的返回值为对象,对象的值为setup中的数据,方法注意点

  • 尽量不要与vue2.x的混用,vue2.x中可以访问到vue3.0的 数据与方法而3.x不能访问到 vue2.X的数据和方法

  • setup不能被 async 修饰,因为vue3.0.X的返回值注定是个对象,如果被 async 修饰,那返回值就成为一个 promise了,vue3.X并没对 为promise的情况进行处理,因此setup不能被async修饰

案例:







1.ref函数

概念:ref函数可以实现 响应式数据

语法:

import {ref} 'vue'
const name = ref('张三')
const obj = ref({
   kind:"web前端",
   salary:"30k"
}) 
  • 被ref函数包裹 返回一个 ref 引用实例对象

  • 修改被ref包裹的数据方式

     // 基本数据类型
     name.value = '李四'
     // 对象数据类型
     onj.value.kind = 'ui工程师'
     obj.value.salary = '60k'
    
  • 被ref包裹的基本数据类型返回一个ref引用实例,被包裹的对象通过其 reactive函数返回一个proxy对象,实现对象的响应式

2.reactive函数

  • 作用:定义一个对象类型的响应式数据(基本数据类型不用它,用ref)

  • 语法:reactive包裹一个对象或数组,返回一个被包裹后的代理对象

    const 代理对象 = reactive(源对象)
    
  • reactive 定义的数据是深层次的,可以被深度监听响应式

  • reactive 的底层是通过es6的proxy代理实现深度响应式

案例(骚写法):






3.vue2.0响应式原理

  • 实现原理

    • 对象类型:通过对 object.defindProperty() 对属性的读取 修改进行拦截(数据劫持)

      object.defindProperty()
      
    • 数组类型:通过重写数组的一系列方法来进行拦截(对数组的变更方法进行了拦截)

      push()
      pop()
      shift()
      unshift()
      splice()
      sort()
      reverse()
      

    vue2.0响应式存在的问题

    • 新增属性,删除属性也不会进行更新
    • 通过下标修改数组,页面不会进行更新

    原理模拟代码:

案例1:

   // vue2中的响应式 无法监听 对象 新增 和 删除 属性
          let person = {
              name: "张三",
              age: 18
          }
          let p = {}
          Object.defineProperty(p, "name", {
              configurable:true,
              get() {
                  console.log('读取了name属性', person.name);
                  return person.name
              },
              set(value) {
                  console.log('修改了name属性', value);
                  person.name = value
              }
          })

案例2:




    
    
    
    Document


    

你好,我是

我来自于:

4.vue3的响应式原理

  • 通过 Proxy代理,拦截对象中任意属性的变化,包括对象的新增属性,删除属性
  • 通过 Reflect 反射,对元对象属性进行操作
  // vue 3 响应式原理
        let per = {
            name:"li飞",
            age:15
        }
        // let p = new Proxy(per,{})
        // p 输出的结果 
        // [[Handler]]: Object 增删啊改 的 方法
        // [[Target]]: Object 源数据
        // [[IsRevoked]]: false 
       let p = new Proxy(per,{
            // 读取时 触发 
            get(target,propName){
                console.log( '当属性被读取时触发' );
                return Reflect.get(target,propName)
            },
            // 修改时 触发
            set(target,propName,newVal){
                console.log( "属性被修改时触发",target,propName,newVal );
                // target[propName] = newVal
                Reflect.set(target,propName,newVal) 
            },
            // 删除时 触发
            deleteProperty(target,propName){
                console.log( "属性被删除时触发" ,target,propName)
                // delete target[propName]
                Reflect.deleteProperty(target,propName)
            }
        })

5.reactive 和 ref 区别

  • 从定义数据的角度对比:
    • ref 用来定义:基本数据类型
    • reactive 用来定义:对象或数组类型
    • 备注:ref 也可以定义 数组或对象 ,它内部会通过 reactive函数转为代理对象
  • 从原理角度:
    • ref 底层通过 Object.defineProperty() 的get 和 set 来实现 响应式(数据劫持)
    • reactive 通过使用 Proxy 来实现响应式(数据劫持),并通过 Reflect 来操作源对象内部的数据
  • 从使用角度对比:
    • ref 定义的数据:操作数据需要 .value,读取数据时,模板中直接读取,不需要 .value
    • reactive 定义的数据:操作数据与读取数据:均不需要 .value

6. setup的注意点

  • setup 执行时机

    • 在 beforeCreate 之前,并且 其内部中的 this 为 undefined
  • setup两个参数

    • props: 值为对象,且为父组件传递过来的数据,且在组件中通过 props 接收的数据

    • context

      • attrs: 值为对象 且为父组件传递过来的数据,且没在 props中定义的数据
      • emit: 分发自定义事件的函数 相当于 this.$emit
      • s l o t : 收 到 的 插 槽 内 容 相 当 于 t h i s . slot: 收到的插槽内容 相当于 this. slot:this.slot
    • 案例

      父组件

      
      
      
      
      
      
      • 子组件
        
        
        
      

7.计算属性与监听器

1.computed

  • 与 vue2.x 的功能一致
  • 语法






2.watch

  • 与Vue2.x中watch配置功能一致

  • 两个小“坑”

    • 监视reactive定义的响应式数据时:oldValue无法正确获取、强制开启了深度监视(deep配置失效)。
    • 监视reactive定义的响应式数据中某个属性时:deep配置有效。
    //情况一:监视ref定义的响应式数据
    watch(sum,(newValue,oldValue)=>{
    	console.log('sum变化了',newValue,oldValue)
    },{immediate:true})
    
    //情况二:监视多个ref定义的响应式数据
    watch([sum,msg],(newValue,oldValue)=>{
    	console.log('sum或msg变化了',newValue,oldValue)
    }) 
    
    /* 情况三:监视reactive定义的响应式数据
    			若watch监视的是reactive定义的响应式数据,则无法正确获得oldValue!!
    			若watch监视的是reactive定义的响应式数据,则强制开启了深度监视 
    */
    watch(person,(newValue,oldValue)=>{
    	console.log('person变化了',newValue,oldValue)
    },{immediate:true,deep:false}) //此处的deep配置不再奏效
    
    //情况四:监视reactive定义的响应式数据中的某个属性
    watch(()=>person.job,(newValue,oldValue)=>{
    	console.log('person的job变化了',newValue,oldValue)
    },{immediate:true,deep:true}) 
    
    //情况五:监视reactive定义的响应式数据中的某些属性
    watch([()=>person.job,()=>person.name],(newValue,oldValue)=>{
    	console.log('person的job变化了',newValue,oldValue)
    },{immediate:true,deep:true})
    
    //特殊情况
    watch(()=>person.job,(newValue,oldValue)=>{
        console.log('person的job变化了',newValue,oldValue)
    },{deep:true}) //此处由于监视的是reactive素定义的对象中的某个属性,所以deep配置有效
    

3.watchEffect函数

  • watch 监听器:既要指明监听的属性,也要指明监视的回调

  • watchEffect的回调是:不用指明监听哪个属性,监视的回调中用到那个属性,那就监听哪个属性

  • watchEffect有点像computed:

    • 但是computed更注重的是计算出来的值(回调函数的返回值),所以必须要写返回值
    • 而watch更注重的是过程(回调函数的函数体),所以不用写返回值
    //watchEffect所指定的回调中用到的数据只要发生变化,则直接重新执行回调。
    watchEffect(()=>{
        const x1 = sum.value
        const x2 = person.age
        console.log('watchEffect配置的回调执行了')
    })
    

8.vue3 生命周期

  **vue2 ------------------------- vue3**
  • beforeMount ===>onBeforeMount
  • mounted=======>onMounted
  • beforeUpdate===>onBeforeUpdate
  • updated =======>onUpdated
  • beforeUnmount ==>onBeforeUnmount
  • unmounted =====>onUnmounted



9.自定义hook函数

  • 什么是hook?—— 本质是一个函数,把setup函数中使用的Composition API进行了封装。

  • 类似于vue2.x中的mixin。

  • 自定义hook的优势: 复用代码, 让setup中的逻辑更清楚易懂。

10.toRef 和 toRefs

1.toRef

  • 作用:创一个 ref对象,其 value 值 指向另一个对象中的某个属性

  • 语法;

    const person = { name:"张三" }
    const name = toRef(person,'name')
    
  • 应用:要将相应始终的某个属性 单独提供给外部使用时

  • 案例

    
    
    
    
    
    
    

2.toRefs

  • 作用:创一个 ref对象,将多个 value 值 指向另一个对象中的多个属性

  • 语法:

    person = { name:"李晓飞",age:18 }
    const p = toRefs(person)
    
  • 应用:将多个响应式数据同时提供给外部使用

  • 案例

    
    
    
    
    
    
    

三.其它 Composition API

1.shallowReactive 与 shallowRef

  • shallowReactive :只处理对象的第一层数据为响应式数据(浅响应式)
  • shallowRef : 被包裹的对象 或 基本数据类型,将不再具有响应式的特征
  • 什么时候使用:
    • 如果一个对象嵌套结构比较深,并且只有最外层的数据变动,使用 ====> shallowReactive
    • 如果一个对象,后期将不对其内部的属性进行更改,那马使用 ====> shallowRef
  • 案例





2.readonly 和 shallowReadonly

  • readonly :让一个数据变为只读数据(深只读)

  • shallowReadonly : 让一个多层嵌套的数据变为 浅只读 数据(只有第一层数据只读)

  • 应用场景: 不希望数据被修改时。

  • 案例

    
    
    
    
    
    

3.toRaw 与 markRaw

  • toRaw
    • 作用:将一个由reactive生成的响应式对象转为普通对象
    • 使用场景:用于读取响应式对象对应的普通对象,对这个普通对象的所有操作,不会引起页面更新。
  • markRaw
    • 作用:标记一个对象,使其永远不会再成为响应式对象。
    • 应用场景:
      1. 有些值不应被设置为响应式的,例如复杂的第三方类库等。
      2. 当渲染具有不可变数据源的大列表时,跳过响应式转换可以提高性能。

4.customRef

  • 作用:自定义ref , 对其 依赖项 进行 跟踪触发 更新视图

  • 案例:

    
    
    
    
    
    
    

5.Provide Inject 通信

120.《vue3.0 最全详细总结+案例》_第3张图片

  • 通常,当我们需要从父组件向子组件传递数据时,我们使用 props。想象一下这样的结构:有一些深度嵌套的组件,而深层的子组件只需要父组件的部分内容。在这种情况下,如果仍然将 prop 沿着组件链逐级传递下去,可能会很麻烦。
  • provideinject。无论组件层次结构有多深,父组件都可以作为其所有子组件的依赖提供者。这个特性有两个部分:父组件有一个 provide 选项来提供数据,子组件有一个 inject 选项来开始使用这些数据。

案例文件结构

120.《vue3.0 最全详细总结+案例》_第4张图片

案例效果图

120.《vue3.0 最全详细总结+案例》_第5张图片

  • 祖父组件:

    
    
    
    
    
    
    
  • 子组件

    
    
    
    
    
    
  • 祖孙组件

    
    
    
    
    
    

6.响应式数据的判断

  • isRef: 检查一个值是否为一个 ref 对象
  • isReactive: 检查一个对象是否是由 reactive 创建的响应式代理
  • isReadonly: 检查一个对象是否是由 readonly 创建的只读代理
  • isProxy: 检查一个对象是否是由 reactive 或者 readonly 方法创建的代理

四、Composition API 的优势

1.Options API 存在的问题

使用传统OptionsAPI中,新增或者修改一个需求,就需要分别在data,methods,computed里修改

2.Composition API 的优势

我们可以更加优雅的组织我们的代码,函数。让相关功能的代码更加有序的组织在一起。

五.新的内置组件

1.Fragment

  • 在Vue2中: 组件必须有一个根标签
  • 在Vue3中: 组件可以没有根标签, 内部会将多个标签包含在一个Fragment虚拟元素中
  • 好处: 减少标签层级, 减小内存占用

2.Teleport

  • 什么是Teleport?—— Teleport 是一种能够将我们的组件html结构移动到指定位置的技术。

  • 效果图

    120.《vue3.0 最全详细总结+案例》_第6张图片

  • 案例结构:

    120.《vue3.0 最全详细总结+案例》_第7张图片

    App.vue

    
    
    
    
    
    

    child1

    
    
    
    
    
    

    child2

    
    
    
    
    
    

六、其他

1.全局API的转移

  • Vue 2.x 有许多全局 API 和配置。

    • 例如:注册全局组件、注册全局指令等。

      //注册全局组件
      Vue.component('MyButton', {
        data: () => ({
          count: 0
        }),
        template: ''
      })
      
      //注册全局指令
      Vue.directive('focus', {
        inserted: el => el.focus()
      }
      
  • Vue3.0中对这些API做出了调整:

    • 将全局的API,即:Vue.xxx调整到应用实例(app)上

      2.x 全局 API(Vue 3.x 实例 API (app)
      Vue.config.xxxx app.config.xxxx
      Vue.config.productionTip 移除
      Vue.component app.component
      Vue.directive app.directive
      Vue.mixin app.mixin
      Vue.use app.use
      Vue.prototype app.config.globalProperties

2.其他改变

  • data选项应始终被声明为一个函数。

  • 过度类名的更改:

    • Vue2.x写法

      .v-enter,
      .v-leave-to {
        opacity: 0;
      }
      .v-leave,
      .v-enter-to {
        opacity: 1;
      }
      
    • Vue3.x写法

      .v-enter-from,
      .v-leave-to {
        opacity: 0;
      }
      
      .v-leave-from,
      .v-enter-to {
        opacity: 1;
      }
      
  • 移除keyCode作为 v-on 的修饰符,同时也不再支持config.keyCodes

  • 移除v-on.native修饰符

    • 父组件中绑定事件

      
      
    • 子组件中声明自定义事件

      
      
  • 移除过滤器(filter)

    过滤器虽然这看起来很方便,但它需要一个自定义语法,打破大括号内表达式是 “只是 JavaScript” 的假设,这不仅有学习成本,而且有实现成本!建议用方法调用或计算属性去替换过滤器。

你可能感兴趣的:(vue.js,javascript,前端)