面试官:sessionStorage 能在多个标签页之间共享数据吗?
结论:不能,但是可以通过 window.open() 或者 a 标签(target 不为_blank)的形式打开新标签,这时候可以共享sessionStorage。
结论:不能,但是可以通过 window.open() 或者 a 标签(target 不为_blank)的形式打开新标签,这时候可以共享sessionStorage。
参考链接:Vue3 模态类(Model)封装方案 - 实践参考链接:Vue3丨TS丨7 个思路封装一个灵活的 Modal 对话框
大文件上传和断点续传的流程前端大文件上传和断点续传的流程通常包括以下步骤:选择文件: 用户在前端界面选择要上传的大文件。计算文件哈希: 为了唯一标识文件并实现断点续传,前端通常会使用文件内容的哈希值作为文件的标识符。通过计算文件内容的哈希值,可以确保同一文件内容生成的哈希值是相同的,从而方便后续的断点续传。查询已上传的文件块: 在继续上传之前,前端会发送一个查询已上传文件块的请求到后端。这个请求用于获取已经上传成功的文件块列表,以便在继续上传时跳过已上传的部分。分块上传: 前端将大文件分割成多个块,并逐个上传到后端。通常情况下,每个文件块的大小是固定的,并且文件块的数量根据文件大小来确定...
基本原理远程桌面的实现原理基本上是将被控制端的屏幕图像和用户输入传输到控制端,并在控制端模拟用户的操作,从而实现远程控制的目的。具体实现原理取决于所使用的远程桌面协议和技术,以下是一般的工作流程:1. 图形渲染和捕获被控制端的桌面环境会不断渲染图像,并且需要定期捕获并发送这些图像到控制端。这一过程通常由一个特定的软件或驱动程序来完成,用于捕获屏幕上的图像并将其编码为适合传输的格式。2. 用户输入捕获控制端需要捕获用户在控制端的输入,例如键盘输入、鼠标移动和点击等。这些输入需要通过网络传输到被控制端,并模拟成真实的用户操作。3. 数据传输被控制端捕获的图像数据和控制端的用户输入会通过网络传...
搭建一个 npm 私服可以让团队或组织内部更好地管理和共享 JavaScript 包。以下是搭建 npm 私服的步骤:1. 选择适合的 npm 私服工具有几个常用的 npm 私服工具可供选择,其中最流行的是 Sinopia、Verdaccio 和 Nexus Repository。它们都提供了类似的功能,但在配置和使用方面可能会有些差异。你可以根据自己的需求和偏好选择其中一个。2. 安装和配置选择好工具后,按照官方文档或社区指南进行安装和配置。通常情况下,你需要通过 npm 安装相应的工具,然后运行一些配置命令来设置私服。3. 启动私服安装和配置完成后,通过运行相应的命令来启动私服服务。...
分别是什么作用在 npm 中,dependencies、devDependencies 和 peerDependencies 是用来管理项目依赖的三个重要字段。dependencies:dependencies 字段用于指定项目运行时所依赖的模块。这些模块会被安装到 node_modules 目录下,并且会被打包到生产环境的构建文件中。通常包含的是项目运行时必需的依赖项,如框架、库等。devDependencies:devDependencies 字段用于指定项目开发时所依赖的模块。这些模块不会被打包到生产环境的构建文件中,而是只会被安装到开发环境中。通常包含的是项目构建、测试、打包等开...
区别在 TypeScript 中,unknown 和 any 都是用来表示不确定类型的。它们之间的主要区别在于类型安全性和类型推断。类型安全性:unknown 类型是 TypeScript 中的顶级类型,表示任何类型的值。但是,使用 unknown 类型时,需要在使用前进行类型检查或者类型断言来明确其类型。因为 TypeScript 无法自动推断出 unknown 类型的具体类型信息,所以使用 unknown 类型会更安全,因为它强制进行类型检查。any 类型则是 TypeScript 中的另一个顶级类型,表示任何类型的值,且不进行类型检查。使用 any 类型会降低类型安全性,因为它不会...
参考链接:react+vue2+vue3 diff算法分析及比较原理分别是什么1. react-diff: 递增法移动节点:移动的节点称为α,将α对应的真实的DOM节点移动到,α在新列表中的前一个VNode对应的真实DOM的后面添加节点:在新列表中有全新的VNode节点,在旧列表中找不到的节点需要添加(通过find这个布尔值来查找)移除节点:当旧的节点不在新列表中时,我们就将其对应的DOM节点移除(通过key来查找确定是否删除)不足:从头到尾单边比较,容易增加比较次数2. vue2-diff: 双端比较DOM节点什么时候需要移动和如何移动,总结如下:头-头:不移动尾-尾:不移动头-尾: ...
源码:export function triggerEffects( dep: Dep | ReactiveEffect[], debuggerEventExtraInfo?: DebuggerEventExtraInfo ) { // spread into array for stabilization const effects = isArray(dep) ? dep : [...dep] for (const effect of effects) { if (effect.computed) { triggerEffect(effect,...
参考链接:🥇🥇🥇一文带你打通微前端-qiankun/microapp/icestark/wujie全解析参考链接:2023微前端技术方案选型参考链接:微前端(无界)参考链接:微前端参考链接:从零到一实现企业级微前端框架,保姆级教学
1、轮询打包后的 index.html,比较生成的 js 文件的 hash项目打包后,index.html 会包含打包后的 js 文件,这些文件的文件名包含的 hash 将会和上一次打包的不同,比较 hash 也就能判断是否有版本更新;let firstV = [] //记录初始获得的 script 文件字符串 let currentv = [] //记录当前获得的 script 文件字符串 // 获得的文件字符串类似这样 `<script src="/js/chunk-vendors.1234fff.js"></script>` asyn...
ETag(实体标签)和Last-Modified(最后修改时间)是HTTP协议中用于缓存控制的两种机制,它们都用于标识资源的版本信息,但有一些区别:ETag:ETag是服务器为每个资源生成的唯一标识符,通常是资源内容的哈希值或者一些其他算法生成的字符串。当客户端发起请求时,服务器会在响应头中返回该资源的ETag值。客户端再次请求该资源时,可以将上次获取的ETag值放在请求头的If-None-Match字段中,服务器会根据If-None-Match字段中的ETag值来判断资源是否发生了变化,如果没有变化,服务器返回状态码304(Not Modified),客户端直接从缓存中获取资源。Las...
Web Components 是什么Web Components 是一组现代的 Web 平台 API,用于在 Web 应用程序中创建可重用的自定义组件。它由一系列技术组成,包括自定义元素、Shadow DOM、HTML Templates 和 HTML Imports 等,这些技术结合在一起可以让开发者创建独立、可重用、可移植的 Web 组件。具体来说,Web Components 的核心技术包括:Custom Elements(自定义元素): 允许开发者定义自己的 HTML 元素,以及定义这些元素的行为和样式。通过自定义元素,开发者可以创建属于自己的、具有特定功能的 HTML 元素,使...
区别CommonJS(简称CJS)和 ES Modules(简称ESM)是两种不同的模块系统,它们在定义、导出、导入和加载模块时有一些区别。语法差异:CommonJS 使用 require() 来导入模块,使用 module.exports 或 exports 来导出模块。ES Modules 使用 import 和 export 语句来导入和导出模块。加载时机:CommonJS 模块是动态加载的,即在运行时加载并执行模块代码。ES Modules 是静态加载的,模块会在编译时就进行解析和加载。导出方式:CommonJS 的导出是一种“值拷贝”,即模块导出的值在导入模块中是一份新的拷贝。...
Tree shaking 是一种优化 JavaScript 代码的技术,其主要目的是消除未使用的代码(dead code),以减少最终打包文件的体积。在 JavaScript 生态中,Tree shaking 主要与模块化打包工具(如Webpack、Rollup等)结合使用。Tree shaking 的原理基于静态代码分析。它通过分析模块之间的依赖关系和导出关系,以及对代码的静态分析,来确定哪些代码不会被执行,进而将这些无用代码从最终打包结果中剔除。具体来说,Tree shaking 的原理如下:静态分析模块依赖: 模块化打包工具首先会对入口文件进行静态分析,构建模块之间的依赖关系图(d...
Composition API 和 Vue 2.x 中的 Options API 有几个显著的不同点:组织代码的方式:Options API: 使用选项对象来组织组件的选项,例如 data、methods、computed、watch 等,将相关功能分散在不同的选项中。Composition API: 使用函数来组织代码,可以根据逻辑关系将相关代码放在一起,提高了代码的可读性和可维护性。代码复用:Options API: 通过 mixins、extends 等方式实现代码复用,但可能导致命名冲突、逻辑不清晰等问题。Composition API: 使用函数来定义逻辑,可以更灵活地实现代码...
使用 Proxy API 相比 Object.defineProperty API 有以下优势:更直观和简洁:Proxy API 提供了更简单和直观的语法,使得代码更易于理解和维护。支持数组的监听:Proxy API 可以直接监听数组的变化,而 Object.defineProperty API 需要额外处理数组的变化。支持深层对象的监听:Proxy API 可以监听深层嵌套对象的变化,而 Object.defineProperty API 需要递归定义属性。可以监听更多操作:Proxy API 支持监听属性的操作包括 get、set、delete、has 等,而 Object.defi...
当谈论 Vue 3 中的性能优化时,我们可以更加深入地探讨每个方面的具体实现和优势:虚拟 DOM 优化:Vue 3 中的虚拟 DOM 经过重构和优化,内部数据结构更简洁高效,减少了不必要的对象创建和比较操作,从而提高了渲染性能。引入了静态树提升技术,即在编译阶段识别出静态节点,将其标记为静态,并在渲染时跳过对这些节点的比较和更新,从而减少了渲染开销。编译优化:Vue 3 的编译器经过重构,采用了更加高效的编译策略,可以更快地将模板编译为渲染函数。引入了模板静态分析技术,通过静态分析模板,识别出其中的静态节点和动态节点,减少了不必要的计算和更新操作,提高了编译效率和性能。Tree-shak...
Composition API:Vue 3 引入了 Composition API,这是一个基于函数的 API,使得组件逻辑更加灵活和可复用。Vue 2 使用的是选项式 API,适合简单的组件逻辑,但是对于复杂的组件,选项式 API 可能会导致代码结构混乱和难以维护。Composition API 可以将相关的逻辑组织在一起,提高了代码的可读性和可维护性,同时也更容易进行单元测试和代码重用。Teleport(传送门):Vue 3 引入了 Teleport 组件,可以将组件的内容渲染到任意的 DOM 节点中,这在创建模态框、下拉菜单等组件时非常有用。Vue 2 中可以通过使用 portal...
在Vue项目中处理错误通常涉及以下几个方面:1. 全局错误处理可以使用Vue的全局错误处理函数来捕获整个应用范围内的错误。可以通过Vue的 config.errorHandler 或者 Vue.config.errorHandler 来配置全局错误处理函数。这个函数接收三个参数:错误对象、错误信息和Vue实例。你可以在这个函数中处理错误的记录、报警、展示等逻辑。Vue.config.errorHandler = function (err, vm, info) { // 处理错误 console.error('全局错误:', err, info); };2. 组件内错误处...
路由配置问题: SPA 使用前端路由来控制页面导航,而不是通过传统的页面跳转。如果 Nginx 配置不正确,无法正确处理前端路由,就会导致部分页面无法访问,出现404错误。需要在 Nginx 的配置中设置对于前端路由的转发规则,确保所有页面 都被正确导向到入口文件(比如 index.html),由前端路由来处理。
权限控制在前端项目中通常涉及接口权限、路由权限、菜单权限和按钮权限等方面。下面我将详细说明每个方面的权限控制实现方法:接口权限控制在前端项目中,接口权限控制通常指的是根据用户角色或权限级别限制用户对特定接口的访问权限。以下是实现接口权限控制的一般步骤:后端接口权限设计: 后端根据业务需求设计接口权限,通常在接口的请求头或请求参数中携带用户的认证信息或角色信息。前端接口请求拦截: 前端通过axios等工具拦截所有接口请求,在请求发送前进行权限验证,验证通过后才发送请求,否则拒绝发送请求或者跳转到错误页面。处理请求结果: 在接收到接口的响应结果后,根据后端返回的状态码或响应数据进行相应的处理...
在划分大型Vue或React项目的目录结构时,可以遵循一些通用的最佳实践,以提高项目的可维护性、可扩展性和可读性。以下是一个通用的目录结构示例:project/ │ ├── public/ # 公共资源目录 │ ├── index.html # 入口 HTML 文件 │ └── favicon.ico # 网站图标 │ ├── src/ # 源代码目录 │ ├── assets/ # 静态资源文件 │ │ ├── images/ ...
为什么用SSR优势:SEO优化: 由于搜索引擎爬虫在渲染页面时可以直接获取到HTML内容,因此能够更好地理解页面内容,有利于SEO优化。首屏加载性能: SSR能够提供更快的首屏加载速度,因为用户在接收到HTML内容后就可以开始渲染页面,而不需要等待JavaScript的下载和执行。更好的用户体验: 用户在等待JavaScript下载和执行的过程中可能会感到页面加载速度慢,使用SSR能够提供更好的用户体验,尤其是对于低网速或低性能设备的用户。有利于浏览器缓存: 由于SSR返回的是完整的HTML页面,可以更容易地利用浏览器缓存来提升页面加载速度。使用SSR会有什么问题服务器负载增加: SSR...
// 创建一个简易的axios类 class Axios { constructor() { // 初始化拦截器对象,包含请求拦截器和响应拦截器 this.interceptors = { request: [], response: [] }; } // 发送请求的方法 async request(config) { // 创建一个AbortController对象 const controller = new AbortController(); // 获取AbortController的信号对...
为什么封装封装 Axios 的目的主要有以下几点:简化 HTTP 请求操作:Axios 提供了简洁且易于使用的 API,使得发送 HTTP 请求变得更加方便和直观。通过封装 Axios,可以进一步简化 HTTP 请求的操作,提高开发效率。统一配置和处理:通过封装 Axios,可以在一个地方统一配置请求的默认参数、拦截器、错误处理等,使得整个项目的请求逻辑更加统一和规范。这样可以避免在每个请求中都进行重复的配置和处理。提供额外功能:封装 Axios 还可以为项目提供额外的功能,例如请求的 loading 状态、请求超时处理、请求重试机制等。这些功能可以在封装的过程中添加到 Axios 实例...
什么是虚拟dom虚拟 DOM(Virtual DOM)是一个 JavaScript 对象,它是对真实 DOM 的一种轻量级表示。虚拟 DOM 是由 React 框架引入的概念,后来被其他框架如 Vue、Angular 等广泛采用。虚拟 DOM 的存在有以下几个主要原因:性能优化:DOM 操作是相对昂贵的操作,频繁地进行 DOM 更新会导致性能下降。而虚拟 DOM 可以在内存中进行操作,通过批量更新真实 DOM,减少了对真实 DOM 的频繁操作,从而提升了性能。跨平台兼容性:虚拟 DOM 的概念使得前端框架可以在不同的平台上工作,因为底层的 DOM 操作被框架封装了起来,与平台无关。方便的...
表单防止重复提交// 1.设置v-throttle自定义指令 Vue.directive('throttle', { bind: (el, binding) => { let throttleTime = binding.value; // 节流时间 if (!throttleTime) { // 用户若不设置节流时间,则默认2s throttleTime = 2000; } let cbFun; el.addEventListener('click', event => { if (!cbFun) { //...
Vue.js 中常用的修饰符有以下几种:1. .prevent:阻止默认事件的触发。<a v-on:click.prevent="handleClick">点击我不会跳转</a>2. .stop:阻止事件冒泡。<div v-on:click.stop="handleClick">点击我不会触发父元素的点击事件</div>3. .once:只触发一次事件,之后移除监听器。<button v-on:click.once="handleClick">点击我只会触发一次<...
缓存与更新Vue 中可以通过 <keep-alive> 组件来缓存组件。<keep-alive> 会缓存其内部的组件树,而不是销毁它们。当组件在 <keep-alive> 内部切换时,不会触发销毁和重新创建,而是会触发相应的生命周期钩子。要使用 <keep-alive> 缓存组件,只需将需要缓存的组件包裹在 <keep-alive> 标签内部即可。例如:<template> <div> <keep-alive> <component :is="curre...
省流:使对象变成响应式,类似于Vuex,比Vuex更轻量定义state// 引入vue import Vue from 'vue // 创建state对象,使用observable让state对象可响应 export let state = Vue.observable({ name: '张三', 'age': 38 }) // 创建对应的方法 export let mutations = { changeName(name) { state.name = name }, setAge(age) { state.age = age } }直接使用&...
在 Vue 中,有三种类型的插槽:默认插槽(Default Slot):如果组件没有具名插槽,那么任何没有被包裹在具名插槽中的内容都会被传入到组件的默认插槽中。默认插槽在父组件中以普通的 HTML 或其他 Vue 组件的形式被传入。具名插槽(Named Slot):具名插槽允许您在父组件中使用特定的插槽名称,以便将内容传递到子组件的指定插槽中。这种方式让您可以更精细地控制父组件中的内容如何分发到子组件的不同插槽中,提高了组件的灵活性和可重用性。作用域插槽(Scoped Slot):作用域插槽允许子组件将数据传递到父组件中,并且可以在父组件中使用该数据进行渲染。它们允许父组件在插槽内容中使...
在Vue中,Mixin 是一种可重用的组件选项,它允许你在多个组件之间共享一些通用的功能或逻辑。Mixin 将一组选项合并到一个组件中,可以包括 data、methods、computed、watch 等选项。应用场景包括但不限于:代码复用: 如果有一些功能在多个组件中需要使用,可以将这些功能提取为一个Mixin,并在需要的组件中引入使用,从而避免代码重复。跨组件通用逻辑: 当多个组件需要共享一些通用的逻辑时,可以将这些逻辑提取到Mixin中,以便在多个组件中复用。扩展框架功能: 可以使用Mixin扩展Vue框架的功能,比如添加全局的方法、指令、过滤器等。增强组件功能: 可以使用Mixi...
以下代码打印什么?<template> <div class="demo"> <p class="name">{{ name }}</p> <button @click="modify">修改</button> </div> </template> <script lang="ts" setup> const name = ref("111"); const...
原理在 Vue 源码中,nextTick 方法的实现是基于异步任务队列和微任务队列的机制。下面是其大致实现原理:首先,Vue 使用了一个数组 callbacks 来存储 nextTick 方法传入的回调函数。当调用 nextTick 方法时,将传入的回调函数推入 callbacks 数组中。Vue 利用异步任务队列(如 setTimeout 或 setImmediate)或微任务队列(如 Promise 或 MutationObserver)的机制来确保回调函数在 DOM 更新之后执行。在异步任务队列或微任务队列中,Vue 会执行一个任务函数,该任务函数遍历 callbacks 数组,并...
原代码<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Simple Vue</title> </head> <body> <div id=&quo...
1. Props/Events(父子组件通信):父组件通过 Props 向子组件传递数据,子组件通过 Events 向父组件发送消息。父组件:<template> <ChildComponent :message="parentMessage" @notify="handleNotify" /> </template> <script> import ChildComponent from './ChildComponent.vue'; export default { component...
Vue2在 Vue.js 中编写插件通常需要遵循以下步骤:创建插件:创建一个 JavaScript 文件,编写你的插件代码。定义插件:在插件代码中,定义一个对象或者函数作为你的插件。实现插件功能:在插件对象或者函数中实现你的插件功能,可以包括全局组件、指令、过滤器、混入等。注册插件:使用 Vue.use() 方法注册你的插件。下面是一个简单的示例,演示了如何编写一个 Vue 插件:// 定义插件 const MyPlugin = { install(Vue, options) { // 添加全局方法或者属性 Vue.myGlobalMethod = function ...
当动态给 Vue 的 data 添加一个新的属性时,页面不会刷新的原因是因为 Vue 不会自动检测到新属性的添加并触发视图更新。Vue 实例在初始化时会对 data 中的属性进行响应式处理,但对于在实例创建后动态添加的属性,并不会被 Vue 实例所追踪。解决这个问题的方法是使用 Vue.set 方法或者 this.$set 方法来添加新属性。这两个方法可以确保新添加的属性被 Vue 实例正确地响应式追踪,从而触发视图更新。另外,如果是在模板中使用了动态添加的属性,Vue 也不会自动更新视图,需要手动触发重新渲染。可以通过修改已经存在的响应式属性来触发重新渲染,或者使用 this.$for...
为什么是函数?在 Vue.js 中,组件的 data 属性如果直接使用对象的形式,会导致多个组件实例 共享同一个数据对象 ,从而造成数据的污染和混乱。为了避免这种情况,Vue.js 推荐将 data 属性定义为一个函数,每次创建组件实例时,都会调用这个函数返回一个新的数据对象,从而保证每个组件实例都拥有独立的数据对象,互不影响。具体来说,当 data 属性是一个函数时,Vue.js 在初始化组件实例时会调用这个函数,并将返回的对象作为组件实例的数据对象,确保每个组件实例都拥有自己的数据对象,不会相互影响。这样可以有效地避免多个组件实例共享数据对象带来的问题,提高了组件的封装性和复用性。什...
v2 中:v-for 优先级比v-if高,同时使用浪费性能v3 中:v-if优先级比v-for高,同时使用可能会报错,例如:<!-- 这会抛出一个错误,因为属性 todo 此时 没有在该实例上定义 --> <li v-for="todo in todos" v-if="!todo.isComplete"> {{ todo.name }} </li>在外先包装一层 <template> 再在其上使用 v-for 可以解决这个问题 (这也更加明显易读):<template v-for=&qu...
在 ES6 中使用 class 和 extends 实现继承,可以转换成 ES5 语法的方式如下:1. ES6 语法:class Parent { constructor(name) { this.name = name; } sayHello() { console.log(`Hello, ${this.name}!`); } } class Child extends Parent { constructor(name, age) { super(name); this.age ...
Set、Map、WeakSet 和 WeakMap 是 JavaScript 中的四种数据结构,它们各自有不同的特点和用途。1. Set:Set 是一种集合,其中的元素是唯一且无序的。它类似于数组,但不允许包含重复的值。主要特点:元素的值是唯一的。不允许包含重复的值。内部的元素是无序的。适用场景:用于存储一组唯一的值,比如去重、判断值是否存在等。2. Map:Map 是一种键值对的集合,其中的键是唯一的,但值可以重复。主要特点:存储键值对。键是唯一的,值可以重复。可以使用任意类型作为键和值。适用场景:用于存储键值对的集合,比如缓存、数据映射等。3. WeakSet:WeakSet 是一种...
1. BFC(Block Formatting Context):BFC 是页面中的一个独立的块级渲染区域,其中的元素按照特定的规则进行布局。BFC 的特点包括:内部的盒子会在垂直方向上一个接一个地放置,各个盒子的 margin 会发生重叠,BFC 可以包含浮动的元素,BFC 不会与浮动元素重叠。触发 BFC 的条件包括:根元素或包含根元素的元素、浮动元素、绝对定位元素(position: absolute 或 fixed)、overflow 属性不为 visible 的元素等。应用场景:清除浮动、防止 margin 重叠、实现多栏布局等。2. IFC(Inline Formatting...
最近评论