前端常见题目4

1.vuex的基础解析

Vuex 是一个专为 Vue.js 应用程序开发的状态管理插件。它采用集中式存储管理应用的所有组件的状态,而更改状态的唯一方法是提交mutation。

其中的5个属性分别是state,actions,mutations,getters,modules

state

在state中存储的值,要通过mutation里面注册一个mutation并在组件中使用this.$store.commit提交mutation来改变state中的值。

actions

与mutation不同的是,action可以包含异步操作,mutation只能用于同步操作,action用于提交mutation,提交的方式也不同。action是用 this.$store.dispath('ACTION_NAME',data), 而mutation是用this.$store.commit('ACTION_NAME',data)。并且接收参数不同,mutation第一个参数是state,而action第一个参数是context。

mutations

  • 如在组件中多次提交一个函数,使用mapMutations辅助函数。
  • 注意必须是同步的函数。
  • 在mutation中不可以访问全局的satat和getter,只能访问到局部的state。
  • 在带命名空间的模块内提交全局的mutation和action,将 { root: true } 作为第三参数传给 dispatch 或 commit 即可。this.$store.dispatch('actionA', null, { root: true }) ``this.$store.commit('mutationA', null, { root: true })

getters

getter属性,相当Vue中的计算属性computed,只有原状态改变派生状态才会改变。 getter接收两个参数,第一个是state,第二个是getters(可以用来访问其他getter)。 然后在组件中可以用计算属性computed通过this.$store.getters.total这样来访问这些派生转态。

 

javascript

复制代码

computed: { total() { return this.$store.getters.total } }

modules

使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。所以将 store 分割成模块(module)。每个模块拥有自己的 state、mutations、actions、getters,甚至是嵌套子模块,从上至下进行同样方式的分割。

2.vue父子组件的生命周期

父beforeCreate→父created→父beforeMount→子bereforeCreate→子created→子beforeMound→子mounted→父mounted

父子组件更新过程

父beforeUpdate→子beforeUpdate→子updated→父updated

created和mounted的区别

created创建vue实例之后,此时已经完成了数据检测和事件及配置,可以访问data数据,,可以进行网络请求。created是在模板渲染成html前调用,所以不能进行dom操作 mounted是组件挂载完毕,模板渲染成html之后调用,可以进行dom相关的操作。

3.原型链里面有原型对象、构造函数、数据对象他们之间有什么关系

每当我们new一个函数出来,该属性都会自带一个prototype属性,该属性就是一个指针指向原型对象. 原型对象默认都有一个属性constructor,这个属性也是一个指针,指向相关联的构造函数。 通过调用构造函数产生的实例对象,都拥有一个内部属性,指向了原型对象。三者的关系是,每个构造函数都有一个原型对象,原型对象上包含着一个指向构造函数的指针,而实例都包含着一个指向原型对象的内部指针。

4.v-if和v-show的区别

v-show

  • 原理是修改元素的的CSS属性(display)来决定实现显示还是隐藏
  • 值为真(true)的时候元素显示,值为假(false)的时候元素隐藏
  • 传值会解析为布尔值

v-if

  • v-if指令的作用:根据表达式的真假切换元素的显示状态
  • v-if = "表达式"
  • 本质是通过操纵dom元素来进行切换显示
  • 表达式的值为true的时候元素存在于dom树中,为false的时候从dom树中移除

v-if需要操作dom元素,有更高的切换消耗,v-show只是修改元素的的CSS属性有更高的初始渲染消耗,如果需要非常频繁的切换,建议使用v-show较好,如果在运行时条件很少改变,则使用v-if较好

5.上传一个文件需要配置那些参数

  • 1.验证文件大小,文件大于预设值则提示错误信息
  • 2.中文乱码处理
  • 3.验证文件类型
  • 4.允许上传文件个数验证

上传参数
与普通的post传参不同,在上传文件时候应该配置一下请求头。 content-type: multipart/form-data;

6.说一下防抖和节流,以及他们应用的场景

防抖

有的操作是高频触发的,但是其实触发一次就好了,比如我们短时间内多次缩放页面,那么我们不应该每次缩放都去执行操作,应该只做一次就好。再比如说监听输入框的输入,不应该每次都去触发监听,应该是用户完成一段输入后在进行触发。

防抖就是防止抖动,避免事件的重复触发

总结:等用户高频事件完了,再进行事件操作。

节流 防抖存在一个问题,事件会一直等到用户完成操作后一段时间在操作,如果一直操作,会一直不触发。比如说是一个按钮,点击就发送请求,如果一直点,那么请求就会一直发布出去。这里正确的思路应该是第一次点击就发送,然后上一个请求回来后,才能再发。

节流就是减少流量,将频繁触发的事件减少,并每隔一段时间执行。即,控制事件触发的频率,减少接口数据的请求

总结:某个操作希望上一次的完成后再进行下一次,或者希望隔一段时间触发一次。

7.说一下ES6常用语法

  • 块级作用域(let、const)

let定义的变量可以改变值,const定义的都是静态变量,不可以修改的

但是像数组,只对数据进行push操作的话,也可以定义成const的(不动用之前的数组值)。

  • 模版字符串

反引号(``),变量(${})

  • 解构赋值

从数组和对象中提取值 ,对变量进行赋值 ,这被叫作解构赋值。

  • 箭头函数

箭头函数作为普通函数的一个补充,将this指向了函数体之外最近一层的this,而不是向普通JS一样将this指向window变量。

  • 剩余参数&扩展运算符

剩余参数是把参数转成数组,扩展运算符是把数组转成非数组。

  • 对象新增方法,Object.assign()

//扩展运算符,合并数组 let arr1 = [1,3,5]; let arr2 = [2,4,6]; let arr3 = [...arr1, ...arr2]; // arr3 == [1,3,5,2,4,6];

// 或者 arr1.push(...arr2); // arr1 = [1,3,5,2,4,6];

  • Set和Map数据结构

Set类似于数组,但是成员的值都是唯一的,没有重复的值。

Map是类似Object的一种键值对集合

  • promise对象

    • 异步编程的一种解决方案
    • 从语法上说,Promise是一个对象,从它可以获取异步操作的消息;
      • 对象的状态不受外界影响;Promise对象代表一个异步操作,有三种状态:pending(进行中)、fufilled(已成功)、rejected(已失败);只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态
      • 一旦状态改变,就不会再变,任何时候都可以得到这个结果;Promise对象的状态改变,只有两种可能:从pending变为fulfilled 和 从pending变为rejected;只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这是就称为resolved;如果改变已经发生了,再对Promise对象添加回调函数,也会立即得到这个结果;这与事件Event完全不同,事件的特点是,如果错过了它,再去监听,是得不到结果的

Promise构造函数接收一个函数作为参数,该函数的两个参数分别是resolve和reject;它们是两个函数

resolve函数的作用是,将Promise对象的状态从pending变为resolved,在异步操作成功时调用,并将异步操作的结果,作为参数传递出去

reject函数的作用是,将Promise对象的状态从pending变为rejected,在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去

Promise实例生成以后,可以用then方法分别指定resolved状态和rejected状态的回调函数

 

const promise = new Promise(function(resolve,reject){

if(/*异步操作成功*/ )

{ resolve(value); }

else{ reject(error); }

})

promise.then(function(value){ //success },function(error){ //failure })

  • asyn 和 await 函数

async 会将其后的函数的返回值封装成一个 Promise 对象, 而 await 会等待这个 Promise 完成,并将其 resolve 的结果返回出来。

如果async函数内没有await, 那么async没有意义的, 全是同步的内容. 注意:只有await往后的才是异步代码 // 使用async/await获取成功的结果 //

定义一个异步函数,3秒后才能获取到值(类似操作数据库)

function getSomeThing(){ return new Promise((resolve,reject)=>{ setTimeout(()=>{ resolve('获取成功') },3000) }) }

async function test(){ let a = await getSomeThing(); console.log(a) } test(); // 3秒后输出:获取成功

  • es6模块化 中 import和export 用法
  1. export命令可以出现在模块的任何位置,但必须处于模块顶层。
  2. import命令会提升到整个模块的头部,首先执行。
  3. export default 向外暴露的成员,可以使用任意变量来接收。

8.说一下操作数组的方法

1,push 尾部添加 数组本身改变 返回值 是数组的长度

2,pop 尾部删除 数组本身改变 返回值 返回删除的数组

3,shift 头部删除 数组本身改变 返回值 返回删除的元素

4,unshift 头部添加 数组本身改变 返回值 是数组的长度

5,sort 排序 数组本身改变 返回值 排序后的数组

6,reverse 反转 数组本身改变 返回值 反转后的数组

7,splice 删除 添加 替换 arr.splice(下标,长度,插入的值)

9.说一下vue双向绑定原理

我们通过Object.defineProperty的get方法用来获取值 set方法用来拦截设置值

双向绑定的核心:

Object.defineProperty() var obj = {}; //定义一个空对象

Object.defineProperty(obj, 'val', {//定义要修改对象的属性 get: function () { console.log('获取对象的值') },

set: function (newVal) { console.log('设置对象的值:最新的值是'+newVal); } }); obj.hello = 'hello world'

发布订阅模式

他定义了一种一对多的依赖关系,即当一个对象的状态发生改变的时候,所有依赖他的对象都会得到通知。发布者发布消息所有订阅者都会接收到。

10.HTML页面加载和解析流程

1.用户输入网址,浏览器向服务器发送请求,服务器返回html代码。

2.浏览器开始加载html代码,发现标签里的引入css文件

3.浏览器又发出css文件的请求,服务器返回css文件代码

4.此时浏览器开始解析body中的代码,并且此时css文件已经到手了,可以开始渲染页面了

5.接下来加载服务器中返回html中的图片文件,并将css一并渲染

6.当浏览器发现

重排(回流)

意味着元件的几何尺寸变了,需要重新验证并计算渲染树。是渲染树的一部分或全部发生了变化。

重绘

屏幕的一部分重画,不影响整体布局,比如某个CSS的背景色变了,但元素的几何尺寸和位置不变。

尽量减少重排与重绘。重排要比重绘更花费时间,也就更影响性能。所以在写代码的时候,要尽量避免过多的重排。

引起重排的情况

  (1)页面初始化时;

  (2)操作DOM时;

  (3)某些元素的尺寸改变;

  (4)CSS 的属性发生变化。

减少重排/重绘

  (1)不要一个个的修改 DOM 的样式。应通过 class 来修改。

  (2)为动画的 HTML 元素使用 position: absoult,那么修改它的 CSS 是不会重排的。

  (3)尽量不要使用 table 布局。可能很小的一个改动会造成整个 table 的重排。

11.怎么让Chrome支持小于12px的文字

Chrome中文版浏览器默认设定页面的最小字号是12px,英文版的没有限制。如果文本需要以更小的字号来显示,就需要编写代码的时候就设置好。

解决的方法包括:

css

zoom:变焦; -webkit-transform:scale():放缩; -webkit-text-size-adjust:none:根据设备(浏览器)来自动调整显示大小。

12.$nextTick

理解: nextTick(),是将回调函数延迟在下一次dom更新数据后调用,简单的理解是:当数据更新了,在dom中渲染后,自动执行该函数,

  • 在Vue生命周期的created()钩子函数进行的DOM操作一定要放在Vue.nextTick()的回调函数中
  • 在数据变化后要执行的某个操作,而这个操作需要使用随数据改变而改变的DOM结构的时候,这个操作都应该放进Vue.nextTick()的回调函数中。

13.vue中ref与document.querySelector()的区别

ref用在template中的标签中时(用于得到该标签的dom元素) 方法中使用 this.$refs.上面标签中ref的属性

document.getElementById(""),与ref作用相似,区别在于原生在使用是要将id暴露在标签中,而ref不用

14.动态路由

权限管理-动态路由

 

markdown

1. 路由分为两大模块 1. 静态路由:登录页,主页,404等 不需要权限的页面 2. 动态路由:需要权限管理的页面 3. 默认为静态路由 2. 在获取到用户信息后 1. 用户信息中包括当前用户能访问的权限页面的数据 2. 通过动态路由匹配出能访问的路由信息 3. 通过addRoutes动态添加到路由上

创建动态路由

将路由数据通过foreach方法转化为一维数组

15.说一下请求的状态码有那些,其中的404、405、503等常见的状态码分别代表什么意思

  • 200 请求成功

  • 206 部分内容

  • 301 永久重定向

  • 302 临时重定向

  • 400 错误请求

  • 401 未经授权

  • 403 禁止访问

  • 404 请求错误

  • 500 内部服务器错误

  • 502 错误网关

    状态码为405表示请求的方式不对

    状态码为503

    503错误是一种HTTP状态码。英文名503与404是同属一种网页状态出错码。两者的区别是:前者是服务器出错的一种返回状态,后者是网页程序没有相关结果后返回的一种状态。

16.适配移动端有哪些方案

1. 响应式布局,通过@media实现一套html配合多套css实现适配;也可以设置设备适配,在不同设备上显示不同的效果,通常都是写两套css,一套移动端一套pc端。

2. 通过rem或者vw,vh等实现不同的设备按照相同的比例适配;

17.vueRouter的两种模式分别应用在什么场景

浏览器提供hash 和history 两种模式支持(可以说,hash 模式和 history 模式都属于浏览器自身的特性),Vue-Router 只是利用了这两个特性(通过调用浏览器提供的接口)来实现前端路由。

一般场景下,hash 和 history 都可以,除非你更在意颜值,# 符号夹杂在 URL 里看起来确实有些不太美丽。 如果不想要很丑的 hash,我们可以用路由的 history 模式,这种模式充分利用history.pushState API 来完成URL 跳转而无须重新加载页面。 —— Vue-router 官网。

注意:无论hash值如何变化,服务器接收到的HTTP请求中url永远是#前面的对后端完全没有 影响,因此改变 hash 不会重新加载页面。

注意:history模式更改url不会向后端发送请求,但是如果点击刷新,就会向后端发送请求。、

总结:hash更适合前端自娱自乐,开发期间随便玩。history则适合在向后端发送请求时使用。

18.前端如何去解决跨域问题

跨域,是指浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对JavaScript实施的安全限制。

如何解决跨域?

  • jsonp(现在已经不怎么用了)

  • 跨域资源共享(CORS) 普通跨域请求:只在服务端设置Access-Control-Allow-Origin即可,前端无须设置,若要带cookie请求,则前后端都需要设置。

  • nginx代理跨域 - node.js中间件代理跨域

    node中间件实现跨域代理,原理大致与nginx相同,都是通过启一个代理服务器,实现数据的转发,也可以通过设置cookieDomainRewrite参数修改响应头中cookie中域名,实现当前域的cookie写入,方便接口登录认证。

  • vue跨域

配置webpack.config.js中的参数

module.exports = { entry: {}, module: {}, ... devServer: { historyApiFallback: true, proxy: [{ context: '/login', target: 'http://www.demo2.com:8080', // 代理跨域目标接口 changeOrigin: true, secure: false, // 当代理某些https服务报错时用 cookieDomainRewrite: 'www.demo1.com' // 可以为false,表示不修改 }], noInfo: true }

}

正在学习写项目,顺便复习知识点

 

csharp

复制代码

1) 跳转路由的2种基本方式         声明式: <router-link to="">         编程式: this.$router.push()/replace()   2) 跳转路由携带参数的2种方式         params参数         query参数   3) 面试问题1: 描述: 编程式路由跳转到当前路由(参数不变), 会抛出NavigationDuplicated的警告错误     解决1: 在跳转时指定成功或失败的回调函数, 通过catch处理错误 解决2: 修正Vue原型上的push和replace方法 (优秀)   4) 面试问题2: 如何指定params参数可传可不传?     path: '/search/:keyword?'   5) 面试问题3: 指定params参数时可不可以用path和params配置的组合? 不可以用path和params配置的组合, 只能用name和params配置的组合 query配置可以与path或name进行组合使用   6) 面试问题4: 如果指定name与params配置, 但params中数据是一个"", 无法跳转     解决1: 不指定params 解决2: 指定params参数值为undefined   7) 面试问题5: 路由组件能不能传递props数据?     可以: 可以将query或且params参数映射/转换成props传递给路由组件对象 实现: props: (route)=>({keyword1:route.params.keyword, keyword2: route.query.keyword })

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值