2025年2月凉面与热面(2)—— 还没开始就结束了🤡?

前言

这个是二月 20 多号面的 , 首先就是 hr 在面试 ,我不知道说错了什么 ?之后面就凉了 ~ 下面是面经 , 请大家吃面 ~~

可以看出比较偏基础 , 话不多说 , 然我们一起打打基础 。

点赞关注 , 我将持续带来新鲜的面经 ~

html5 新特性 ?

HTML5 是HTML 的第五个版本,是用于创建网页和其他web 应用程序的标记语言。与之前的HTML版本相

比,HTML5引I入了许多新特性和改进,包括以下几个方面:

  • 语义化标签:HTML5引入了很多新的标签,如<header>、<footer>、<nav>、<article>、<section>等,这些标签都是为了更好地表达文档内容的语义而设计的。
  • 多媒体支持:HTML5 支持多媒体内容,包括音频、视频、SVG 和 Canvas 等图形元素,这些都可以直接在网页中嵌入,无需使用第三方插件。
  • 新的表单控件:HTML5引入了一些新的表单控件,如日期选择器、搜索框、滑块等,这些控件都能够提高用户体验。
  • Web 存储:HTML5 提供了两种新的客户端存储机制:localStorage 和 sessionStorage,它们可以让Web应用程序在客户端上存储数据,从而提高性能和用户体验。
  • Web Workers:HTML5 提供了一种新的机制,即WebWorkers,它们可以让Web 应用程序在后台运行,从而提高性能和响应速度。
  • 地理位置支持:HTML5 提供了一种新的 API,即 Geolocation APl,它可以让Web应用程序获取用户的地理位置信息。

HTML5的新特性为Web开发提供了更多的功能和工具,让开发者能够更加方便地开发Web应用程序,并提高用户体验。

浮动 ?

什么是浮动 ?

在网页布局中,浮动(float)是 CSS 的一种属性,用于控制元素在文档流中的位置。当对一个元素设置浮动属性(如 float: left 或 float: right)后,该元素会从正常的文档流中脱离,向左或向右移动,直到碰到包含它的元素或者其他浮动元素的边界 。

浮动原本是为了实现文本环绕图片的效果而设计的,但在实际应用中,常被用于实现多列布局等复杂的页面排版。不过,由于浮动元素脱离文档流,会对周围元素的布局产生影响,比如导致父元素高度塌陷等问题,这就需要使用清除浮动的方法来解决布局紊乱的情况。

清除浮动 ?

清除浮动主要是为了避免由于浮动元素脱离正常文档流而引发的布局问题。当一个元素浮动时,它从普通文档流中脱离,常会影响到其父元素和后续兄弟元素的显示效果,典型问题包括父元素无法包裹浮动元素的高度等。清除浮动是为了解决这些布局上的紊乱问题,确保页面布局按照预期运行。 清除浮动的方式有以下几种:

  1. 使用空的清除浮动元素(clearfix hack)。
  2. 使用伪元素 ::after 清除浮动。
  3. 使用 overflow 属性清除浮动。
  4. 使用 display:flow-root 清除浮动。

扩展知识

  1. 空的清除浮动元素(clearfix hack) :这种方法通过在浮动元素之后插入一个空的拥有 clear 样式的 div,来清除浮动。
css 复制代码
<div class="clearfix"></div>
​
css 复制代码
.clearfix {
    clear: both;
}
  1. 伪元素 ::after 清除浮动:这是比较受欢迎的一种清除浮动方法,通过在父元素的 CSS 规则中添加伪元素 ::after,给它设置 clear: both。
css 复制代码
.clearfix::after {
    content: "";
    display: table;
    clear: both;
}

通常会通过添加一个泛用的 clearfix 类来实现:

css 复制代码
.clearfix::after {
    content: "";
    display: table;
    clear: both;
}
  1. 使用 overflow 属性清除浮动:这个方法利用 CSS 的 overflow 属性让父元素包裹浮动的子元素。这样避免了添加额外的 HTML 元素。
css 复制代码
.container {
    overflow: auto;
}

在某些浏览器中,使用 overflow: hidden 也可以达到同样效果。

  1. 使用 display:flow-root 清除浮动:CSS 的 display: flow-root 属性可以创建一个新的块级格式化上下文(BFC),从而清除浮动。
css 复制代码
.container {
    display: flow-root;
}

这种方法是相对简洁的处理方式,因为它不影响其他样式。

实现移动端适配问题 ?

1. 通过@media实现一套html

@media是CSS3引入的媒体查询功能,它允许网页根据不同设备的特性(如屏幕宽度、高度、分辨率、方向等)应用不同的样式规则。

在一套HTML结构下,使用@media可以这样操作:

css 复制代码
/* 针对屏幕宽度小于600px的设备,比如手机 */
@media (max - width: 600px) {
    body {
        background - color: lightblue;
    }
}
​
/* 针对屏幕宽度在601px到992px之间的设备,比如平板 */
@media (min - width: 601px) and (max - width: 992px) {
    body {
        background - color: lightgreen;
    }
}
​
/* 针对屏幕宽度大于992px的设备,比如桌面电脑 */
@media (min - width: 993px) {
    body {
        background - color: lightyellow;
    }
}

这样,同一个HTML页面在不同宽度的设备上,会呈现不同的背景颜色,实现简单的响应式布局。在实际项目中,会针对不同设备的宽度调整元素的尺寸、位置、排列方式等样式属性。

2. 通过rem或者vw、vh在不同设备有相同比例进而实现适配(以小米移动端商城rem为例)

  • rem:rem是相对于根元素(html元素)的字体大小的单位。在移动端开发中,常根据设备的宽度动态设置html元素的字体大小。例如,在小米移动端商城中,假设设计稿是375px宽度,把html的字体大小设置为100px,那么1rem就等于100px。当元素宽度设计为100px时,在CSS中就可以写成1rem。当设备宽度改变时,通过JavaScript动态调整html的字体大小,从而保证不同设备上元素的相对比例一致。
js 复制代码
(function (doc, win) {
    var docEl = doc.documentElement,
        resizeEvt = 'orientationchange' in window? 'orientationchange' :'resize',
        recalc = function () {
            var clientWidth = docEl.clientWidth;
            if (!clientWidth) return;
            if (clientWidth >= 640) {
                docEl.style.fontSize = '100px';
            } else {
                docEl.style.fontSize = 100 * (clientWidth / 640) + 'px';
            }
        };
    if (!doc.addEventListener) return;
    win.addEventListener(resizeEvt, recalc, false);
    doc.addEventListener('DOMContentLoaded', recalc, false);
})(document, window);
  • vw、vh:vw是视口宽度的1%,vh是视口高度的1% 。使用它们可以实现元素尺寸相对于视口的等比缩放。比如一个元素宽度设置为50vw,那么在任何设备上,它都会占据视口宽度的50%。

3. 同时采用媒体监听和rem等等比适配(王者荣耀官网)

王者荣耀官网结合了媒体查询和rem单位来实现适配。通过媒体查询针对不同设备宽度范围,设置不同的根字体大小基准,然后在布局中使用rem单位定义元素的尺寸、间距等。例如:

css 复制代码
@media (max - width: 768px) {
    html {
        font - size: 14px;
    }
}
@media (min - width: 769px) and (max - width: 1024px) {
    html {
        font - size: 16px;
    }
}
@media (min - width: 1025px) {
    html {
        font - size: 18px;
    }
}
/* 元素使用rem定义尺寸 */
.container {
    width: 10rem;
    height: 5rem;
}

这样在不同设备上,既能根据设备宽度范围调整根字体大小,又能通过rem单位保持元素间的等比关系,从而实现较好的响应式适配效果。

说一说盒子模型 ?

在网页设计中,CSS盒子模型是一种常用的思维模型,它将HTML文档中的元素看作一个个矩形盒子,每个盒子从内到外由内容区(content)、填充(padding)、边框(border)和空白边(margin)四个部分构成。

1. 组成部分

  • 内容区:是盒子的核心,用于呈现文本、图片等主要信息。可通过width和height属性设置其宽度和高度,当内容超出范围时,可使用overflow属性处理,比如设为hidden隐藏溢出部分,visible让溢出部分可见,scroll添加滚动条,auto由浏览器决定处理方式 。
  • 填充:位于内容区和边框之间,用于设置内容与边框的间距,属性包括padding-top(上填充)、padding-bottom(下填充)、padding-left(左填充)、padding-right(右填充),还有快捷属性padding可综合设置。设置背景色时,背景会延伸到填充区域。
  • 边框:环绕在内容区和填充外的边界。属性有border-style(边框样式,如dotted点线、dashed虚线、solid实线等)、border-width(边框宽度,可用长度值或thin、medium、thick表示)、border-color(边框颜色,如rgb值或css规定的颜色名),也有快捷属性border可整体设置。在不同浏览器中,背景色对边框区域的显示可能不同。
  • 空白边:处于盒子最外围,用于分隔不同盒子,是布局的重要手段。属性有margin-top(上外边距)、margin-bottom(下外边距)、margin-left(左外边距)、margin-right(右外边距),以及快捷属性margin。相邻盒子的空白边会取较大值合并,还可设置负空白边值使盒子重叠或移动位置。

2. 盒子模型的定位

  • 文档流:是HTML默认的网页布局模式,也是盒子模型定位的基础。块状元素自上而下排列,内联元素从左到右排列。若不做特殊设置,元素位置由在HTML文档中的顺序决定。
  • 浮动:使元素脱离文档流,产生漂浮效果,生成块级元素,一般需指明宽度。当浮动空间不足时,元素会换行。
  • position定位:常用的有相对定位和绝对定位。相对定位不脱离文档流,以自身左上角为参照进行偏移,原位置仍保留空间;绝对定位则脱离文档流,不占空间,后续元素会填补其空位 。

css 选择器的优先级 ?

CSS选择器优先级用于确定当多个样式规则同时作用于一个元素时,哪个样式规则会生效。具体规则如下:

1. 特异性计算

按照选择器类型给其赋予不同的权重分值,分值越高,优先级越高:

  • 内联样式 :直接写在HTML元素的style属性中的样式,如<div style="color: red;">,权值为1000 。
  • ID选择器 :通过元素的ID来选择,如#header,权值为0100(也可理解为100分)。
  • 类选择器、伪类选择器和属性选择器 :类选择器如.nav ,伪类选择器如:hover,属性选择器如[type="text"],它们的权值均为0010(10分)。
  • 类型选择器和伪元素选择器 :类型选择器如divp,伪元素选择器如::first - line ,权值是0001(1分)。
  • 通配符、子选择器、相邻选择器等 :通配符* ,子选择器> ,相邻选择器+,权值为0000(0分)。
  • 继承的样式:没有权值。即当元素样式是从父元素继承而来时,优先级最低。

2. 源顺序

当两个或多个选择器的特异性相同时,后出现的样式会覆盖先出现的样式。例如在CSS中先后写了如下规则:

css 复制代码
.nav {
    color: blue; 
}
.nav {
    color: red; 
}

那么元素应用的颜色最终会是红色,因为第二条规则在样式表中后出现。

3. !important声明

!important声明可以覆盖所有其他优先级规则,即无论其他选择器权重如何,带有!important声明的样式属性会优先应用。但不建议滥用,因为它会使样式的优先级变得难以追踪和维护,导致代码可读性变差。如:

css 复制代码
.nav {
    color: blue!important; 
}

此时,.nav类元素的颜色将优先显示为蓝色,即使有更高权重的选择器定义了其他颜色。

怎么处理异步 ?

在编程中,处理异步操作是为了应对那些不能立即返回结果的任务,比如网络请求、文件读写、定时器等。以下是常见的几种处理异步的方式:

  1. 回调函数(Callback Functions)

    • 这是最基本的异步处理方式。将一个函数作为参数传递给另一个函数,当异步操作完成时,调用这个回调函数来处理结果。
    • 示例(以JavaScript为例):
js 复制代码
function getData(callback) {
    setTimeout(() => {
        const data = { message: '异步操作完成' };
        callback(data);
    }, 1000);
}

getData((result) => {
    console.log(result);
});
  • 缺点:当存在多个嵌套的异步操作时,会出现"回调地狱"(Callback Hell),代码可读性和维护性变差。
  1. Promise

    • Promise是一种处理异步操作的对象,它代表一个异步操作的最终完成(或失败)及其结果值。
    • 有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。
    • 示例:
js 复制代码
function getData() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            const success = true;
            if (success) {
                const data = { message: '异步操作成功' };
                resolve(data);
            } else {
                reject(new Error('异步操作失败'));
            }
        }, 1000);
    });
}

getData()
   .then((result) => {
        console.log(result);
    })
   .catch((error) => {
        console.error(error);
    });
  • 优点:通过链式调用解决了回调地狱的问题,使代码更加清晰。
  1. async/await

    • 这是基于Promise的语法糖,使得异步代码看起来更像同步代码。
    • async函数总是返回一个Promise对象,await只能在async函数内部使用,用于等待Promise的解决(或拒绝)。
    • 示例:
js 复制代码
async function getData() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            const success = true;
            if (success) {
                const data = { message: '异步操作成功' };
                resolve(data);
            } else {
                reject(new Error('异步操作失败'));
            }
        }, 1000);
    });
}

async function main() {
    try {
        const result = await getData();
        console.log(result);
    } catch (error) {
        console.error(error);
    }
}

main();
  • 优点:代码结构更清晰,可读性强,错误处理也更直观。
  1. 事件发布/订阅模式(Publish/Subscribe Pattern)

    • 定义一个发布者(Publisher)和多个订阅者(Subscriber),当异步操作完成时,发布者发布事件,订阅者接收到事件后执行相应的操作。
    • 示例(以JavaScript为例):
js 复制代码
class EventEmitter {
    constructor() {
        this.events = {};
    }

    on(eventName, callback) {
        if (!this.events[eventName]) {
            this.events[eventName] = [];
        }
        this.events[eventName].push(callback);
    }

    emit(eventName, data) {
        if (this.events[eventName]) {
            this.events[eventName].forEach(callback => callback(data));
        }
    }
}

const emitter = new EventEmitter();

const callback = (data) => {
    console.log('接收到数据:', data);
};

emitter.on('asyncComplete', callback);

setTimeout(() => {
    const data = { message: '异步操作完成' };
    emitter.emit('asyncComplete', data);
}, 1000);
  • 优点:解耦了异步操作和处理逻辑,使得代码的扩展性和维护性更好。

不同的编程语言可能会有不同的语法和实现方式,但这些基本概念在处理异步操作时是通用的。

js 的变量的声明方式

我的文章 :juejin.cn/post/743562... 有详细介绍 ~

在 JavaScript 中,变量的声明方式主要有 varletconst 这三种,它们在作用域、声明提升以及可变性等方面存在一些差异,以下是具体介绍:

  1. var声明变量

    • var 是 JavaScript 早期用于声明变量的关键字。它具有函数作用域或全局作用域,即变量在声明它的函数内部或整个全局范围内有效。
    • 存在声明提升现象,也就是说在代码执行之前,使用 var 声明的变量会被提升到其作用域的顶部,但赋值操作不会提升。
    • 可以多次声明同一个变量,后声明的变量不会报错,会覆盖之前声明的值。
    • 示例:
js 复制代码
console.log(x); // 输出:undefined
var x = 10;
console.log(x); // 输出:10

function example() {
    var y = 20;
    console.log(y); // 输出:20
}
example();
console.log(y); // 报错:y is not defined
  1. let声明变量

    • let 是 ES6 引入的声明变量的关键字,具有块级作用域,即变量只在其所在的代码块(如 {} 包裹的区域)内有效。
    • 不存在像 var 那样的声明提升,在声明变量之前访问该变量会导致 ReferenceError(暂时性死区)。
    • 不允许在同一作用域内重复声明同一个变量,否则会报错。
    • 示例:
js 复制代码
console.log(z); // 报错:ReferenceError: z is not defined
let z = 30;
console.log(z); // 输出:30

{
    let w = 40;
    console.log(w); // 输出:40
}
console.log(w); // 报错:ReferenceError: w is not defined

let a = 50;
// let a = 60; // 报错:Identifier 'a' has already been declared
  1. const 声明变量

    • const 也是 ES6 引入的,用于声明常量,一旦声明,其值就不能被重新赋值。
    • 同样具有块级作用域,存在暂时性死区,在声明之前访问会报错。
    • 不允许在同一作用域内重复声明同一个常量。
    • 需要注意的是,如果 const 声明的是一个对象或数组,虽然不能重新赋值整个对象或数组,但可以修改其内部的属性或元素。
    • 示例:
js 复制代码
const PI = 3.1415926;
// PI = 3.14; // 报错:Assignment to constant variable.
console.log(PI); // 输出:3.1415926

{
    const obj = { name: 'Alice' };
    obj.age = 25;
    console.log(obj); // 输出:{ name: 'Alice', age: 25 }
    // obj = { name: 'Bob' }; // 报错:Assignment to constant variable.
}
console.log(obj); // 报错:ReferenceError: obj is not defined

在实际开发中,应根据变量的使用场景和需求,合理选择 varletconst 来声明变量。

vue 3 组件通信 ?

在 Vue 3 中,组件之间的通信是构建复杂应用的重要部分,常见的通信方式有以下几种:

  1. 父子组件通信
js 复制代码
<!-- 父组件 -->
<template>
    <ChildComponent :message="parentMessage"></ChildComponent>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
    components: {
        ChildComponent
    },
    data() {
        return {
            parentMessage: 'Hello from parent'
        };
    }
};
</script>
<!-- 子组件 -->
<template>
    <p>{{ message }}</p>
</template>
<script>
export default {
    props: {
        message: String
    }
};
</script>
js 复制代码
<!-- 子组件 -->
<template>
    <button @click="sendMessage">Send Message</button>
</template>
<script>
export default {
    methods: {
        sendMessage() {
            this.$emit('childEvent', 'Message from child');
        }
    }
};
</script>
<!-- 父组件 -->
<template>
    <ChildComponent @childEvent="handleChildEvent"></ChildComponent>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
    components: {
        ChildComponent
    },
    methods: {
        handleChildEvent(message) {
            console.log(message);
        }
    }
};
</script>
  • 父传子(props) :父组件通过在子组件标签上绑定属性来传递数据,子组件通过 props 选项来接收。props 可以是简单的数据类型,也可以是对象、数组等复杂类型。子组件不能直接修改 props,若要改变,应通过触发事件通知父组件。
  • 子传父(自定义事件) :子组件通过 $emit 方法触发自定义事件,父组件在使用子组件的标签上监听该事件并定义相应的处理函数。
  1. 兄弟组件通信
js 复制代码
// 创建一个事件总线实例
import mitt from'mitt';
const emitter = mitt();

// 第一个兄弟组件
import { onMounted } from 'vue';
export default {
    setup() {
        onMounted(() => {
            emitter.on('brotherEvent', (data) => {
                console.log('Received from brother:', data);
            });
        });
        return {};
    }
};

// 第二个兄弟组件
import { ref } from 'vue';
export default {
    setup() {
        const sendData = () => {
            emitter.emit('brotherEvent', 'Hello from another brother');
        };
        return {
            sendData
        };
    }
};
  • 兄弟组件之间通常不直接通信,而是通过共同的父组件作为中介。一个兄弟组件通过触发父组件的事件,父组件接收到事件后,再将数据传递给另一个兄弟组件。
  • 也可以使用 mittEventBus 等第三方库来实现兄弟组件间的通信。以 mitt 为例:
  1. 祖孙组件通信
js 复制代码
<!-- 祖先组件 -->
<template>
    <div>
        <GrandChildComponent></GrandChildComponent>
    </div>
</template>
<script>
import GrandChildComponent from './GrandChildComponent.vue';
export default {
    components: {
        GrandChildComponent
    },
    provide() {
        return {
            sharedData: 'This is shared data from ancestor'
        };
    }
};
</script>
<!-- 后代组件 -->
<template>
    <p>{{ sharedData }}</p>
</template>
<script>
export default {
    inject: ['sharedData']
};
</script>

provide/inject :祖先组件通过 provide 选项提供数据,后代组件无论嵌套多深,都可以使用 inject 选项注入并使用这些数据。provideinject 主要用于跨层级传递数据,不适合响应式数据的双向传递。

  • Vuex 或 Pinia:对于大型应用,使用状态管理库(如 Vuex 或 Pinia)来管理共享状态,所有组件都可以访问和修改这些状态,从而实现组件间的通信。

以上是 Vue 3 中常见的组件通信方式,开发者可以根据具体的应用场景选择合适的方法。

vue3 生命周期

在 Vue 3 中,生命周期是指 Vue 实例从创建到销毁的整个过程,在这个过程中会自动调用一些钩子函数,开发者可以在这些钩子函数中编写相应的代码来处理特定阶段的逻辑。以下是 Vue 3 中主要的生命周期钩子函数及其特点:

  1. setup

    • 这是 Vue 3 新增的一个特殊的生命周期钩子,它在创建组件实例,初始化 propscontext 之后,其他生命周期钩子函数之前调用。
    • 它是组合式 API 的入口点,用于设置响应式数据、计算属性、方法等,并且不能访问 this(因为在 setup 执行时,组件实例尚未完全创建)。
    • 示例:
js 复制代码
import { ref } from 'vue';
export default {
    setup() {
        const count = ref(0);
        const increment = () => {
            count.value++;
        };
        return {
            count,
            increment
        };
    }
};
  1. onBeforeMount

    • 在组件即将挂载到 DOM 之前调用。此时,组件的 render 函数已经被调用,但还没有真正将组件渲染到 DOM 中。
    • 可以在这个钩子函数中进行一些初始化操作,比如设置一些数据的初始值等。
    • 示例:
js 复制代码
import { onBeforeMount } from 'vue';
export default {
    setup() {
        onBeforeMount(() => {
            console.log('Component is about to be mounted.');
        });
        return {};
    }
};
  1. onMounted

    • 组件挂载到 DOM 之后调用。在这个钩子函数中,可以访问到已经渲染好的 DOM 元素,常用于执行一些依赖于 DOM 的操作,比如初始化第三方库、获取 DOM 元素的尺寸等。
    • 示例:
js 复制代码
import { onMounted } from 'vue';
export default {
    setup() {
        onMounted(() => {
            const element = document.getElementById('app');
            console.log('Component is mounted, DOM element:', element);
        });
        return {};
    }
};
  1. onBeforeUpdate

    • 在组件数据更新之前调用,此时组件的 propsdata 已经发生了变化,但 DOM 尚未更新。
    • 可以在这个钩子函数中对即将更新的数据进行一些处理或记录。
    • 示例:
js 复制代码
import { ref, onBeforeUpdate } from 'vue';
export default {
    setup() {
        const count = ref(0);
        const increment = () => {
            count.value++;
        };
        onBeforeUpdate(() => {
            console.log('Component is about to update, current count:', count.value);
        });
        return {
            count,
            increment
        };
    }
};
  1. onUpdated

    • 在组件数据更新之后调用,此时 DOM 已经更新完成。可以在这个钩子函数中执行一些依赖于更新后 DOM 的操作,比如重新计算元素的位置等。
    • 示例:
js 复制代码
import { ref, onUpdated } from 'vue';
export default {
    setup() {
        const count = ref(0);
        const increment = () => {
            count.value++;
        };
        onUpdated(() => {
            const element = document.getElementById('count');
            console.log('Component has been updated, DOM element:', element);
        });
        return {
            count,
            increment
        };
    }
};
  1. onBeforeUnmount

    • 在组件即将卸载之前调用。可以在这个钩子函数中进行一些清理工作,比如清除定时器、解绑事件监听器等,以避免内存泄漏。
    • 示例:
js 复制代码
import { onBeforeUnmount } from 'vue';
export default {
    setup() {
        let timer;
        const startTimer = () => {
            timer = setInterval(() => {
                console.log('Timer is running...');
            }, 1000);
        };
        const stopTimer = () => {
            clearInterval(timer);
        };
        onBeforeUnmount(() => {
            stopTimer();
            console.log('Component is about to be unmounted.');
        });
        return {
            startTimer
        };
    }
};
  1. onUnmounted

    • 组件卸载之后调用。此时组件实例已经被销毁,相关的 DOM 元素也已从文档中移除。
    • 示例:
js 复制代码
import { onUnmounted } from 'vue';
export default {
    setup() {
        onUnmounted(() => {
            console.log('Component has been unmounted.');
        });
        return {};
    }
};
  1. onErrorCaptured

    • 当捕获到后代组件抛出的错误时调用。可以在这个钩子函数中进行错误处理,比如记录错误信息、显示错误提示等。
    • 示例:
js 复制代码
import { onErrorCaptured } from 'vue';
export default {
    setup() {
        onErrorCaptured((error, instance, info) => {
            console.log('Error captured:', error);
            console.log('Component instance:', instance);
            console.log('Error info:', info);
            return true; // 阻止错误继续向上传播
        });
        return {};
    }
};

这些生命周期钩子函数为开发者提供了在组件不同阶段执行自定义逻辑的能力,合理使用它们可以更好地管理组件的状态和行为。

router 和 route 的区别 ?

在 Vue Router(Vue.js 应用的路由管理器)中,routerroute 是两个不同但又相关的概念,它们的主要区别如下:

  1. 概念含义
  • routerrouter 是一个全局的路由实例对象,它是 Vue Router 的核心实例,负责整个应用的路由管理。它包含了路由的配置信息、路由的跳转方法、路由的钩子函数等。可以把它看作是一个"路由引擎",负责处理所有与路由相关的操作,比如导航到不同的路由地址、监听路由的变化等。 - routeroute 表示当前激活的路由信息对象,它包含了当前路由的路径、参数、查询参数、匹配的组件等信息。每一个路由匹配成功后,都会生成一个对应的 route 对象,并且这个对象会随着路由的变化而更新。
  1. 使用场景和作用
  • router:在应用中,通常在创建 Vue 实例时配置和使用 router。例如,使用 router.push() 方法进行编程式导航,实现页面的跳转;使用 router.beforeEach() 等全局钩子函数来进行导航守卫,在路由跳转前进行权限验证、登录状态检查等操作。
js 复制代码
import { createRouter, createWebHistory } from 'vue-router';
import Home from './views/Home.vue';
import About from './views/About.vue';

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home
  },
  {
    path: '/about',
    name: 'About',
    component: About
  }
];

const router = createRouter({
  history: createWebHistory(),
  routes
});

router.beforeEach((to, from, next) => {
  // 进行权限验证等操作
  next();
});

export default router;

route :在组件中,可以通过 this.$route(在选项式 API 中)或 useRoute()(在组合式 API 中)来访问当前的 route 对象。例如,获取当前路由的参数值用于数据展示或进一步的逻辑处理。

js 复制代码
// 选项式 API
export default {
  computed: {
    currentRouteParams() {
      return this.$route.params;
    }
  }
};

// 组合式 API
import { useRoute } from 'vue-router';
export default {
  setup() {
    const route = useRoute();
    const currentRouteParams = route.params;
    return {
      currentRouteParams
    };
  }
};
  1. 数据内容
  • router:包含了路由的配置数组(routes)、路由的历史记录模式(如 createWebHistorycreateWebHashHistory)等信息,以及一系列用于操作路由的方法和钩子函数。 - route:包含 path(当前路由的路径)、params(路由参数)、query(查询参数)、matched(匹配到的路由记录数组)等属性,反映了当前路由的具体状态和信息。

总之,router 是管理整个应用路由的核心对象,而 route 则是表示当前激活路由的具体信息对象,二者在 Vue Router 中扮演着不同但又相互配合的角色。

总结

金 3 银 4 快来了 , 兄弟们 Are you ready ?🤡👈

相关推荐
黄毛火烧雪下4 分钟前
React Context API 用于在组件树中共享全局状态
前端·javascript·react.js
Apifox14 分钟前
如何在 Apifox 中通过 CLI 运行包含云端数据库连接配置的测试场景
前端·后端·程序员
一张假钞17 分钟前
Firefox默认在新标签页打开收藏栏链接
前端·firefox
高达可以过山车不行17 分钟前
Firefox账号同步书签不一致(火狐浏览器书签同步不一致)
前端·firefox
m0_5937581018 分钟前
firefox 136.0.4版本离线安装MarkDown插件
前端·firefox
掘金一周21 分钟前
金石焕新程 >> 瓜分万元现金大奖征文活动即将回归 | 掘金一周 4.3
前端·人工智能·后端
三翼鸟数字化技术团队40 分钟前
Vue自定义指令最佳实践教程
前端·vue.js
uhakadotcom43 分钟前
构建高效自动翻译工作流:技术与实践
后端·面试·github
Jasmin Tin Wei1 小时前
蓝桥杯 web 学海无涯(axios、ecahrts)版本二
前端·蓝桥杯
圈圈编码1 小时前
Spring Task 定时任务
java·前端·spring