面试背完这一篇绝对就够用了

行内元素与块级元素

块元素有div、p、h1、ol、ul、dl、tabel、form;

行内元素有a、span、i、strong、em、label

行内块元素有img、input、select、button;

行内元素与块级函数可以相互转换,通过修改display属性值来切换块级元素和行内元素,行内元素display:inline,块级元素display:block

数据代理的理解/vue的理解

具体实现思路,在实例化mvvm时候需要传入一个配置对象,内部进行存储,同时获取配置对象中的data,通过object.keys方法获取data中所有的属性进行遍历,在遍历的过程中调用proxy.data方法并传入data中的属性,该方法内部,使用object.defineProtperty方法为vm对象添加data中的属性,并且重写get和set方法

数据劫持

开始进行数据劫持,遍历 data 对象中所有的属性,定义响应式的数据,创建 dep 对象,进
行 深度递归数据劫持,调用 object.defineProperty() 方法,为劫持对象的 data 属性添加
data 对象中的每个属性,重写 get 和 set 方法;数据劫持完毕后,每个属性会产生对应的
dep 对象

ts和js区别

首先,它们都是脚本语言,ts是微软开发的开源编程语言,ts包含了js的库和函数,ts上可以写任何的js
​
js没有重载概念,ts有可以重载
​
4、ts增加了接口interface、泛型、类、类的多态、继承等
​
5、ts对比js基础类型上,增加了 void/never/any/元组/枚举/以及一些高级类型

数据响应式理解(简版)

其实就是通过底层原理object.defineProperty(),去做了一些监听机制,订阅发布者模式,结合他的一个这个dep,更新的一个机制去实现的响应式
​
怎么把它变为响应式:通过vue的语法糖,$set把它强制变为响应式,或者加一个自己手写的get方法,也可以是get set方法
手写的get怎么写:
通过object.defineProperty(),对他的变量进行修改,以及变量的获取去做监听,监听到之后就给他绑定现成的事件
​
1.一对一的关系:指的是一个dep对应一个watcher
​
2.一对多的关系:指的是一个dep对应多个watcher
​
3.多对一的关系:指的是多个dep对应一个watcher
​
4.多对多的关系:指的是多个dep对应多个watcher

模板解析(简版)

首先 Vue 中是有模板解析存在的;
模板解析发生在数据代理和数据劫持之后,
首先创建编译实例对象,传入选择器和vm实例对象,内部存储vm,通过选择器获取模板容
器对象,创建文档碎片对象,把模板容器中所有的节点全部都放进文档碎片对象中:

从输入url到渲染出页面的整个过程

1. 得到服务器对应的IP地址 ==> DNS解析
2. 通过IP连接上服务器: 3次握手
3. 向服务器发请求, 接收服务器返回的响应
4. 解析响应数据(html/css/js)显示页面
解析html => dom树
解析css => cssom树
解析js => 更新dom树/cssom树
生成渲染树 = dom树 + cssom树
布局
渲染
5. 断开连接:4次挥手

MVVM

object.efineProperty()的一个结构,主要的优势在于vue和moedl之间的双向数据绑定,视图改变数据就可以改变,数据改变视图也会改变

v-for和v-if为什么不能连用

v-for比v-if优先级高,先执行v-for每一次都要遍历整个数组,造成不必要的计算,影响性能

跨域

11. ajax跨域问题的理解和解决方案 ✓
 跨域问题是因为违反了同源策略
 所谓同源,是指 协议、域名、端口都相同;发送 ajax 请求时,浏览器要求 当前网页和服务
器必须同源(安全), 否则会抛出跨域的错误;
 但是image,script 没有跨域问题
 解决 ajax 跨域问题的方法:
 JSONP
 JSONP 之所以能够用来解决跨域方案,主要是因为 <script> 脚本拥有跨域能力,而
JSONP正是利用这一点来实现
 CORS
 是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。它允
许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用
的限制。
 是后端进行的
 PROXY
 主要是前端对接口进行代理,前端ajax请求的是本地接口,本地接口接收到请求后向
实际的接口请求数据,然后再将信息返回给前端;
 但是这个仅是开发过程中进行的

diff算法

渲染真实DOM的开销很大,如果渲染到真实dom上会引起整个都没数的重绘和重排,修改一小块dom而不是整个dom,diff算法会帮助我们

重排和重绘

重排肯定会重绘, 但重绘不一定有重排

重排比重绘开销更大, 更消耗性能

哪些操作会导致重排

浏览器窗口尺寸改变

元素位置和尺寸发生改变的时候

新增和删除可见元素

内容发生改变(文字数量或图片大小等等)

元素字体大小变化。

webpack**配置层面优化**

代码Tree Shaking 是一种通过移除多余代码,来优化打包体积的

压缩代码,删除多余代码,简化代码

虚拟dom的定义与作用

虚拟dom就是一个普通的js对象。是一个用来描述真实dom结构的js对象,因为他不是真实dom,所以才叫虚拟dom。

v-model指令(双向数据绑定)的原理

双向绑定的原理其实就是分为两步:模板编译和数据劫持

    模板编译:分析模板tempalte,元素节点的属性如果存在v-html,v-model,{{ }}等属性,需要找到对应的数据,并进行渲染。

    数据劫持:当数据data发生改变的时候,重新编译模板。(利用的是Object.defineProperty监听数据变化,watch方法对每个元素进行监听,发布订阅者模式订阅watch对象,发布watch对象中update方法)

原型的理解

首先原型有2个,一个是prototype,一个是__proto__,他们是属性也都是对象,prototype是显式原型,存在于函数中,[[__proto__]]是隐式原型,存在于对象中,函数也是对象,所以2个都有.

原型的作用主要是用来实现数据共享,目的是节省内存

原型的产生:针对于实例对象,在new的时候,除了做四件事
1.申请一块空闲的内存空间,存储当前对象
2.设置this指向 为当前对象
3.初始化属性和方法的值 
4.返回当前的实例对象this

说说项目中 axios 二次封装

1.对api统一管理,不管接口有多少,所有的接口都可以非常清晰,容易维护。
 axios 二次封装中做了哪些设置
 创建 axios 实例,
 配置通用的基础路径 和 超时
 设置了请求进度条的显示和结束(请求/响应拦截器回调),用的NProgress 插件
 在请求拦截器中,
 显示进度条 /
 携带 token 、userTempId
 统一处理了请求错误
 每个请求自动携带 userTempId 的请求头,
 在响应拦截器中,对 token 过期的错误进行处理;需要注意的是,如果成功,返回的数
据是response.data, 而非 response
 二次封装axios使用示例
1.新建api文件夹 对请求进行集中管理
2.在api文件夹下 建立对应功能模块文件
3.在文件中导入 封装好的request函数

Instanceof的原理

如何判断?(原理)

- 对于A  Instanceof  B
- A是实例对象, B是构造函数
- 如果B的prototype属性所指向的原型对象是A实例对象的原型链上的某个对象, 返回true, 否则返回false

预解析

可以先调用函数,再声明函数,实现了函数可以在任何地方定义和声明

分为:全局预解析,局部预解析

好处:声明变量和函数更加方便,

预解析的时机:代码书写完毕之后,作用域就定下来了,打开页面,就是执行上下文环境,然后下一步就到了预解析,简单地说就是代码执行之前。

执行上下文

首先执行上下文是动态的,分为全局上下文和局部执行上下文,在代码执行之前,先出现预解析,然后出现全局执行上下文环境,设置this指向,收集var和function声明的变量和函数,有一个压栈的过程,此时在环境当中会出现作用域链,是存在数组里面的

如果有函数调用,同上,函数调用完毕之后出栈

作用域或执行上下文环境的理解

作用域是变量的使用范围,用来隔离变量,避免命名污染,分为全局作用域和局部作用域,函数中的是局部作用域,一层函数之外或script标签之内,是全局作用域.在书写代码完成之后,就书写了作用域,所以作用域是静态的,定义好了之后一直存在,且不会再变化,执行上下文环境是动态的,

十三、事件循环机制的理解(JS是单线程的,能做异步操作吗)

js是单线程执行的程序,只有一条主线,所以程序都是排队执行的,在这种情况可能出现问题,比如说setTimeout,ajax等执行的时间较长,执行代码时会很好使,是有几个通道的,

首先是调用栈,执行耗时较短的操作,耗时较长的操作先放置到任务队列中,任务队列又分为宏任务(macro-task)和微任务(micro-task),微任务中队列中放置的是 promise.then、aysnc、await 这样操作,宏任务队列中放置的是 setTimeout、ajax、onClick事件,等调用栈的任务执行完成再轮询微任务队列,微任务队列中任务执行完成之后再执行宏任务。

这里提到了栈和队列,简单说一下这两种数据结构,栈是一种后进先出的结构,只能从尾部进入,从尾部删除,拿生活中的场景来打比方,就好像自助餐的餐盘,最先放的盘子在最底下,最后放的盘子在最上面,需要把最上面的盘子一个个拿走,才能拿到最下面的盘子。

而队列,是一种先进先出的结构,从尾部进入,从头部删除,就像我们去排队买东西,先去的同学可以先买到。
再回到事件循环机制(event loop),不阻塞主进程的程序放入调用栈中,压入栈底,执行完了就会弹出,如果是函数,那么执行完函数里所有的内容才会弹出,而阻塞主进程的程序放入任务队列中,他们需要“排队”依次执行

十四、事件冒泡

所谓的事件冒泡指的是:标签或组件之间有嵌套关系,都绑定或注册了相同或类似的事件,如果内部的元素触发了,外部的元素自动触发,注册是 = 的方式,绑定是使用addEventListener或attachEvent

十五、关于路由鉴权的理解

上级主管添加新用户,并给用户分配角色。因为每个用户的角色不同,所以拥有的权限也都不同,那在登录系统后所能看到的页面,菜单,能够访问的路由地址,也是不一样的。
那在开发时就需要将所有路由进行拆分,
一种是所用用户都可以访问的路由--常量路由,可以直接进行路由注册。
一种是不是所有用户都能访问的路由--异步路由,需要之后进行筛选,动态进行注册。
还有一种在地址栏输入用户没有的路由,需要进入的路由---任意路由,重定向到404,因为任意路由可以和任何路由都匹配上,我们要保证当常量路由,异步路由都匹配不上时,再让他匹配任意路由。所以任意路由也要拆出来,并放在最后,方便后边筛选完异步路由之后进行合并。
首先,用户登录后拿到token,请求头携带token去获取用户信息,用户信息获取成功后 能拿到5个数据,用户名,用户头像,用户角色,路由权限标识数组,按钮权限标识数组。
接下来就可以进行路由鉴权。在pinia中导入拆分好的三种路由,封装过滤函数,内部使用filter,对异步路由进行过滤,判断当前路由name属性在路由权限标识数组中是否存在,如果存在,返回true,返回之前还有判断当前路由是否有子路由,如果有,则需要深度递归过滤子路由,把过滤后的数组返回,这个数组就是过滤完毕的该用户可以访问的异步路由.
由于过滤过程会修改原数组,所以需要在调用函数时,深拷贝异步路由。防止切换用户时,造成异步路由不全。
接下来把异步路由和任意路由合并一个数组(异步路由添加到最后一个),遍历当前数组调用addroute(s),注册到路由表中.合并同步路由和异步路由,赋值给仓库的menus,方便sidebar组件遍历,根据meta中的title显示用户可访问的路由菜单选项。
在退出登录时,需要删除所有路由,再重新添加常量路由。否则可能会出现有户没有该路由权限却可以输入地址访问该页面的情况。删除使用removeroute。
因为不同角色对同一页面能进行的操作不同,也就是增删改查等这些操作。所以还需要进行按钮权限鉴权。
通过自定义指令实现。可以在按钮组件标签上直接使用这个指令,绑定对应的按钮权限标识。自定义指令中可以在按钮挂载时拿到按钮的真实dom及指令中绑定的值。导入pinia中的按钮权限标识数组,如果指令中的按钮权限标识,在按钮权限标识数组中查不到,则表示该用户没有这个按钮的权限,需要将按钮删除,按钮的父节点调用removechild方法就可以删除

十六、说一说cookie、sessionStorage、localStorage 区别

1.都是浏览器存储 2.都存储在浏览器本地 区别: 1.cookie由服务器写入, sessionStorage以及localStorage都是由前端写入 2.cookie的生命周期由服务器端写入时就设置好的,localStorage是写入就一直存在,除非手动清除,sessionStorage是由页面关闭时自动清除 3.cookie存储空间大小约4kb, sessionStorage及localStorage空间比较大,大约5M 4.3者的数据共享都遵循同源原则,sessionStorage还限制必须是同一个页面 5.前端给后端发送请求时,自动携带cookie, session 及 local都不携带 6.cookie一般存储登录验证信息或者token,localStorage常用于存储不易变动的数据,减轻服务器压力,sessionStorage可以用来监测用户是否是刷新进入页面,如音乐播放器恢复进度条功能

十七、Promise的理解

Promise是异步微任务,解决了异步多层嵌套回调的问题,让代码的可读性更高,更容易维护 Promise使用:Promise是ES6提供的一个构造函数,可以使用Promise构造函数new一个实例,Promise构造函数接收一个函数作为参数,这个函数有两个参数,分别是两个函数 `resolve`和`reject`,`resolve`将Promise的状态由等待变为成功,将异步操作的结果作为参数传递过去;`reject`则将状态由等待转变为失败,在异步操作失败时调用,将异步操作报出的错误作为参数传递过去。实例创建完成后,可以使用`then`方法分别指定成功或失败的回调函数,也可以使用catch捕获失败,then和catch最终返回的也是一个Promise,所以可以链式调用。 Promise的特点: 1. 对象的状态不受外界影响(Promise对象代表一个异步操作,有三种状态)。 - pending(执行中) - Resolved(成功,又称Fulfilled) - rejected(拒绝) 其中pending为初始状态,fulfilled和rejected为结束状态(结束状态表示promise的生命周期已结束)。 2. 一旦状态改变,就不会再变,任何时候都可以得到这个结果。 Promise对象的状态改变,只有两种可能(状态凝固了,就不会再变了,会一直保持这个结果): - 从Pending变为Resolved - 从Pending变为Rejected 3. resolve 方法的参数是then中回调函数的参数,reject 方法中的参数是catch中的参数 4. then 方法和 catch方法 只要不报错,返回的都是一个fullfilled状态的promise 加分回答 Promise的其他方法: Promise.resolve() :返回的Promise对象状态为fulfilled,并且将该value传递给对应的then方法。 Promise.reject():返回一个状态为失败的Promise对象,并将给定的失败信息传递给对应的处理方法。 Promise.all():返回一个新的promise对象,该promise对象在参数对象里所有的promise对象都成功的时候才会触发成功,一旦有任何一个iterable里面的promise对象失败则立即触发该promise对象的失败。 Promise.any():接收一个Promise对象的集合,当其中的一个 promise 成功,就返回那个成功的promise的值。 Promise.race():当参数里的任意一个子promise被成功或失败后,父promise马上也会用子promise的成功返回值或失败详情作为参数调用父promise绑定的相应句柄,并返回该promise对象。

十八、Vuex的理解

Vuex是集中管理项目公共数据的。Vuex 有state、mutations 、getters、actions、module属性。 state 属性用来存储公共管理的数据。 mutations 属性定义改变state中数据的方法, 注意:不要在mutation中的方法中写异步方法ajax,那样数据就不可跟踪了 。 getters 属性可以认为是定义 store 的计算属性。就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。 action属性类似于 mutation,不同在于:Action 提交的是 mutation,而不是直接变更状态。Action 可以包含任意异步操作。 moudle属性是将store分割成模块。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块,从上至下进行同样方式的分割 使用方法: state :直接以对象方式添加属性 mutations :通过`store.commit`调用 action:通过 `store.dispatch` 方法触发 getters:直接通过store.getters.调用 加分回答 可以使用辅助函数mapState、mapMutations、mapAction、mapGetters一次性获取每个属性下对应的多个方法。 VueX在大型项目中比较常用,非关系组件传递数据比较方便

十九、map和foreach的区别

map 和 forEach 的区别:map有返回值,可以开辟新空间,return出来一个原数组一致的数组,即便数组元素是undefined或者是null。forEach默认无返回值,返回结果为undefined,可以通过在函数体内部使用索引修改数组元素。 加分回答 map的处理速度比forEach快,而且返回一个新的数组,方便链式调用其他数组新方法,
比如filter、reduce let arr = [1, 2, 3, 4, 5]; 
let arr2 = arr.map(value => value * value).filter(value => value > 10); // arr2 = [16, 25]

二十、组件通信的方式

Vue组件的通信方式分为两大类,一类是父子组件通信,另一类是任何关系类型组件通信(父子、兄弟、非兄弟) 父子组件的通信方式: 父给子传递数据,通过给子组件添加自定义属性,比如:``,list是父组件给子组件传递的数据。子获取父的数据,在子组件中使用props属性获取 子给父传递数据,通过给子组件传递父组件的方法,子组件调用父组件的方法传递数据,比如:`` ,deleteHandler就是父组件的函数,在子组件中通过this.$emit('方法名',参数),调用父组件的方法,并把数据传递到父组件。 props是只读,不可以被修改,所有被修改都会失效和被警告 任何关系类型组件通信(父子、兄弟、非兄弟)方式: EventBus: 使用方法是创建一个新的Vue实例,需要通信的组件都引入该Vue实例,传递数据的组件使用` event.$emit('名称',参数)`发送数据,接收数据的组件使用 `event.$on('名称',方法)`接收数据。 VueX: 集中管理项目公共数据,Vuex 的状态存储是响应式的,当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。 加分回答 EventBus的优缺点,缺点vue是单页应用,如果你在某一个页面刷新了之后,与之相关的EventBus会被移除,这样就导致业务走不下去。同时如果页面中有反复操作的业务,EventBus在监听的时候就会触发很多次,需要好好处理EventBus在项目中的关系。在vue页面销毁时,同时移除EventBus事件监听。优点,解决了多层组件之间繁琐的事件传播,使用原理十分简单,代码量少。适合业简单,组件传递数据较少的项目,大型项目业务复杂的还是尽量使用VueX

二十一、为什么data必须为一个方法且返回值必须是一个对象

因为对象是引用数据类型,会在堆内存中开辟一个空间,将内存地址写入,这就使得所有的组件共用一个data,如果有一个组件中修改了data的数据,所有的数据都会跟着变,而使用返回对象的函数,由于每次返回的都是一个全新的data,引用地址不同,则不会出现这个问题,从函数作用域来看,当组件被复用时,函数与函数之间是有作用域的,所以两个不同作用域之间也应该互不干扰,数据不会受影响。

二十二、vue2与vue3的区别

1.vue2和vue3双向数据绑定原理发生了改变
vue2的双向数据绑定是利用了es5 的一个API:Object.definepropert() 对数据进行劫持,结合发布订阅模式来实现的。
vue3中使用了es6的proxyAPI对数据进行处理。
相比与vue2,使用proxy API 优势有:defineProperty只能监听某个属性,不能对全对象进行监听;可以省去for in 、闭包等内容来提升效率(直接绑定整个对象即可);可以监听数组,不用再去单独的对数组做特异性操作,vue3可以检测到数组内部数据的变化。
2.vue2用的是选项式API,vue3是组合式API:选项式api在代码里分割了不同得属性:data,computed,methods等;组合式api可以使用方法来分割,相比于选项式API使用属性来分组,这样代码会更加简便和整洁
3.vue2中有this,vue3中没有,vue3中有setup语法糖
4.vue2只能有一个根节点,vue3中可以有多个

二十三、关于闭包的理解

闭包其实就是一种嵌套关系,当嵌套的内部函数引用了外部函数的变量时就形成了闭包,当外部函数调用时,执行了内部函数定义时就产生了闭包,闭包可以让函数作用域中的变量在函数执行结束后会被销毁,同时也可以让函数外部可以访问函数内部的局部变量,由于垃圾回收机制不会将闭包中的变量销毁,于是就造成了内存泄漏,积累多次后的内存泄漏不被回收就会导致内存溢出。

二十四、关于this的理解

常规情况下,函数中的this取决于执行函数的方式:直接调用时this指向window;当new时,this指向是创建的实例对象;通过对象调用时this指向调用的这个对象;箭头函数是没有this的,指向外部作用域的this。

二十五、如何在作用域链中查找一个变量

先在对象自身上查找,如果有,直接返回,如果没有,根据__proto__(隐式原型对象)在原型对象上查找,如果有,直接返回,否则就沿着原型对象的隐式原型对象一直找,一直找到Object原型对象为止,还是没有的话为null,返回undefined。

二十六,BFC

bfc是一个块级格式化区域,开启bfc就不会被浮动的元素覆盖了,而子和父元素可以解决一个外边距重叠,可以包含主一个子元素,开启bfc方式有很多

二十七 ,http和https的区别

http是超文本传输协议,他的传输方式是明文传输的,所以他的安全性相对较低,端口号是:80

https是具有安全性的ssl加密传输协议,端口是:443

200成功

301重定向状态

400客户端错误

500服务器错误

二十八.地址栏输入一串网页地址,背后发生了什么

浏览器会先查看浏览器缓存,然后系统缓存,路由缓存,如果存在缓存就直接显示,没有的话就进行下一步,域名解析来获取对应的一个ip,然后浏览器向服务器发送TCP链接并且要与这个浏览器建立,tcp的第三次握手,最后就是解析cs的样式

二十九路由懒加载/图片懒加载

路由懒加载

就是只加载你当前点击的那个模块,按需去加载路由对应的资源,提高首屏加载速度

图片懒加载
也叫延迟加载或按需加载,比如图片延迟加载或符合某些条件时才加载某些图片。

document.documentElement.clientHeight//获取屏幕可视区域的高度
document.documentElement.scrollTop//获取浏览器窗口顶部与文档顶部之间的距离,也就是滚动条滚动的距离
element.offsetTop//获取元素相对于文档顶部的高度

clientHeight+scroolTop>offsetTop,则图片进入了可视区内,则被请求。

三十.父子组件的加载顺序与销毁顺序

1、父子组件的加载顺序为
 父beforeCreated ->父created  ->父beforeMounted ->子beforeCreated ->子created  ->子beforeMounted ->子mounted -> 父mounted

 2、父子组件销毁顺序为**
 父beforeDestroy->子beforeDestroy->子destroyed->父destroyed

三十一:v-if和v-for不能一起用

v-for和v-if不能一起使用的原因是,v-for是用来循环渲染列表的指令,而v-if是用来条件判断是否渲染元素的指令。如果在同一个元素上同时使用v-for和v-if,会导致渲染出来的结果不符合预期,因为v-if会影响v-for的循环次数,从而导致列表渲染出错。

axios 和 ajax 的区别

axios是基于promise实现的对 ajax 技术的一种封装,两者用法基本一样,个别参数不同,

axios 封装了一些更简便的 ajax 操作。

说说你项目中的axios的二次封装

配置通用的基础路径和超时,显示请求进度条,和一些统一的处理错误,如果当前有token,自动携带token的请求头,对token过期的错误进行处理

JS的事件循环机制

js内部是通过事件循环机制来实现单线程异步执行任务的  浏览器中有辅助异步单线程的分线程管理模块 
 主要管理异步操作 事件轮训机制的本质 代码从上而下执行 遇到定时器 DOM ajax的回调 都有对应的管理模块
  整体执行顺序是先同步 再异步  异步中待执行队列分为两个队列 
一个宏队列 一个微队列  整体流程为  先执行整体代码 
 然后再执行微队列中的微任务 执行完毕后 再执行第一个宏队列中的宏任务 第一个宏任务执行完 如果还有微任务 
就会先把微队列中的微任务执行完毕 再执行宏队列里的任务 这样循环处理 就是js的循环机制

谈谈对路由的理解

(路由,路由器,路由的使用,路由跳转的实现,路由跳转的控制-路由守卫)
vue是 spa单页面应用 - 实现页面跳转,用的是路由;
路由指的是一种映射关系,是地址和组件的关系 (path, component),也就是一个对象,
对象中可以有 path/component/name/children/meta/props 属性;路由对象会存储在一个容器中,也就是 routes 数组中,当一个组件被注册路由时,该组件被称为路由组件;
路由器 router 是一个对象,用来设置路由的模式和管理路由;
路由器一旦注册成功(new Vue中),此时在浏览器的地址栏中,输入地址回车,就可以看到这个地址注册时对应的组件内容(前提是使用了 router-view);
<router-view /> 是路由视图,用来显示路由组件;
<router-link  to=""/>是路由链接,最终会编译成 a 标签,to 属性存储的是地址,最终会编译成 a 标签中的 href 属性;
这就是声明式路由;
**声明式路由的理解**:指的就是 router-link  , 不需要书写 JS 代码,就可以实现路由跳转;
**编程式路由的理解**:指的是通过 JS 代码,路由器对象调用 push/replace 方法,来实现路由跳转;
但是路由不能随意跳转成功:
**导航守卫的理解**:用来控制路由跳转,有 3 种路由守卫方式,全局导航守卫、路由独享守卫、组件内守卫,一共有 7 个,最常用的是 beforeEach(),接收3个参数 to, from, next。   
**路由传参**:路由跳转的时候可以携带参数,携带参数的方式有 params , query , props, meta 这4种;params 传参需要占位 (/:表达式),使用 ?可以设置参数可有可无,可以配合 name 属性使用,query 传参使用 ? 开头,键值的方式,多个键值之间用 & 符号连接,可以配合 path 和 name 使用,props 传参有 布尔/对象/函数模式,可以解耦 $route 对象;
meta中 可以绑定 title, icon 及其他属性,用来进行传参,可以控制路由跳转时部分组件的显示/隐藏,在后台项目中,用 meta 中的 title, icon, 来设置页面的标题和菜单的图标;
**路由原理的本质**:使用的是 浏览器的 BOM 对象中的 location 对象 和 history 对象来实现的,声明式路由是 location.hash 来实现的,编程式路由的本质 是 history 对象中的 pushState 和 repalceState 来实现的,路由参数获取的本质 是  history 对象中的 state属性,
路由挑战以后,设置页面的初始位置,用的是 scrollBehavior 控制坐标;
以上就是我对路由的简单理解。

*vue组件间有哪些通信方式**

\1) 父向子   

props(非函数)

v-model

$refs, $children

插槽

\2) 子向父

props(函数)

vue自定义事件

v-model

.sync

$parent

作用域插槽

\3) 祖孙间

$attrs与$listeners 与v-bind/v-on配合使用

provide与inject

\4) 兄弟或其它/任意

全局事件总线

Vuex

Promise中的all方法

Promise.all([p1, p2, p3])

接收包含多个promise的数组, 返回一个新的promise

只有当所有接收的promise都成功了, 返回的promise才成功, 且成功的value为所有成功promise

的value组成的数组

一旦有一个失败了, 返回的promise就失败了, 且失败的reason就是失败promise的reason

Promise.race([p1, p2, p3])

接收包含多个promise的数组, 返回一个新的promise

返回的promise的结果由第一个完成的promise决定

项目介绍

1.是一个关于商城的后台管理系统,主要用到的技术栈是vue3+ts做的,主要做的功能是登入和权限管理,和一些sku和spu,和一些根据下拉框的分类,选择对应展示的数据,例如查找一些茶叶的产地,和茶叶的品类展示对应的茶叶信息的页面,

登入就是用户输入相关的用户信息,然后进行表单校验,不通过,就返回错误,前台携带数据发请求,后台将用户信息和token返回给前台,前台将用户信息和token存储到vuex仓库,将token保存到本地localStorage中,跳转来时的页面,用户的token是有过期时限的,token时限一般是在后台做的

权限主要是开始只注册用户可以看到的常量路由,登入请求成功后,根据token获取用户和权限数据,并根据权限生成权限路由并动态祖册

通过deepClone从所有的异步路由的数组中过滤出当前用户的权限路由,然后通过router.addRoute() 动态挂载这些路由,将用户的权限路由与常量路由合并用来显示左则导航菜单

搜索相关功能的实现流程(联想、历史记录、热点词) 搜索框内容变化根据搜索框中内容向后台发送请求,后台返回关联词汇;

后台项目安全性优化

为了保证安全性,我司现在后台所有token有效期都是Session,就是当浏览器关闭了就丢失了。重新打开游览器都需要重新登录验证,后端也会在每周固定一个时间点重新刷新token,让后台用户全部重新登录一次,确保后台用户不会因为电脑遗失或者其它原因被人随意使用账号。

项目中遇到的问题

问题1:
 element的from的item高有问题没办法由内容撑开
 解决:
 在from上加一个size=“mini”规范from就好了
 
问题2;路由权限控制中的bug
如果a用户登入,退出后用b用户登入,结果只能看见部分的权限路由,因为我们过滤异步路由的数组中,过滤掉了内部的路由,另一个用户看不见,用深拷贝进行过滤就可以了

前端项目的优化

 路由懒加载 图片懒加载
 搜索框的防抖设置,减小服务器的压力
 频繁切换使用 v-show,不频繁切换使用 v-if
 v-if 和 v-for 不连用
 console.log()删除
懒加载
节流
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值