当前位置: 首页 > news >正文

web前端面试高频考点——Vue3.0新增API(生命周期,ref、toRef 和 toRefs 的理解和最佳使用方式)

系列文章目录

内容参考链接
JavaScript 面试高频考点HTML、CSS、JavaScript、ES6、AJAX、HTTP 面试考点
Vue2.x 面试高频考点Vue2.x 面试高频考点

文章目录

  • 系列文章目录
    • 一、Vue3 比 Vue2 有什么优势?
    • 二、Vue2 和 Vue3 生命周期区别
      • 1、Options API 生命周期
      • 2、Composition API 生命周期
    • 三、如何理解 Composition API 和 Options API
      • 1、Composition API 带来了什么
      • 2、Composition API 和 Options API 如何选择?
      • 3、如何选择
      • 4、别误解 Composition API
    • 四、如何理解 ref、toRef 和 toRefs
      • 1、ref
      • 2、ref 扩展(获取模板的dom元素)
      • 3、toRef
      • 4、toRefs
    • 五、ref、toRef 和 toRefs 的最佳使用方式


一、Vue3 比 Vue2 有什么优势?

  • 性能更好
  • 体积更小
  • 更好的 ts 支持
  • 更好的代码组织
  • 更好的逻辑抽离
  • 更多新功能

二、Vue2 和 Vue3 生命周期区别

App.vue 父组件:

<template>
  <div>
    <life-cycles :msg="msg" v-if="flag" />
    <button @click="changeHandler">change msg</button>
    <button @click="changeFlagHandler">change flag</button>
  </div>
</template>

<script>
import LifeCycles from "./components/LifeCycles.vue";
export default {
  data() {
    return {
      msg: "hello vue3",
      flag: true,
    };
  },
  methods: {
    changeHandler() {
      this.msg = "hello vue3" + Date.now();
    },
    changeFlagHandler() {
      this.flag = !this.flag;
    },
  },
  components: { LifeCycles },
};
</script>

1、Options API 生命周期

LiftCycles.vue 子组件:

  • Vue2.x 的形式
  • 点击按钮进行 组件更新组件销毁(查看控制台输出内容)
<template>
  <p>生命周期 {{ msg }}</p>
</template>
  
<script>
export default {
  name: "LiftCycles",
  props: {
    msg: String,
  },
  beforeCreate() {
    console.log("beforeCreate");
  },
  created() {
    console.log("created");
  },
  beforeMount() {
    console.log("beforeMount");
  },
  mounted() {
    console.log("mounted");
  },
  beforeUpdate() {
    console.log("beforeUpdate");
  },
  updated() {
    console.log("updated");
  },
  beforeUnmount() {
    console.log("beforeUnmount");
  },
  unmounted() {
    console.log("unmounted");
  },
};
</script>

在这里插入图片描述


在这里插入图片描述


在这里插入图片描述


2、Composition API 生命周期

  • beforeDestroy 改为 beforeUnmount
  • destroyed 改为 unmounted
  • 其他沿用 Vue2 的生命周期
<template>
  <p>生命周期 {{ msg }}</p>
</template>
  
<script>
import {
  onBeforeMount,
  onMounted,
  onBeforeUpdate,
  onUpdated,
  onBeforeUnmount,
  onUnmounted,
} from "vue";

export default {
  name: "LiftCycles",
  props: {
    msg: String,
  },
  // 等于 beforeCreate 和 created
  setup() {
    console.log("setup");

    onBeforeMount(() => {
      console.log("onBeforeMounted");
    });
    onMounted(() => {
      console.log("onMounted");
    });
    onBeforeUpdate(() => {
      console.log("onBeforeUpdate");
    });
    onUpdated(() => {
      console.log("onUpdated");
    });
    onBeforeUnmount(() => {
      console.log("onBeforeUnmount");
    });
    onUnmounted(() => {
      console.log("onUnmounted");
    });
  },
};
</script>

在这里插入图片描述


在这里插入图片描述


在这里插入图片描述


三、如何理解 Composition API 和 Options API

Options API 对比 Composition API:

请添加图片描述

1、Composition API 带来了什么

  • 更好的代码组织
  • 更好的逻辑复用
  • 更好的类型推导

2、Composition API 和 Options API 如何选择?

  • 不建议共用,容易引起代码混乱
  • Composition API 用于复杂的业务情况
  • Options API 用于简单的业务情况

3、如何选择

  • 不建议乱用,会引起混乱
  • 小型项目、业务逻辑简单,用 Options API
  • 中大型项目、逻辑复杂,用 Composition API

4、别误解 Composition API

  • Composition API 属于高阶技巧,不是基础必会
  • Composition API 是为解决复杂业务逻辑而设计
  • Composition API 就像 Hooks 在 React 中的地位

四、如何理解 ref、toRef 和 toRefs

1、ref

  • 生成值类型的响应式数据
  • 可以用于 reactive,也可以用于模板(不需要 .value)
  • 用 .value 去修改值
  • 所有的 ref 变量,尽量使用 xxxRef 的格式命名,便于区分

Ref.vue 组件

  • ref 用来定义响应式的值类型
  • reactive 用来定义响应式的引用类型
  • ref 定义的值类型可在 reactive 和 模板中直接使用(不需要 .value
  • 修改值的时候要使用 .value
<template>
  <p>ref demo {{ ageRef }} {{ state.name }}</p>
</template>
  
<script>
import { ref, reactive } from "vue";
export default {
  name: "Ref",
  setup() {
    const ageRef = ref(21); // 值类型 响应式
    const nameRef = ref("杂货铺");

    const state = reactive({
      name: nameRef,
    });

    setTimeout(() => {
      console.log("ageRef", ageRef.value);

      ageRef.value = 18; // .value 修改值
      nameRef.value = "前端杂货铺";
    }, 1000);

    return {
      ageRef,
      state,
    };
  },
};
</script>

在这里插入图片描述


在这里插入图片描述


2、ref 扩展(获取模板的dom元素)

RefTemplate.vue 组件

  • ref 本身的意思就是一个引用,给它传什么,它就是指向什么
  • 传一个 DOM 当然就指向 DOM 了
<template>
  <p ref="elemRef">我是一行文字</p>
</template>

<script>
import { ref, onMounted } from "vue";
export default {
  name: "RefTemplate",
  setup() {
    const elemRef = ref(null);

    onMounted(() => {
        console.log('ref template', elemRef.value.innerHTML, elemRef.value);
    })

    return {
      elemRef,
    };
  },
};
</script>

在这里插入图片描述


3、toRef

  • 针对一个响应式对象(reactive)的 prop(属性)
  • 创建一个 ref,具有响应式
  • 两者保持引用关系

toRef.vue 组件

  • toRef(对象, "属性") 修改响应式对象的属性
  • 改变 ageRef 时, state.age 也会改变
  • 改变 state.age 时,ageRef 也会改变
<template>
  <p>toRef demo - {{ ageRef }} - {{ state.name }} - {{ state.age }}</p>
</template>

<script>
import { reactive, toRef } from "@vue/reactivity";

export default {
  name: "ToRef",
  setup() {
    const state = reactive({
      age: 20,
      name: "杂货铺",
    });

    // toRef 如果用于普通对象(非响应式对象),产出的结果不具备响应式
    // const state = {
    //     age: 20,
    //     name: '杂货铺'
    // }

	// 修改响应式对象(reactive)的一个属性(age)
    const ageRef = toRef(state, "age");

    setTimeout(() => {
      state.age = 25;
    }, 1000);

    setTimeout(() => {
      ageRef.value = 30; // 用 .value 修改值
    }, 2000);

    return {
      state,
      ageRef,
    };
  },
};
</script>

在这里插入图片描述


在这里插入图片描述


在这里插入图片描述

4、toRefs

  • 将响应式对象(reactive 封装)转换为普通对象
  • 对象的每个 prop 都是对应的 ref
  • 两者保持引用关系

toRefs 组件

  • toRefs,将响应式对象变为普通对象(仍然具有响应式)
  • 对象的每个属性都是对应的 ref
<template>
  <p>toRefs demo {{ ageRef }} {{ nameRef }}</p>
</template>

<script>
import { toRefs, reactive } from "vue";
export default {
  name: "ToRefs",
  setup() {
    const state = reactive({
      age: 20,
      name: "杂货铺",
    });

    // 将响应式对象,变为普通对象
    const stateAsRefs = toRefs(state); 

    // 每个属性,都是 ref 对象
    const { age: ageRef, name: nameRef } = stateAsRefs; 

    setTimeout(() => {
      state.age = 25
    }, 1000)

    return {
      ageRef,
      nameRef,
    };
  },
};
</script>

在这里插入图片描述

或者这么写(推荐):

  • 直接返回这个普通对象
  • 注意此时模板内容也发生了变化,直接写对象里面的属性
<template>
  <p>toRefs demo {{ name }} {{ age }}</p>
</template>

<script>
import { toRefs, reactive } from "vue";
export default {
  name: "ToRefs",
  setup() {
    const state = reactive({
      age: 20,
      name: "杂货铺",
    });

    // 将响应式对象,变为普通对象
    const stateAsRefs = toRefs(state); 

	setTimeout(() => {
      state.age = 25
    }, 1000)
    
    return stateAsRefs
  },
};
</script>

在这里插入图片描述

在这里插入图片描述

五、ref、toRef 和 toRefs 的最佳使用方式

  • 用 reactive 做对象的响应式,用 ref 做值类型的响应式
  • setup 中返回 toRefs(state),或者 toRefs(state, ‘xxx’)
  • ref 的变量命名都用 xxxRef
  • 合成函数返回响应式对象时,使用 toRefs

xxx.js 文件

  • 定义函数和响应式对象
  • 返回时转为 ref
import { toRefs, reactive } from "vue"

function useFeatureX() {
    const state = reactive({
      x: 1,
      y: 2
    })
  
    // 逻辑运行状态,省略 N 行
      
    // 返回时转换为 ref
    return toRefs(state)
}

export default useFeatureX

xxx.vue 组件

  • 使用时直接写对象的属性就可以
export default {
  setup() {
    // 可以在不是去响应式的情况下破坏结构
    const { x, y } = useFeatureX()

    return {
      x,
      y
    }
  } 
}

不积跬步无以至千里 不积小流无以成江海

这篇文章如果对你有些许帮助,还请铁铁 三连 + 关注 支持一波,优质好文,正在产出…

相关文章:

  • 管理经济学--重点
  • Java学习路线(个人学习总结)
  • 【数据结构】跳表SkipList代码解析(C++)
  • 中医治疗特发性震颤,哪些食物不能吃?
  • 2022 创业方向指南
  • 11.vue3组件化开发(父子组件之间的通信)
  • 戳这里!有机产品认证知识库来了
  • 基于微信小程序和安卓的农产品线上销售购物商城APP
  • QScored大型代码异味和质量度量-数据集
  • 爱摸鱼的TT~自学Java从入门到入土学习手册
  • 中断上下文使用spin_lock进程上下文使用spin_lock_irqsave的原因?
  • 【AGC】【FAQ】Dynamic Ability常见问题
  • 集成应用签名服务,加入签名计划后,想要删除AGC中托管的应用签名,退出签名计划如何做?应用签名服务常见问题小集合
  • docker 查看容器启动日志 查看运行日志
  • 【web-攻击本地编译性应用程序】(11.1)缓冲区溢出漏洞
  • 【Amaple教程】5. 插件
  • 【跃迁之路】【699天】程序员高效学习方法论探索系列(实验阶段456-2019.1.19)...
  • 78. Subsets
  • Angular 响应式表单 基础例子
  • docker容器内的网络抓包
  • iOS 系统授权开发
  • JS变量作用域
  • oldjun 检测网站的经验
  • opencv python Meanshift 和 Camshift
  • oschina
  • PHP 使用 Swoole - TaskWorker 实现异步操作 Mysql
  • react-core-image-upload 一款轻量级图片上传裁剪插件
  • 大数据与云计算学习:数据分析(二)
  • 基于Volley网络库实现加载多种网络图片(包括GIF动态图片、圆形图片、普通图片)...
  • 计算机在识别图像时“看到”了什么?
  • 技术胖1-4季视频复习— (看视频笔记)
  • 坑!为什么View.startAnimation不起作用?
  • 嵌入式文件系统
  • 什么软件可以剪辑音乐?
  • 树莓派 - 使用须知
  • 说说动画卡顿的解决方案
  • 微信小程序填坑清单
  • # 安徽锐锋科技IDMS系统简介
  • $$$$GB2312-80区位编码表$$$$
  • (17)Hive ——MR任务的map与reduce个数由什么决定?
  • (30)数组元素和与数字和的绝对差
  • (8)STL算法之替换
  • (html转换)StringEscapeUtils类的转义与反转义方法
  • (八)Spring源码解析:Spring MVC
  • (二十一)devops持续集成开发——使用jenkins的Docker Pipeline插件完成docker项目的pipeline流水线发布
  • (附源码)springboot 智能停车场系统 毕业设计065415
  • (一)Spring Cloud 直击微服务作用、架构应用、hystrix降级
  • (一)SvelteKit教程:hello world
  • (转)linux自定义开机启动服务和chkconfig使用方法
  • .md即markdown文件的基本常用编写语法
  • .NET C# 使用GDAL读取FileGDB要素类
  • .net redis定时_一场由fork引发的超时,让我们重新探讨了Redis的抖动问题
  • .net 重复调用webservice_Java RMI 远程调用详解,优劣势说明
  • .vue文件怎么使用_vue调试工具vue-devtools的安装
  • @EnableConfigurationProperties注解使用