前端问题整理

Vue

  1. vue mvvm(Model-View-ViewModel)架构模式原理 - Model 是数据层,即 vue 实例中的数据

    • View 是视图层, 即 dom
    • ViewModel,即连接Model和Vue的中间层,Vue实例就是ViewModel
    • ViewModel 负责将 Model 的变化反映到 View 上,同时也监听 View 的变化并反映到 Model 上,实现了双向数据绑定。
  2. 组件传参方式有哪些?

    • props和emit

    • 插槽

    • $refs

    • event-bus $emit $on

    • vuex和pinia

    • 路由传参

    • 本地储存

  3. 什么是vue实例?

    vue实例包含了数据、模板、方法等属性,负责处理视图的渲染和交互逻辑

  4. computed和watch原理

    计算属性 (computed) 的原理:

    计算属性是 Vue 中用于派生数据的一种方式,它的原理如下:

    依赖追踪:当在计算属性中使用响应式数据时,Vue 会自动建立一个依赖关系。这意味着计算属性知道哪些响应式数据影响了它的值。

    缓存:计算属性会缓存它的计算结果,只有当依赖的响应式数据发生变化时,才会重新计算。这样可以避免不必要的计算,提高性能。

    懒计算:计算属性只在实际需要时才会计算,这意味着只有当计算属性被访问时,它才会执行计算逻辑。

    自动更新:当依赖的响应式数据发生变化时,与之相关的计算属性会自动重新计算其值,并确保界面上相应的数据也会更新。

    监听属性 (watch) 的原理:

    监听属性用于监视响应式数据的变化,并执行副作用代码,其原理如下:

    侦听变化:当你在 Vue 实例中定义一个 watch 属性,你可以指定要监听的响应式数据。

    回调函数:你可以为每个被监听的数据定义一个回调函数。当被监听的数据发生变化时,这些回调函数会被触发执行。

    异步执行:Vue 默认会在数据变化后异步执行 watch 回调函数,以避免阻塞主线程。

    取消监听:你可以通过调用 unwatch 或 unwatchAll 方法来取消对响应式数据的监听。

  5. vue双向绑定原理

    Object.defineProperty(obj 要定义/修改的属性的对象, prop 要定义/修改的属性名, descriptor 具体的方法)

    <script type="text/javascript">
        var obj = {};
        Object.defineProperty(obj, 'txt', {
            get: function() {
                return obj;
            },
            set: function(val) {
                document.getElementById("txt").value = val;
                document.getElementById("show").innerText = val;
            }
        })
        document.addEventListener("keyup", function (e) {
            obj.txt = e.target.value;
        })
    </script>
    
  6. $nextTick

    DOM 更新之后执行回调函数

    新增表格输入框自动聚焦

  7. vue2和vue3的差异

    • setup相当于整合了beforeCreate和created
    • 移除了一些修饰符
    • ref reactive
    • 源码使用typescript进行重构,vue对typescript支持更加友好了
    • 样式穿透 v-deep
    • 插槽
首页加载优化

chrome devtools lighthouse 有性能分析
1.加 CDN,图片,使用SVG图标。js\css文件比较大的可以用cdn加载-externals。
2.图片懒加载Lazy Loading,按需加载,webpp格式的图片。组件懒加载,组件按需引入,路由懒加载;
3.减少公共自定义组件。减少全局的混入
4.减少http请求。
10.延迟调用一些方法,减少js主进程(比如埋点方法。fastclick,vconsole的加载)
5.前端compression-webpack-plugin、服务端开启gzip。
7.删除无效代码。
8.后端接口查sql比较慢,这个可以提意见,骨架图,性能测试。
9.使用浏览器强缓存策略 Cache-Control。
12.需要设置的样式很多时,设置className,不要设置style;减少重绘和回流;
13.服务端渲染,ssr技术,next.js

网页性能优化
  • 网络请求优化

  • 资源精简优化

  • 渲染优化

  • 图片优化

    图片懒加载

  • 代码优化

    组件化、模块化、代码复用

webpack
  • tree shaking 代码分割
  • dllPlugin 分离打包
  • hotModuleReplscementPlugin 热更新
  • HtmlWebpackPlugin 生成入口html文件
webpack升级vite
  1. vue版本一定要是^2.7
  2. webpack配置一定要记得继承,尤其是和alias、extends
  3. sass、less有一些常见的坑(全局变量、:export等语法不支持、@/)
  4. html模板变量注入方式改变
  5. 环境变量process.env要改成import.meta
  6. commonjs模块不支持
  7. webpack相关的文件可以去除,postcss,babel等等,vite已经内部集成,eslint.js也去掉后续重新在vite中编写
浏览器兼容、分辨率适配
  • css兼容:reset.css

    *{margin:0;padding:0;)}

  • 加浏览器前缀兼容

  • 设置统一字体:ttf字体包

  • 媒体查询

  • 百分比

  • em、rem

统计数组中每项出现的次数
let arr = [2, 3, 4, 2, 0, 1, 3, 2, 2, 9, 7, 100]
let obj = {}
for(var i = 0; i < arr.length; i++) {
    let key = arr[i]
    // 三元运算符判断
    obj[key] == undefined ? obj[key] = 1 : obj[key]++
}
console.log(obj);
输入url地址到浏览器显示页面发生了什么
  • DNS对域名进行解析

  • 建立TCP连接(三次握手) 我要xxx=>确定吗?=>确定

  • 发送请求

  • 返回结果

  • 解析 HTML: 浏览器解析 HTML 并构建 DOM 树。

  • 解析 CSS: 浏览器解析 CSS 文件并构建 CSSOM 树。

  • 合并 DOM 和 CSSOM: 将 DOM 树和 CSSOM 树合并成渲染树(Render Tree)。

  • 布局(Layout): 根据渲染树计算每个元素的大小和位置,生成布局(Layout)。

  • 绘制(Paint): 将布局绘制到屏幕上。

  • 重绘与重排: 当页面的样式或布局发生变化时,浏览器会触发重绘(Repaint)和重排(Reflow),其中重排会引起布局的重新计算,性能开销较大,应尽量避免。

  • 在这里插入图片描述

iframe缺点
  • 不利于seo优化
  • 移动设备兼容性差
  • 阻塞主页面onLoad
  • 前进返回问题
uniapp遇到哪些问题
  1. 列表页获取数据的时候,页面会闪一下

页面里面存在图片,图片只定义了宽度,没有定义高度
解决:给图片定义高度
2. 上传图片旋转
3. 在页面调用uni.scanCode识别普通二维码再进来小程序该页面,会再执行一次onShow,也就是onShow会执行两次
记得有需要数据回显的页面,请求数据的时候一定不要放在onShow,否则很有可能会导致新更改的数据,被回显的数据覆盖
4.背景图
5.分包

小程序分包

https://i-blog.csdnimg.cn/direct/48445b40bb8148749241ae19cfa7e1e4.png在这里插入图片描述
1.首先在 mainfest.json mp-weixin添加以下代码(启动分包)

"optimization": {
			"subPackages": true
		}

2.项目结构改变,添加分包目录
├── pages // 主包页面
│ └── index
├── subpackage1 // 分包1
│ ├── page1
│ └── page2
├── subpackage2 // 分包2
│ ├── page3
│ └── page4
├── app.js
├── app.json
├── app.wxss
解释一下:subpackage1 subpackage2 就是你要分出去的包这里面就要写你写的项目比如首页啊什么的但是注意tabar栏的内容不能分

3.路径也成相对分包的变一下

	"subPackages": [{
		"root": "subpackage1       ",
		"pages": [	{
			"path": "",
			"style": {
				
			}
		},
		{
			"path": "",
			"style": {
				
			}
		},
		{
			"path": "",
			"style": {
				
			}
		}]
	}],

subPackages这里面写分包内容的路径,就跟pages写路径一样,但是分包不用写前面的pages直接就 index/index就行

"path": "pages/index/index",
cookie
  • cookie是在浏览器中保存的
  • cookie的保存是以键值对的形式存在的 大小有一定限制
//1.cookie的构造方法,目的是实例化出来cookie对象
Cookie(String name,String value)
//2.设置cookie的方法
setValue(String value) //修改cookie的值
setMaxAge(int time) //设置cookie的有效时间
setPath(String path) //设置当前cookie的有效路径
//3.要将cookie发送到浏览器
response.addCookie(Cookie cookie);
//4.获取浏览器中cookie,返回值是一个数组
   Cookie[] cookies = request.getCookies();
TS
  1. 接口:interface
    接口是用于描述对象的形状的结构化类型。它定义了对象应该包含哪些属性和方法。在TypeScript中,接口可以用来约束对象的结构,以提高代码的可读性和维护性。例如:
interface Person {
    name: string;
    age: number;
}
function greet(person: Person) {
    return `Hello, ${person.name}!`;
}
  1. 泛型:generic
    泛型是一种在定义函数、类或接口时使用类型参数的方式,以增加代码的灵活性和重用性。在TypeScript中,可以使用来创建泛型。例如:
function identity<T>(arg: T): T {
    return arg;
}
// 调用泛型函数
let output = identity<string>("hello");
  1. 枚举:enum
    枚举是一种对数字值集合进行命名的方式。它们可以增加代码的可读性,并提供一种便捷的方式来使用一组有意义的常量。例如:
enum Color {
    Red,
    Green,
    Blue
}

let selectedColor: Color = Color.Red;
  1. 联合类型
// typescript
let myVar: string | number;
myVar = "Hello"; // 合法
myVar = 123; // 合法

  1. TypeScript中的声明文件
    声明文件(通常以 .d.ts 扩展名结尾)用于描述已有 JavaScript 代码库的类型信息。它们提供了类型定义和元数据,以便在 TypeScript 项目中使用这些库时获得智能感知和类型安全。
  2. 命名空间(Namespace)和模块(Module)
    模块:提供了一种组织代码的方式,使得我们可以轻松地在多个文件中共享代码
// greeter.ts
export function sayHello(name: string) {
  return `Hello, ${name}!`;
}
// app.ts
import { sayHello } from './greeter';
console.log(sayHello('John'));

命名空间:提供了一种在全局范围内组织代码的方式,防止命名冲突。

// greeter.ts
namespace Greetings {
  export function sayHello(name: string) {
    return `Hello, ${name}!`;
  }
}
// app.ts
<reference path="greeter.ts" />
console.log(Greetings.sayHello('John'));


  1. 类型断言
    类型断言允许程序员手动指定一个值的类型。这在需要明确告诉编译器某个值的类型时非常有用。
let someValue: any = "this is a string";
let strLength: number = (someValue as string).length;
  1. 可选参数和默认参数
    可选参数允许函数中的某些参数不传值,在参数后面加上问号?表示可选。
    默认参数允许在声明函数时为参数指定默认值,这样如果调用时未提供参数值,则会使用默认值。
    可选参数示例:
function greet(name: string, greeting?: string) {
  if (greeting) {
    return `${greeting}, ${name}!`;
  } else {
    return `Hello, ${name}!`;
  }
}

默认参数示例:

function greet(name: string, greeting: string = "Hello") {
  return `${greeting}, ${name}!`;
}
nginx
# 开启压缩文件 
    #gzip  on;
  • HTTPS配置:如果需要启用HTTPS,可以添加以下配置来配置SSL证书和密钥:
server {
    listen 443 ssl;
    server_name example.com;

    ssl_certificate /path/to/certificate.crt;
    ssl_certificate_key /path/to/private.key;

    location / {
        proxy_pass http://backend-server;
    }
}

  • 静态资源访问和重定向
server {
    listen 80;
    server_name example.com;

    location /static {
        alias /path/to/static/files;
        proxy_pass http://backend-server;
    }
}

http 7层

在这里插入图片描述

微应用原理

通过import-html-entry 以html为应用入口,
通信:globalState、qiankun官方提供了一个简要的方案,思路是基于一个全局的globalState对象。这个对象由基座应用负责创建,内部包含一组用于通信的变量,以及两个分别用于修改变量值和监听变量变化的方法:setGlobalState和onGlobalStateChange。

小程序、公众号开发流程
axios封装、去除重复接口调用

XMLHttpRequest.abort()
关于取消重复请求,最重要的是这么做的意义,而不在于代码的实现
其实,我觉得,绝大部分能够想到的应用场景,都可以通过防抖、节流方式实现,比如实时搜索,比如重复订单提交、比如上拉获取最新数据等
事实上,取消请求,请求也是会到达服务端的!只是发出后就不管了,不再接受服务端返回的数据
axios.CancelToken

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

楚叫兽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值