Vue面试2

1.跨域问题以及如何解决跨域

跨域问题(Cross-Origin Resource Sharing, CORS)是指在浏览器中,当一个资源试图从一个不同的源请求另一个资源时所遇到的限制。这种限制是浏览器为了保护用户安全而实施的一种同源策略(Same-origin policy)。同源指的是协议、域名以及端口号三者都相同。如果这三者中的任何一个不同,那么它们就被认为是不同的源。

解决方案

解决跨域问题的方法有几种:

  • CORS配置:最直接的方式是在服务器端设置适当的CORS头。例如,在Express.js应用中可以通过安装并使用cors中间件来快速实现。

const express = require('express');
const cors = require('cors');
const app = express();

app.use(cors());

app.get('/data', (req, res) => {
  res.json({message: 'This is CORS-enabled for all origins!'});
});

app.listen(8080, () => console.log('Server running on port 8080'));
  • JSONP:这是一种较老的技术,仅支持GET请求。它的工作原理是动态创建一个<script>标签,并将跨域请求的URL指定为该标签的src属性值。服务器端需要返回一段JavaScript代码,这段代码调用一个客户端预先定义好的回调函数,并以参数的形式传递请求结果。由于现代浏览器支持CORS,这种方法现在较少使用。

  • 使用代理:可以设置一个代理服务器,前端向这个代理服务器发送请求,代理服务器再向目标服务器转发请求并将响应返回给前端。这样就不存在跨域问题了,因为请求都是在同一源内发生的。

在开发环境中,可以通过配置Vue CLI提供的vue.config.js文件来设置代理,以解决开发时的跨域问题。这将使得开发服务器能够转发请求到指定的目标服务器,从而避免了浏览器的同源策略限制。

module.exports = {
  devServer: {
    proxy: {
      '/api': {
        target: 'http://your-backend-server.com', // 目标服务器地址
        changeOrigin: true,
        pathRewrite: {
          '^/api': ''  // 重写路径,去掉/api前缀
        }
      }
    }
  }
}

在这个例子中,所有以/api开头的请求都会被代理到target指定的服务器上 。

2.Vue2中的过滤器

在Vue.js中,过滤器(Filters)主要用于对文本进行格式化操作。虽然从Vue 3开始,官方已经移除了过滤器这一特性,推荐使用计算属性(Computed Properties)或方法(Methods)来替代它们,但在Vue 2中,过滤器仍然是一个有效的功能,尤其是在需要对文本进行简单转换而不修改原始数据的情况下。

本质上,过滤器是定义为函数的形式,接受一个值作为输入参数,然后返回一个新的值。这个过程不会修改原始值,而是基于原始值创建一个新的值用于显示或其他用途。

使用场景
  1. 日期格式化:将ISO格式的日期字符串转换为更易读的形式。
  2. 货币格式化:显示金额时添加货币符号、千位分隔符等。
  3. 大小写转换:如将文本全部转换为大写或小写。
  4. 数字处理:例如,限制小数点后的位数。
  5. 国际化:根据用户语言设置显示不同语言的内容。
实现做法

定义全局过滤器

可以在main.js中定义全局过滤器,这样所有组件都可以使用这些过滤器:

Vue.filter('capitalize', function(value) {
  if (!value) return '';
  value = value.toString();
  return value.charAt(0).toUpperCase() + value.slice(1);
});

Vue.filter('currency', function(value) {
  if (typeof value !== "number") {
    return value;
  }
  var formatter = new Intl.NumberFormat('en-US', {
    style: 'currency',
    currency: 'USD',
  });
  return formatter.format(value);
});

定义局部过滤器

也可以在单个组件内定义过滤器,仅该组件可以使用:

export default {
  // ...
  filters: {
    capitalize(value) {
      if (!value) return '';
      value = value.toString();
      return value.charAt(0).toUpperCase() + value.slice(1);
    },
    currency(value) {
      if (typeof value !== "number") {
        return value;
      }
      var formatter = new Intl.NumberFormat('en-US', {
        style: 'currency',
        currency: 'USD',
      });
      return formatter.format(value);
    }
  }
}
在模板中使用过滤器

一旦定义了过滤器,就可以在模板中使用管道符号|应用过滤器:

<p>{{ message | capitalize }}</p>
<p>{{ amount | currency }}</p>

3.什么是虚拟dom,如何实现虚拟dom

什么是虚拟DOM?

虚拟DOM(Virtual DOM)是一种编程概念,它指的是在Web应用中,使用JavaScript对象来模拟真实的DOM树。每个虚拟DOM节点对应着真实DOM树中的一个元素。通过这种方式,可以有效地减少直接操作真实DOM的次数,从而提高性能。

虚拟DOM的主要目的是优化用户界面的更新过程。当数据模型发生变化时,不是立即更新真实DOM,而是先更新虚拟DOM。然后通过比较新旧两个虚拟DOM树的差异(这个过程称为Diff算法),找出需要更新的部分,并将这些变化批量地应用到真实DOM上。这样做的好处是可以最小化重绘和回流,提高渲染效率。

如何实现?

①创建虚拟dom:

function createElement(type, props = {}, ...children) {
    return { type, props, children };
}

②渲染虚拟dom为真实dom:

function render(vnode){
    ...
    return node
}

③使用diff算法最小化更新

④更新真实dom

4.Vue权限管理

在 Vue 项目中实现权限管理是一个常见的需求,通常涉及路由权限按钮权限接口权限的控制。

①路由权限控制

核心思路是 动态管理路由 和 全局权限校验

路由权限是指根据用户角色或权限动态加载可访问的路由。

实现步骤:

  • 定义路由表

将路由分为公共路由(所有用户可访问)和权限路由(根据用户角色动态加载)。

// publicRoutes.js
export const publicRoutes = [
  { path: '/login', component: () => import('@/views/Login.vue') },
  { path: '/404', component: () => import('@/views/404.vue') },
];

// privateRoutes.js
export const privateRoutes = [
  { path: '/dashboard', component: () => import('@/views/Dashboard.vue'), meta: { role: 'admin' } },
  { path: '/user', component: () => import('@/views/User.vue'), meta: { role: 'user' } },
];
  • 动态添加路由

根据用户角色从后端获取权限列表,动态添加路由。

import { publicRoutes, privateRoutes } from './routes';
import router from './router';

const addRoutes = (role) => {
  const allowedRoutes = privateRoutes.filter(route => route.meta.role === role);
  allowedRoutes.forEach(route => router.addRoute(route));
};

// 登录成功后调用
addRoutes('admin');
  • 路由守卫

使用 beforeEach 钩子检查用户是否有权限访问目标路由。

router.beforeEach((to, from, next) => {
  const userRole = localStorage.getItem('userRole'); // 从本地存储获取用户角色
  if (to.meta.role && to.meta.role !== userRole) {
    next('/404'); // 无权限则跳转到 404
  } else {
    next();
  }
});
②按钮权限控制

按钮权限是指根据用户角色或权限动态显示或隐藏页面中的按钮。

实现步骤:

  • 自定义指令

创建一个自定义指令 v-permission,用于控制按钮的显示和隐藏。

// main.js
Vue.directive('permission', {
  inserted(el, binding, vnode) {
    const userRole = localStorage.getItem('userRole');
    if (binding.value !== userRole) {
      el.parentNode.removeChild(el); // 无权限则移除按钮
    }
  },
});
  • 使用指令

在按钮上使用 v-permission 指令。

<template>
  <button v-permission="'admin'">管理员按钮</button>
  <button v-permission="'user'">普通用户按钮</button>
</template>
接口权限控制

接口权限是指根据用户角色或权限控制用户能否调用某些接口。

实现步骤:

  • 后端控制

    • 后端接口根据用户角色返回不同的数据或状态码(如 403 无权限)。

  • 前端拦截

    • 在请求拦截器中检查用户权限。

axios.interceptors.request.use((config) => {
  const userRole = localStorage.getItem('userRole');
  if (config.url === '/admin/data' && userRole !== 'admin') {
    return Promise.reject(new Error('无权限访问'));
  }
  return config;
});
权限管理的完整流程
  1. 用户登录

    • 用户登录后,后端返回用户角色和权限列表。

    • 前端将角色和权限信息存储在 localStorage 或 Vuex 中。

  2. 动态路由加载

    • 根据用户角色动态加载路由。

  3. 路由守卫

    • 在路由跳转时检查用户权限。

  4. 按钮权限

    • 使用自定义指令控制按钮的显示和隐藏。

  5. 接口权限

    • 在请求拦截器中检查用户权限。

5.SPA首屏加载优化

一、代码优化:减少主包体积

1. 代码分割(Code Splitting)

  • 使用 Webpack 的 SplitChunksPlugin 或 Vite 的自动分割,将代码拆分成多个小块。

2. 路由懒加载

  • 结合动态导入(import())实现按需加载路由组件。

3. Tree Shaking

  • 移除未使用的代码(仅对 ESM 模块有效)。
  • 注意:确保项目使用 ES6 模块语法,并在 package.json 中设置 "sideEffects": false

4. 压缩代码

  • 使用 TerserPlugin 压缩 JS,CssMinimizerPlugin 压缩 CSS。
二、资源优化:减少传输体积

1. 图片压缩与格式优化

  • 使用 WebP 格式替代 PNG/JPG(体积减少 30%~70%)。
  • 工具推荐:
    • Squoosh(在线压缩)
    • ImageMagick(批量处理)
    • vue-lazyload(图片懒加载)

2. 字体文件优化

  • 使用 font-display: swap; 避免字体加载阻塞渲染。
  • 按需加载字体子集(通过 Google Fonts Subset)。

3. 开启 Gzip/Brotli 压缩

  • 服务器配置 Gzip 或 Brotli(比 Gzip 压缩率高 20%)。
三、缓存策略:减少重复加载

1. 强缓存(Cache-Control)

  • 对静态资源(JS/CSS/图片)设置长缓存。

2. 版本号哈希

  • 文件名添加哈希(如 app.3a87f.js),确保内容变更后缓存失效。
四、渲染优化:加速首屏展示

1. 服务端渲染(SSR)

  • 使用 Nuxt.js(Vue) 或 Next.js(React) 实现服务端生成 HTML。
  • 优势:直接返回渲染好的 HTML,减少客户端解析时间。

2. 预渲染(Prerendering)

  • 对静态页面(如营销页)在构建时生成 HTML。
  • 工具推荐:vue-cli-plugin-prerender-spareact-snap

3. 骨架屏(Skeleton Screen)

  • 在数据加载前展示占位图,提升用户体验。
五、网络层优化:加速资源传输

1.资源预加载(Preload/Prefetch)

  • 使用 <link rel="preload"> 提前加载关键资源。

6.回流和重绘

在前端开发中,回流(Reflow) 和重绘(Repaint) 是浏览器渲染机制的关键概念,直接影响页面性能。以下是详细解析:

一、概念区别
  1. 回流(Reflow)

    • 当元素的尺寸、位置、布局等几何属性发生变化时,浏览器需要重新计算元素的几何信息(布局),并更新渲染树。
    • 触发条件:影响页面布局的操作,例如修改宽高、边距、字体大小、DOM结构变化等。
    • 性能消耗:高,可能导致子元素或父元素的连锁回流。
  2. 重绘(Repaint)

    • 当元素的外观属性(如颜色、背景、透明度等)发生变化,但布局未改变时,浏览器仅重新绘制受影响的部分。
    • 触发条件:不影响布局的样式变化,如 colorbackground-colorvisibility 等。
    • 性能消耗:低于回流,但仍需避免高频触发。
二、优化策略:减少回流和重绘

1. 批量 DOM 操作

  • 使用 DocumentFragment 或离线 DOM
    将多次 DOM 修改合并到临时容器中,再一次性插入
const fragment = document.createDocumentFragment();
for (let i = 0; i < 100; i++) {
  const node = document.createElement("div");
  fragment.appendChild(node);
}
document.body.appendChild(fragment);
  • 隐藏元素后操作

        通过 display: none 隐藏元素,操作完成后再显示

2. 避免频繁读取布局属性

  • 缓存布局信息

3. 使用 CSS 优化

  • 通过 CSS 类合并样式
  • 使用 transform 和 opacity 实现动画
    这些属性由 GPU 加速处理,避免触发回流/重绘

4. 避免表格布局和复杂选择器

  • 表格布局(display: table)易触发连锁回流。
  • 减少 CSS 选择器嵌套层级,降低样式计算复杂度

7.CSS预编语言

CSS 预处理器(CSS Preprocessor)通过扩展 CSS 的功能,提供了更高效、更灵活的样式编写方式。以下是主流 CSS 预处理器(SassLessStylus)的区别与特点总结。

一、共同特点
  • 变量

    支持定义变量,方便复用和维护样式

$primary-color: #3498db; // Sass
@primary-color: #3498db; // Less
primary-color = #3498db // Stylus
  • 嵌套

        支持嵌套规则,减少代码冗余。

.container {
  .item {
    color: red;
  }
}
  • 混合(Mixins)

        支持定义可复用的样式块。

@mixin border-radius($radius) { // Sass
  border-radius: $radius;
}
.box { @include border-radius(10px); }

// Less
.alert {
 font-weight: 700;
}
.highlight(@color: red) {
 font-size: 1.2em;
 color: @color;
}
.heads-up {
  .alert;
  .highlight(red);
}
  • 导入(Import)

        支持模块化,将样式拆分为多个文件

@import "variables"; // Sass/Less/Stylus
二、对比

三、选择建议
  1. Sass:功能强大,适合复杂项目,推荐使用 .scss 语法。
  2. Less:简单易用,适合小型项目或与 Bootstrap 集成。
  3. Stylus:灵活且功能丰富,适合追求简洁语法的开发者。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/975340.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

毕业项目推荐:基于yolov8/yolo11的水稻叶片病害检测识别系统(python+卷积神经网络)

文章目录 概要一、整体资源介绍技术要点功能展示&#xff1a;功能1 支持单张图片识别功能2 支持遍历文件夹识别功能3 支持识别视频文件功能4 支持摄像头识别功能5 支持结果文件导出&#xff08;xls格式&#xff09;功能6 支持切换检测到的目标查看 二、数据集三、算法介绍1. YO…

DeepSeek写贪吃蛇手机小游戏

DeepSeek写贪吃蛇手机小游戏 提问 根据提的要求&#xff0c;让DeepSeek整理的需求&#xff0c;进行提问&#xff0c;内容如下&#xff1a; 请生成一个包含以下功能的可运行移动端贪吃蛇H5文件&#xff1a; 要求 蛇和食物红点要清晰&#xff0c;不超过屏幕外 下方有暂停和重新…

C/C++跳动的爱心

系列文章 序号直达链接1C/C李峋同款跳动的爱心2C/C跳动的爱心3C/C经典爱心4C/C满屏飘字5C/C大雪纷飞6C/C炫酷烟花7C/C黑客帝国同款字母雨8C/C樱花树9C/C奥特曼10C/C精美圣诞树11C/C俄罗斯方块小游戏12C/C贪吃蛇小游戏13C/C孤单又灿烂的神14C/C闪烁的爱心15C/C哆啦A梦16C/C简单…

深入理解 JSP 与 Servlet:原理、交互及实战应用

一、引言 在 Java Web 开发领域,JSP(JavaServer Pages)和 Servlet 是两个至关重要的技术,它们共同构成了动态网页开发的基础。Servlet 作为服务器端的 Java 程序,负责处理客户端请求并生成响应;而 JSP 则是一种简化的 Servlet 开发方式,允许开发者在 HTML 页面中嵌入 J…

百度搜索,能否将DeepSeek变成“内功”?

最近&#xff0c;所有的云平台和主流APP都在努力接入DeepSeek。其中&#xff0c;搜索类APP与搜索引擎更是“战况激烈”。那么问题来了&#xff0c;接入DeepSeek已经变成了标准配置&#xff0c;到底应该如何做出差异化&#xff1f;接入DeepSeek这件事能不能实现11大于2的效果&am…

小智机器人CMakeLists编译文件解析

编译完成后&#xff0c;成功烧录&#xff01; 这段代码是一个CMake脚本&#xff0c;用于配置和构建一个嵌入式项目&#xff0c;特别是针对ESP32系列芯片的项目。CMake是一个跨平台的构建系统&#xff0c;用于管理项目的编译过程。 set(SOURCES "audio_codecs/audio_code…

保姆级教程 | Office-Word中图目录制作及不显示图注引文的方法

背景 由于毕业论文的格式修改需要&#xff08;没错&#xff0c;我终于要拿下PhD了。差不多四个月没更新&#xff0c;主要是①根据处理完的数据完成小论文撰写&#xff1b;②找工作...③完成学位论文的撰写。因而对建模和数据处理的需求不高&#xff0c;对有些时隔久远的博文具…

SVN把英文换中文

原文链接&#xff1a;SVN设置成中文版本 都是英文&#xff0c;换中文 Tortoise SVN 安装汉化教程(乌龟SVN) https://pan.quark.cn/s/cb6f2eee3f90 下载中文包

负载均衡集群( LVS 相关原理与集群构建 )

目录 1、LVS 相关原理 1.1、LVS集群的体系结构以及特点 1.1.1 LVS简介 1.1.2 LVS体系结构 1.1.3 LVS相关术语 1.1.4 LVS工作模式 1.1.5 LVS调度算法 1.2 LVS-DR集群介绍 1.2.1 LVS-DR模式工作原理 1.2.2 LVS-DR模式应用特点 1.2.3 LVS-DR模式ARP抑制 1.3 LVS – NA…

深度解析:使用 Headless 模式 ChromeDriver 进行无界面浏览器操作

一、问题背景&#xff08;传统爬虫的痛点&#xff09; 数据采集是现代网络爬虫技术的核心任务之一。然而&#xff0c;传统爬虫面临多重挑战&#xff0c;主要包括&#xff1a; 反爬机制&#xff1a;许多网站通过检测请求头、IP地址、Cookie等信息识别爬虫&#xff0c;进而限制…

[Android]APP自启动

APP添加自启动权限&#xff0c;重启设备后自动打开APP。 1.AndroidManifest.xml <?xml version"1.0" encoding"utf-8"?> <manifest xmlns:android"http://schemas.android.com/apk/res/android"xmlns:tools"http://schemas.an…

Kubernetes 使用 Kube-Prometheus 构建指标监控 +飞书告警

1 介绍 Prometheus Operator 为 Kubernetes 提供了对 Prometheus 机器相关监控组件的本地部署和管理方案&#xff0c;该项目的目的是为了简化和自动化基于 Prometheus 的监控栈配置&#xff0c;主要包括以下几个功能&#xff1a; Kubernetes 自定义资源&#xff1a;使用 Kube…

清华大学第五弹:《DeepSeek与AI幻觉》

作者&#xff1a;清华大学新闻与传播学院新媒体研究中心、人工智能学院&#xff08;新媒沈阳团队&#xff09; 时间&#xff1a;2025年2月 完整版下载地址&#xff1a;夸克网盘分享 一、AI幻觉的定义与分类 定义 学术定义&#xff1a;模型生成与事实不符、逻辑断裂或脱离上下…

鹰角基于 Flink + Paimon + Trino 构建湖仓一体化平台实践项目

摘要&#xff1a;本文整理自鹰角大数据开发工程师&#xff0c;Apache Hudi Contributor 朱正军老师在 Flink Forward Asia 2024 生产实践&#xff08;二&#xff09;专场中的分享。主要分为以下四个部分&#xff1a; 一、鹰角数据平台架构 二、数据湖选型 三、湖仓一体建设 四、…

deepin 下安装nvm(npm+node)

1、切换root用户&#xff0c;并更新系统 sudo su sudo apt update && apt upgrade -y 期间所有提示选择yes即可 2、切换回自己用户 su - fchsoft 3、安装git sudo apt install git -y 4、安装wget sudo apt install wget -y 5、安装nvm 创建文件夹 mkdir -p…

【JavaEE进阶】MyBatis通过注解实现增删改查

目录 &#x1f343;前言 &#x1f340;打印日志 &#x1f334;传递参数 &#x1f38b;增(Insert) &#x1f6a9;返回主键 &#x1f384;删(Delete) &#x1f332;改(Update) &#x1f333;查(Select) &#x1f6a9;起别名 &#x1f6a9;结果映射 &#x1f6a9;开启驼…

三、数据治理应用开发整体架构

1.数据治理应用开发整体架构概览 该架构图描绘了一个全面的数据治理应用开发平台&#xff0c;旨在为用户提供从数据调研、治理构建、资产管理到应用开发、运维监控等全生命周期的一体化服务。整体架构呈现出模块化、松耦合的特点&#xff0c;并强调低代码开发和业务中台能力。 …

C#项目05-猜数字多线程

本项目利用多线程&#xff0c;通过点击按钮猜数字&#xff0c; 知识点 线程 基本概念 进程:一组资源&#xff0c;构成一个正在运行的程序&#xff0c;这些资源包括地址空间、文件句柄以及程序启动需要的其他东西的载体。 线程:体现一个程序的真实执行情况&#xff0c; 线…

XiaoMi Mi5(gemini) 刷入Ubuntu Touch 16.04——安卓手机刷入Linux

最近在研究个人用的小服务器&#xff0c;期间也搞了一台某讯的盒子&#xff0c;s905的芯片&#xff0c;28G&#xff0c;刷入了Armbian&#xff0c;在自己本地当linux服务器用用挺方便的&#xff0c;但总感觉性能不太够。 然后灵机一动&#xff0c;手上还有几台旧的安卓手机&am…

Spring Security+JWT+Redis实现项目级前后端分离认证授权

1. 整体概述 权限管理包括用户身份认证和授权两部分&#xff0c;简称认证授权。对于需要访问控制到资源&#xff0c;用户首先经过身份认证&#xff0c;认证通过后用户具有该资源的访问权限方可访问。 1.1 认证概述 认证是确认用户身份的过程&#xff0c;确保用户是谁。 1.1.1 …