2025前端面试题

uniapp

uniapp如何打包发版到线上

准备工作

代码测试:确保应用功能完整,没有明显 Bug。

配置调整:根据目标平台调整 manifest.json 和页面配置。

版本号更新:更新应用的版本号(通常在 manifest.json 中配置)。

API 环境切换:将开发环境的 API 地址切换为生产环境
准备工作
代码测试:确保应用功能完整,没有明显的Bug
配置参数:根据目标平台调整manifest.json和页面配置,更新版本号,API 地址切换为生产环境
打包发版
1.发布到H5
配置:在manifest.json的web节点,配置router模式(hash或history)并设置publicPath的路径
打包:点击发行->网站pcweb或手机H5 或者npm run build:h5 在\unpackage\dist\build\web生成静态部署:配置 Nginx,部署到服务器
访问:域名或hash #
2.发布到小程序
配置:在 manifest.json 中,找到 mp-weixin 节点,配置小程序的 AppID 和其他设置
打包:点击发行->小程序微信,在\unpackage\dist\build\mp-weixin生成静态文件
上传:在微信开发工具中,点击上传:填写版本号和备注,提交审核
发布:登录微信公众平台,在“版本管理”中提交审核,审核通过后即可发布。
3.发布到APP
配置:在 manifest.json 中,配置 App 的基本信息,如应用名称、图标、启动图等
打包:点发行->app 云打包 会生成 Android 的 .apk 文件或 iOS 的 .ipa 文件
发布:发布到应用商店
andriod配置签名 上传到google应用商店
ios使用 Xcode 打开生成的 iOS 项目,配置证书和描述文件。将应用上传到 App Store。

vue

vuex刷新数据会丢失吗?怎么解决


解决

  1. 使用 localStorage 或 sessionStorage
    在 Vuex 中监听状态变化,将数据持久化到 localStorage 或 sessionStorage 中,页面刷新时再从存储中读取数据。
// vuex存储到 localStorage
const store = new Vuex.Store({
  state: {
    user: JSON.parse(localStorage.getItem('user')) || null
  },
  mutations: {
    setUser(state, user) {
      state.user = user;
      localStorage.setItem('user', JSON.stringify(user)); // 存储到 localStorage
    },
    clearUser(state) {
      state.user = null;
      localStorage.removeItem('user'); // 清除 localStorage
    }
  }
});
// 监听页面的刷新
window.addEventListener('load', () => {
  const user = JSON.parse(localStorage.getItem('user'));
  if (user) {
    store.commit('setUser', user);
  }
});

computed©和watch(W)的区别

1.C是计算属性,W是监听,监听的data中的数据变化
2.C支持缓存,依赖的属性值发生变化,计算属性才会重新计算,否则用缓存,W不支持缓存
3. C不支持异步,W是可以异步操作的
4. C是第一次加载就监听,W是不监听
5. C函数中必须有return,W不用

vue路由的hash模式和history模式有什么区别

1.hash地址上有 #
2.刷新,hash会对应的加载,history报404
3.hash支持低版本的浏览器,history不支持,因为是H5新增api
4.实现原理 hash的location.hash history的history.pushState和replaceState
5.hash不用配置,history后台服务需要配之
6.hash模式对seo不友好,history对seo更做好

axios如何做封装

封装 axios通统一处理错误、请求头、拦截器等,有助于在项目中更好地管理 API 请求,
1.创建request.js文件,import引入axios,通过.create创建封装实例,设置基础的url,超时时间,请求头等

// 导入axios
import axios from 'axios';
// 使用自定义配置新建一个axios 实例,对axios 做一些基础配置
const instance = axios.create({
  // axios中请求配置有baseURL选项,表示请求URL公共部分
  // baseURL: process.env.VUE_APP_SERVER,
  baseURL: "http://127.0.0.1:8080/",
  timeout: 50000,
  headers: {'X-Custom-Header': 'foobar'}
});

2.请加请求拦截 interceptors.request.use()

instance.interceptors.request.use(function (config) {
  //请求之前执行该函数, 一般在该处设置token
  let token = localStorage.getItem("token");
  if (token) {
    config.headers["token"] = token
  }
  // 在发送请求之前做些什么
  return config;
}, function (error) {
  // 对请求错误做些什么
  return Promise.reject(error);
});

3.添加响应拦截 .interceptors.response.use()

instance.interceptors.response.use(response => {
  //1.非200响应
  //2.token过期
  //3.异地登陆
  //4.非对象加密的解密
  console.log('返回结果:', response);
  return response;
}, error => {
  console.log('返回错误:', error);
  const response = error.response;
  const status = response.status;
  if (status === 401) {
    // 判断状态码是401 跳转到首页或登录页
    console.log("未登录,跳到首页");
    store.commit("setUser", {});
    message.error("未登录或登录超时");
    router.push('/');
  }
  return Promise.reject(error);
})

4.export default instance 导出实例
5.引入request,封装接口

// 所有的请求都放在该目录
import instance from "../utils/request";

//1. 获取登录数据列表
export function login(params) {
  return instance.post('/wxh5/login?code='+params)
}
// 全部分类数据接口
export function GetChannelDataApi(params) {
  return instance({
    url: '/api/catalog/index',
    method: 'get',
    params
  })
}

6.使用封装的接口

import {login} from '@/https/http.js';
login(this.code).then((res) => {})

vue 中reactive定义的响应式对象,如何赋值

不能替换整个对象原因
由于 Vue 的响应式跟踪是通过属性访问实现的,因此我们必须始终保持对响应式对象的相同引用。这意味着我们不能轻易地“替换”响应式对象,因为这样的话与第一个引用的响应性连接将丢失
解决
在 Vue 3 中,使用 reactive 定义的响应式对象可以通过直接修改其属性来更新数据。如果你需要整体替换响应式对象,可以使用 Object.assign 或手动赋值。

vue中如何进行组件通信

1.父子: props 和 e m i t 实现 2. 兄弟:同一父中转,事件总线 emit 实现 2.兄弟:同一父中转,事件总线 emit实现2.兄弟:同一父中转,事件总线emit和 o n , v u e x 3. 跨层级的 p r o v i d e / i n j e c t 和 v u e x 4. 直接通过 on,vuex 3.跨层级的provide/inject和vuex 4.直接通过 on,vuex3.跨层级的provide/injectvuex4.直接通过refs
5.传递属性和事件:$attrs 和 $listeners

elementui如何实现表单的验证

1.在el-form的表单中,添加rules属性,在data中定义校验规则,在方法中通过this.$refs.form.validate()

<el-form :model="form" :rules="rules" ref="form">
data() {
   return {
     form: {...},
     rules: {...}
   }}
methods:{
	submitForm() {
      this.$refs.form.validate((valid) => {
        if (valid) {
          alert("表单验证通过,可以提交!");
        } else {
          alert("表单验证失败,请检查输入!");
        }
      });
    },
    resetForm() {
      this.$refs.form.resetFields();
    },
}

2.直接在行内添加规则
在行内通过rules=“[{规则}]”

<el-form-item label="邮箱" rules="[{ required: true, message: '请输入邮箱地址', trigger: 'blur' }, { type: 'email', message: '请输入正确的邮箱地址', trigger: ['blur', 'change'] }]">
	<el-input v-model="form.email"></el-input>
</el-form-item>

3.自定义规则的校验
在data中定义规则,在data的rules相应的属性中直接赋值,
或在methods中定义规则,在data的rules相应的属性中加this.赋值,

export default {
  data() {
    const validatePassword = (rule, value, callback) => {
      if (value === "") {
        callback(new Error("密码不能为空"));
      } else if (value.length < 6) {
        callback(new Error("密码长度不能少于 6 个字符"));
      } else {
        callback();
      }
    };
    return {
      form: {
        password: "",
      },
      rules: {
        password: [
          { validator: validatePassword, trigger: "blur" },
        ],
      },
    };
  },
};

vue中的修饰符有哪些

1.事件修改符
.stop 阻止冒泡 <button @click.stop=“handleClick”>点击
.prevent 阻止默认的行为 <form @submit.prevent=“onSubmit”>提交
.self
.capture 实现事件的先捕获后冒泡的处理顺序
.once
.passive提升滚动的性能<div @scroll.passive=“onScroll”>滚动
2.按键修改符
.enter .tab .delete (捕获“Delete”和“Backspace”两个按键) .esc .space .up .down .left .right
3.系统修饰符
.ctrl .alt .meta .shift
4.鼠标修改符
.left .right .middle
5.表单修饰符
.lazy .trim .number

vue2的生命周期

1.初始化阶段:
beforeCreat不能访问data,computed,method…
created可以访问数据属性,但dom未挂载,可以进行数据请求和设置定时器,其它不需要依赖dom的
2.挂载阶段
beforeMount:虚拟dom创建,但没渲染页面上
mouted真实的dom渲染
3.更新阶段
beforeUpdate数据生效,
updated组件更新完成,dom渲染完成
4.销毁阶段
beforeDestroy 清理操作,包括定时器
destroyed 销毁组件

vue中key值的作用

1.唯一标识和节点映射,v-for和动态生成的节点的唯一标识
2.提升dom更新,利用虚拟dom+diff算法+key的快速定位,便能最小化的渲染真实dom
3.动画过渡和元素复用
4.避免渲染错误
总体来说,辅助vue引擎更高效,更快速处理虚拟dom的变化,提高性能,确保动画正常工作,避免渲染错误,合理的使用key属性,有利于vue开发。

vue的diff算法是什么,工作原理

定义
diff想法是一种智能高效的更新前端框架的策略,解决最优化更新前端视图的问题,响应式的关键技术
原理
1.虚拟DOm比较 新旧的虚拟dom比较
2.同层级比较 同层级比较,双向遍历,两端比较,向中间靠拢,减少比较次数
3.三大核心比较 移动节点,同层更新位置,而非更新创建;更新节点:仅更新相关属性,而不替换整个节点; 新增/删除节点,dom中添加和移除节点
4.差异记录和批量更新:diff算法后,获取到一份最小化的差异列表记录,随后vue 一次更新dom,达到最小消耗
优点
1.性能优化:在大最的节点中,快速的得到最小差异,精准的定位到相关的dom上,避免了重排与重绘,使用户在大规模的修改dom时,也能达到快速和流畅的体验;
2.具备跨同台的能力
3.简化操作,开发者可以从手动修改dom的任务中抽离出来,专注业务层和逻辑层
4.高效的更新策略,差异最小化更新,节约了时间

如何通过vuex实现登录验证

  1. 使用 Vuex 管理用户状态和登录状态
    在 src/store 目录下创建 index.js 文件,定义 Vuex 的状态、mutations、actions 和 getters。
    state中设置两个变量user,isLogin
    gettters读取变量
    mutations中创建setUser的函数 设置user,isLogin的值,若想在本地持久化登录的话,则要将登录信息存到localStorage,
    actions 异步登录,获取用户信息通过commit setUser并设置
    2.登录组件中
    设置入参,async/await异步方式,调用 Vuex 的登录 action (this.$store.dispatch)登录,成功进入
    3.路由
    在前置路由守卫中获取登录状态,登录了放行,或者重登

keep-alive是什么,缓存的原理, 有哪几个生命周期,如何使用

定义
keep-alive是Vue.js中的一个内置组件,用于缓存动态组件或路由组件,以避免重复渲染和销毁
通过 include 和 exclude 可以控制缓存范围,同时提供了 activated 和 deactivated 钩子来处理组件的激活和停用逻辑。
原理
keep-alive内部维护了一个缓存对象,存储被缓存的组件实例 健是name和key 值是组件的 VNode(虚拟 DOM 节点)缓存策略:当组件首次渲染时,keep-alive 会将其 VNode 和 DOM 节点缓存起来。当组件再次渲染时,keep-alive 会从缓存中直接取出 VNode 和 DOM 节点,而不新创
使用

// 缓存组件
<keep-alive include="ComponentA,ComponentB">
  <component :is="currentComponent"></component>
</keep-alive>
// 缓存路由
<keep-alive>
    <router-view></router-view>
  </keep-alive>

vue3构建项目

vue如何封装组件

首先要明确组件的功能和应用场景
再者要规划好组件的api(与外部交互的接口) props接收的外部参数 slot插槽 event触发的事件
并进一步细化props参数,包括类型,默认值,必要的参数做好校验
最后就是实现组件的逻辑和样式

vue2的响应式原理

Vue2通过Object.defineProperty对data中的属性进行劫持,当属性值发生变化时,会触发对应的更新函数,从而更新视图。
Vue2通过Watcher来实现数据与视图的双向绑定,当数据发生变化时,Watcher会通知对应的视图进行更新。
·Vue2的响应式原理存在一些缺陷,例如无法监听数组的变化,需要通过特殊的方法来实现

vue3的响应式原理

Vue3使用Proxy代替了Object.defineProperty,Proxy可以监听到对象的所有属性,包括新增和删除操作。
Vue3使用了WeakMap来存储依赖关系,避免了Vue2中Watcher的内存泄漏问题
Vue3支持了多个根节点的组件,可以更方便地进行组件的复用和组合。

vue3和2的区别

更快的渲染速度:Vue3使用了Proxy代理对象,可以更快地跟踪数据变化,从而提高渲染速度。
更小的体积:Vue3的体积比Vue2更小,同时也支持按需加载,减少了页面加载时间。
更好的TypeScript支持:Vue3对TypeScript的支持更加完善,可以更好地进行类型检查和代码提示。
更好的组件封装:Vue3引入了Composition API,可以更好地封装组件逻辑,使得组件更加可复用和易维护。
响应式系统进行了重构,可以更好地处理嵌套对象和数组的变化,同时也提供了更多的API来处理响应式数据。

Vuex中的重要核心属性有哪些?

Vuex 应用的核心就是 store(仓库)
五大核心:State,Getter,Mutation,Action,Module
state 存放数据
Getter 相当于计算属性
Mutation 同步修改state中的数据
actions 异步修改数据 调用Mutations中的方法
Module 数据过多或复杂时,将数据用模块化分开

Vue-router有哪几种路由守卫

分四种
全局导航守卫 beforeEach,afterEach
路由独享守卫 beforeEnter
组件内的守卫 beforeRouteEnter beforeRouteUpdate beforeRouteLeave
全局解析守卫 beforeResolve

es6

数组去重的方法

set方法[…new Set(arr)]
filter和indexOf方法: arr.filter((item, index) => arr.indexOf(item) === index)

slice与splice的区别

slice():提取数组的一部分,返回新数组,不修改原数组。
splice():删除、替换或插入元素,修改原数组,返回被删除的元素。

数组有哪些常用方法

添加/删除:push()尾插、pop()尾删、unshift()头插、shift()头删
合并/截取:concat()合并返新、slice()截取返新
遍历:forEach()遍历、map()遍历返新、filter()过滤返新、reduce()累加
查找:indexOf()查找返索引无-1、includes()是否包含返布尔值、find()查询返元素、findIndex()查询第一个返索引
排序/反转:sort()排序、reverse()反转
其他:join()拼接成字符串、toString()转成字符类型、some()是否有返布尔、every()是否都满足条件返布尔、flat()、flatMap()
ES6+:Array.from()、Array.of()、fill()、findLast()、findLastIndex()

ES6的新特性

let const {}[] unicode map set symbol … proxy promise class model
块级作用域 let 和const
箭头函数 ()=> {} 简洁 无this
Promise 异步编程
class和extends继承
模板字符串 使用反引号` 定义字符串,可以嵌入表达式${}
解构赋值:从数组和对象中提取值并赋给变量
默认的参数:函数赋值可以设置默认的参数
扩展运算符:…
模块化:使用 import 和 export 语法导入和导出模块
符号(Symbol):新的数据类型,表示唯一的标识
set 数组元素是唯一,不重复
map 对象,键值对

Promise

ES6引入的异步编程的解决方案,
从语法上说,Promise是一个构造函数,可以实例化对象。封装异步操作,获取成功和失败的结果。
优点:支持链式调用,可以解决回调地狱的问题
缺点:无法取消Promise,一旦新建他就会立即执行,无法中途取消。其次,如果不设置回调函数,Promise内部抛出的错误无法反应到外部。当pending的时候,无法知道进展到了哪一步。
三种状态:pending(进行中)、fullfilled(已成功)、rejected(已失败)。
主要应用在文件读取操作、 数据库操作、AJAX网络请求、定时器

async/await

像写同步代码那样编写异步代码
async 函数返回一个 Promise对象,可以使用 then方法添加回调函数。当函数执行的时候,一旦遇到 await 就会先返回,等到异步操作完成,再接着执行函数体内后面的语句。

防抖和节流,应用场景

防抖和节流都是防止某一时间频繁触发,但是原理却不一样。
防抖是将多次执行变为只执行一次,节流是将多次执行变为每隔一段时间执行
防抖(debounce):
search搜索联想,用户在不断输入值时,用防抖来节约请求资源。
window触发resize的时候,不断的调整浏览器窗口大小会不断的触发这个事件,用防抖来让其只触发一次
节流(throttle):
鼠标不断点击触发,mousedown(单位时间内只触发一次)
监听滚动事件,比如是否滑到底部自动加载更多,用throttle来判断

闭包

定义
闭包通常发生在嵌套函数中,内部函数可以访问外部函数的变量和参数。
主要用途
数据封装:创建私有变量,防止外部的修改
函数柯里化:将多参数函数,变为单参函数
回调函数:
缺点和避免
内存泄漏:因闭包长期存在,不会被垃圾回收机制回收,导致内存泄漏,解决不需要时及时的释放
影响性能:会导致额外的内存开销。避免循环中创建闭包

原型和原型链

原型是一个对象,他包含共享属性和方法
原型链是对象的原型组成的链式结构
继承:通过原型链实现对象之间的继承

0.1+0.2 等于0.3吗?

不等于,这是因为js采用IEEE754浮点数标准,存在精度问题。可以使用toFixed的方法处理

html5

如何理解语义化标签

语义化标签:使用具有明确意义的标签来描述,可以列准确的描述页面的结构和内容层次
优点

  1. 提高可读性和维护性
  2. 提升 SEO(搜索引擎优化)帮助搜索引擎更好地抓取和索引网页内容,从而提高网页的搜索排名
  3. 增强可访问性,阅读性根据标签进行读取,辅助残障用户访问
  4. 兼容性好,符合web标准,避免技术更新带来的兼容性问题

html5的新特性

  1. 语义化标签:header, nav, footer, aside, article, section, main
  2. 表单增加:date,time,range,email,url,search
  3. canvas和svg 脚本化图形
  4. web storage api: localStorage, sessionStorage
  5. 多媒体:video,audio
  6. geolocation api 地理位置
  7. 拖放功能
  8. 离线存储

CSS

css的新特性

1.选择器增强 如伪类选择器nth-child 属性选择器
2.边框和背景 border-radius圆角,linear-gradient 渐变,box-shadow阴影
3.动画和转换 2D/3d动画
4.多列布局 colums
5.媒体查询: 响应式的核心,根据设备视窗的大小进行布局
6.flex和grid布局
7.字体和文本增加
8.滤镜和混合模式 filter

元素的水平垂直居中

1.flex布局

.parent{
	display: flex;
	justify-content:center;
	align-items:center;
}

2.绝对定位+平移transform

.parent{
	position: relative;
}
.child{
	top:50%;
	left:50%;
	transform: translate(-50%,-50%);
}

3.绝对定位+margin:auto;

.parent{
	position: relative;
}
.child{
	top:0;
	left:0;
	right: 0;
	bottom: 0;
	margin:auto;
}

4.grid布局

.parent{
	display: grid;
	place-items:center;
}

安全

跨域CORS

原因:受同源策略的限制,web浏览器若两个页面的协议、域名、端口三者中任意一个不同,就会产生跨域
解决:
CORS(Cross-Origin Resource Sharing)‌:现代浏览器支持CORS,服务器可以在响应头中设置Access-Control-Allow-Origin来允许或拒绝跨域请求
本地做proxy代理 vue-cli代理跨域:使用devServer进行代理
Jsonp 通过

### 2025年最新前端开发面试题汇总 #### 一、基础知识类 1. **HTML/CSS** - 解释 HTML 中 `DOCTYPE` 的作用是什么? 这个声明位于文档的第一行,定义了使用的 HTML 版本。它对于浏览器正确渲染页面至关重要[^1]。 - CSS盒模型由哪些部分组成? 盒模型主要包括四个部分:margin(外边距)、border(边框)、padding(内边距)和 content(内容区)。这些属性共同决定了元素的空间布局方式。 2. **JavaScript核心概念** - JavaScript中的闭包是如何工作的? 当函数可以记住并访问它的词法作用域时,即使这个函数是在其原始作用域之外执行的,这就形成了闭包。通过这种方式可以在内部函数中读取外部变量的数据。 3. **ES6新特性** - 描述一下箭头函数与传统匿名函数的区别有哪些? 箭头函数不绑定自己的 this, arguments, super 或 new.target 关键字;它们依赖于上下文环境提供的 these 值。此外还简化了语法结构,使得代码更加简洁明了。 #### 二、框架和技术栈 1. **React/Vue/Angular对比分析** - 对比 React 和 Vue,在组件化设计方面两者有何不同之处? React 更加注重 JSX 语法糖带来的直观性和灵活性,而 Vue 则强调模板驱动的方式编写视图逻辑更为简单易懂。两种框架都支持单文件组件的形式来组织项目源码。 2. **TypeScript的应用场景与发展景** - TypeScript相比纯JS增加了什么功能?为什么越来越多的企业倾向于采用TS作为主要编程语言之一? 它引入了静态类型检查机制,允许开发者提发现潜在错误从而提高维护效率。随着大型应用规模的增长,这种强类型的脚本语言能够有效降低复杂度并增强团队协作能力。 #### 三、性能优化与实践案例 1. **Web性能优化措施** - 如何解决网页加载速度慢的问题?列举至少三种有效的手段。 可以考虑压缩资源文件大小减少HTTP请求数量;利用CDN加速分发静态资产;开启Gzip/Brotli算法对传输数据流进行无损压缩处理等方式提升整体响应时间表现。 2. **实际项目经验分享** - 结合具体实例讲述曾经参与过的某个重要项目的背景情况、面临的主要难题以及相应的应对策略。 在某电商网站重构过程中遇到了严重的首屏白屏现象,经过深入排查定位到是因为图片懒加载插件配置不当所致。针对此问题调整了相关参数设置,并采用了预加载技术确保关键视觉元素优先呈现给用户查看。 #### 四、安全性考量 1. **XSS攻击防护方案** - 怎样才能有效地防御跨站脚本攻击(XSS)? 措施包括但不限于实施严格的内容安全政策(CSP),强化输入验证流程过滤掉非法字符序列,同时做好输出转义工作避免恶意脚本注入风险发生等多管齐下的综合防控体系构建[^3]。 2. **CSRF防范机制** - CSRF的工作原理是什么样的呢?怎样做才能够阻止此类漏洞被利用? 攻击者试图冒充合法用户的名义向目标服务器提交伪造请求完成某些操作行为。为了抵御这类威胁建议启用同源策略限制第三方站点发起敏感动作的同时配合Token令牌校验机制进一步加固系统边界防护力度。 ```javascript // 示例:简单的防抖函数实现 function debounce(func, wait) { let timeout; return function(...args) { clearTimeout(timeout); timeout = setTimeout(() => func.apply(this, args), wait); } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值