前端学习8 Vue2 和 Vue3

1.生命周期

对于生命周期来说,整体上变化不大,只是大部分生命周期钩子名称上 + “on”,功能上是类似的。不过有一点需要注意,Vue3 在组合式API(Composition API,下面展开)中使用生命周期钩子时需要先引入,而 Vue2 在选项API(Options API)中可以直接调用生命周期钩子。

import { onMounted } from 'vue';   // 使用前需引入生命周期钩子
// 可将不同的逻辑拆开成多个onMounted,依然按顺序执行,不会被覆盖
onMounted(() => {
  // ...
});
Vue2 Vue3
beforeCreate() setup()
created() setup()
beforeMount() onBeforeAMount()
mounted() onMounted()
beforeUpdate() onBeforeUpdate()
undated() onUpdated()
beforeDestroy() onBeforeunmount()
destroyed() onUnmounted()

2.API

Vue2是选项API(Options API),一个逻辑会散乱在文件不同位置(data、props、computed、watch、生命周期钩子等),导致代码的可读性变差。当需要修改某个逻辑时,需要上下来回跳转文件位置。

Vue3组合式API(Composition API)则很好地解决了这个问题,可将同一逻辑的内容写到一起,增强了代码的可读性、内聚性,其还提供了较为完美的逻辑复用性方案。所有逻辑在setup函数中,使用 ref、watch 等函数组织代码。

3.setup函数

setup函数是组合式API的入口函数,默认导出配置选项,setup函数声明,返回模板需要数据与函数。

1.setup 函数是 Vue3 特有的选项,作为组合式API的起点

2.从组件生命周期看,它在 beforeCreate 之前执行

3.函数中 this 不是组件实例,是 undefined

4.如果数据或者函数在模板中使用,需要在 setup 返回

5.今后在vue3的项目中几乎用不到 this , 所有的东西通过函数获取。

4.响应式系统

Vue的响应式系统是其核心特性之一,它使得Vue能够智能地追踪数据变化并自动更新视图。Vue的响应式系统基于JavaScript对象的getter和setter属性,通过这些属性,Vue能够在数据变化时通知并更新视图。

Vue2通过Object.defineProperty来实现,vue3通过Proxy来实现数据劫持。数据劫持允许Vue监听数据的变化,当数据发生变化时,Vue会执行与数据相关的视图更新。

4.1 Object.defineProperty

通过递归遍历对象的每个属性,为每个属性设置 getter 和 setter,拦截属性的读取和修改操作。

object.defineProperty允许你定义或修改对象上的一个属性,并且可以指定该属性的访问器方法(getter和setter)。当属性被读取或设置时,相应的getter或setter将被调用。

所以他的缺点就是1.无法监听到数组的变化。2.必须遍历对象的每个属性。3.必须深层遍历嵌套的对象。

4.2 proxy

proxy创建一个对象的代理,拦截并自定义对象的基本操作(如属性访问、赋值、删除等),无需递归遍历。

ES6 原生提供 Proxy 构造函数,用来生成 Proxy 实例。

var proxy = new Proxy(target, handler);

// target 表示所要拦截的目标对象(任何类型的对象,包括原生数组,函数,甚至另一个代理))

// handler 通常以函数作为属性的对象,各属性中的函数分别定义了在执行各种操作时代理的行为

proxy主要使用的函数有以下几种:

get(target,propkey,receiver) 拦截对象属性的读取;

set(target,propkey,value,receiver) 拦截对象属性的设置;

deleteProperty(target,propKey):拦截delete proxy[propKey]的操作,返回一个布尔值;

4.2.1 get()

get()接受三个参数,依次为目标对象、属性名和 proxy 实例本身,最后一个参数可选。

var person = {
  name: "张三"
};

var proxy = new Proxy(person, {
  get: function(target, propKey) {
    return Reflect.get(target,propKey)
  }
});

proxy.name // "张三"

4.2.2 set()

set方法用来拦截某个属性的赋值操作,可以接受四个参数,依次为目标对象、属性名、属性值和 Proxy 实例本身。

其必须返回布尔值,表示是否成功删除。

// 创建一个普通用户对象
const user = {
  name: "John",
  age: 25
};

// 定义 Proxy 的处理器对象,包含 set 捕获器
const handler = {
  set(target, property, value, receiver) {
    // 1. 对 age 属性进行验证
    if (property === 'age') {
      if (typeof value !== 'number') {
        throw new TypeError('年龄必须是一个数字');
      }
      if (value < 0) {
        throw new RangeError('年龄不能为负数');
      }
      if (value > 150) {
        throw new RangeError('年龄不能超过 150');
      }
    }

    // 2. 合法时更新属性
    const result = Reflect.set(target, property, value, receiver);

    // 3. 记录变更日志
    console.log(`属性 ${property} 被设置为 ${value}`);
    
    return result; // 返回操作结果(布尔值)
  }
};

// 创建代理对象
const userProxy = new Proxy(user, handler);

// 测试合法操作
userProxy.age = 30; 
// 输出: "属性 age 被设置为 30"
console.log(userProxy.age); // 输出: 30

// 测试非法操作
try {
  userProxy.age = -5; // 抛出 RangeError
} catch (error) {
  console.error(error.message); // 输出: "年龄不能为负数"
}

try {
  userProxy.age = "thirty"; // 抛出 TypeError
} catch (error) {
  console.error(error.message); // 输出: "年龄必须是一个数字"
}

4.2.3 deleteProperty()

deleteProperty 是 JavaScript Proxy 对象的一个捕获器(trap),用于拦截对对象属性的 delete 操作。

const target = { id: 1, name: "John", role: "admin" };

const handler = {
  deleteProperty(target, property) {
    if (property === 'id') {
      throw new Error('禁止删除 id 属性');
    }
    return Reflect.deleteProperty(target, property);
  }
};

const proxy = new Proxy(target, handler);

// 正常删除
delete proxy.name; // 成功,target 变为 { id: 1, role: "admin" }

// 尝试删除 id
try {
  delete proxy.id; // 抛出错误:禁止删除 id 属性
} catch (error) {
  console.error(error.message);
}

5.多根节点

Vue2只能存在一个根节点,需要用一个div来包裹;Vue3 支持多个根节点,也就是 fragment。

// Vue2只能存在一个根节点,需要用一个<div>来包裹着
<template>
  <div>
    <header></header>
    <main></main>
    <footer></footer>
  </div>
</template>
 
// Vue3支持多个根节点
<template>
  <header></header>
  <main></main>
  <footer></footer>
</template>
#前端##前端入门#
全部评论

相关推荐

海投的一大弊端是,当hr给你打电话邀面的时候,你根本不记得你投了哪个岗位,很有可能出现两个招聘软件,同一岗位重复投递的情况。以及,有些岗位可能根本不招人了但依旧没有下架,所以在投递的时候,除了观察面试官在线状态外,还要看一下岗位的截止时间(实习僧app可看)、面试官的回复情况(boss直聘氪金可看)。如果只是对你“已读不回”那多半是自己的问题,但如果对所有人“一视同仁”,那就放弃这个岗位吧。我们可以搞个简历(面试)投递表,来记录自己投了哪个公司的哪个岗位,是否面邀与面试通过率。and,面试记得录音,不复盘的面试是无效面试,你根本不知道自己哪里答得好,哪里答得差。喜欢帅哥美女是人之常情,面试官自然也不例外。在面试表现差不多的情况下,面试官更倾向于选养眼的实习生,所以面试前最好化个妆。对于刚开始面试,或很久没有面试的人来说,当同一天恰巧有多场面试的时候,最好提前和hr说好,把小公司的面试安排到上午,大公司的面试安排到下午。这样,有了上午的练手,下午的面试通过率会更高。面多了就会发现,其实有一些常见题型,必须提前写稿背熟(画思维导图也行),你眼中的答得好不一定加分,但答得不好一定扣分。在简历里或在自我介绍、项目环节提前埋点或留白,引导面试官提问你,比如你申请新媒体运营相关岗位,面试官大概率会对你做出15w浏览的爆款内容感兴趣。因为面试官可能没看你简历,所以咱在自我介绍时,要按照简历顺序,讲一下简历的精华部分,在哪几个厂有过目标岗位的相关实习,每个厂做什么项目,先说产品形态/功能是什么样,再说背景、目标、动作、结果。个人评价要体现和面试岗位的匹配性。短视频讲究开头吸睛,自我介绍更是如此,面试官对你的第一印象很可能决定成败。自我介绍不要平铺直叙,比如“我从学历,实习,项目经历,自我评价四个方面进行介绍。首先是学历,我叫xx,xx专业大几,来自xx大学……”网上都是这种清一色的自我介绍模板,虽然按照star法则来,但还是好奇怪,缺乏亮点。咱们可以这样来,把自己的经历分成几个阶段,向面试官展示自己在各阶段打怪升级的过程,先学习了啥,后做了啥,比如:“面试官老师您好,我是xx,来自xx大学,xx专业大几,下面我来从三个阶段向您介绍一下我:第一个阶段是数据探索期,出于对数据的好奇,我去主动学习了SQL与数据看板的制作,在课上也学到了Python和R。刚开始我在用VLOOKUP函数和数据透视表处理数据,后面也接到了抖音矩阵号分析case,结合数据与业务制定策略……老师您看下您对哪个阶段感兴趣,我来给您着重讲一下。”你看,结尾这句“老师您看下您对哪个阶段感兴趣,我来给您着重讲一下。”不就是把主动权拉回到自身,在引导面试官顺着你的节奏来吗?如果单纯按照面试官一问一答,更像是应激反应,因为你保不准面试官会问啥。同样,项目也不是讲得越详细越好,很可能面试官对你之前的业务方向压根不了解,你的“大白话”面试官不一定能听懂,或者让他觉得信息过载,觉得你不会抓重点。一面面试官通常是你的mentor,面试官不是专业面试官,是抽空来面你的,他可能因为开会迟到。工作需要注意力高度集中,已经够忙了,倘若这时你再让他费力地听你讲话,他有可能不耐烦。记得密切关注面试官的表情变化,当觉察到对方脸上出现不耐烦的态度时,挑重点尽快收尾才是明智之举。不要在面试中暴露自己的任何缺点,自谦和老实有时反而是件坏事。如果面试官问你缺点的时候,可以说一些无伤大雅的缺点,比如“学生思维”“完美主义”。如果你敢说自己“拖延症患者”“multi-tasking能力差”,凉的概率更大。到了反问环节,不要“没问题”,这样面试官可能会觉得你是“海王”,或对面试的公司根本不感兴趣,问一下“面试官对实习生的能力期待”“面试官对业务线的理解”也好嘛,就算面过了,也能快速判断公司是否适合自己。&nbsp;&nbsp;
勇敢的牛肉丸面试中:真不容易,能看到产品这些非技术的干货
点赞 评论 收藏
分享
评论
2
5
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务