面试汇总

1.自我介绍
2.vue 父传子(props)

 子组件中定义 props属性,在父组件中使用;可以是动态的也可以是静态的;
 
子传父($emit)
父组件中定义的函数事件,子组件可以使用 $emit 触发父组件的自定义事件,并传参;

$emit/$on
vm.$emit( event, arg ) //触发当前实例上的事件
vm.$on( event, fn );     //监听event事件后运行 fn; 
必须作用在同一个实例上;

3.路由传参params/query/:id 区别;
传参可以使用params和query两种方式。

  • 使用params传参只能用name来引入路由,即push里面只能是name:’xxxx’,不能是path:’/xxx’,因为params只能用name来引入路由,如果这里写成了path,接收参数页面会是undefined!!!。
  • 使用query传参使用path来引入路由。
    params是路由的一部分,必须要在路由后面添加参数名。query是拼接在url后面的参数,没有也没关系。
  • 二者还有点区别,直白的来说query相当于get请求,页面跳转的时候,可以在地址栏看到请求参数,而params相当于post请求,参数不会再地址栏中显示。

params:

<router-link :to="{name: 'goto', params: {name:'zs', age:18}}">跳转</router-link>

//获取路由
console.log(this.$route.params);

//{name: "zs", age: 18},但是当刷新就获取不到路由了;

<router-link :to="{path: '/goto', params: {name:'zs', age:18}}">跳转</router-link>

//获取路由
console.log(this.$route.params);

//{},无法获取路由;

query:

<router-link :to="{name: 'goto', query: {name:'zs', age:18}}">跳转</router-link>

//获取路由
console.log(this.$route.query);

//{name: "zs", age: 18},但是当刷新依然可以获取;

<router-link :to="{path: '/goto', query: {name:'zs', age:18}}">跳转</router-link>

//获取路由
console.log(this.$route.query);

//{name: "zs", age: 18},但是当刷新依然可以获取;

4.路由定义中加/和不加/的区别;

/ 是根路由,不加/是子路由。

4.路由定义中加/和不加/的区别;

/ 是根路由,不加/是子路由。

5.watcher,监听字符串和对象的区别;如果要监听对象怎么写?
监听不到对象,内部的属性,deep:true

6.export default 和export{} 的区别;

导出常量、函数、模块、文件等
 export default.在一个文件或模块中 只能有一个;
引入用 import 不加花括号

export在一个文件或模块中 可以有多个
引入用 import 加花括号

7.es6中{}的作用;解构语法

同名变量解构赋值:
a = {n1:21,n2:31}
{n1,n2} = a;
console.log(n1);//21

不同名变量解构赋值:
a = {n1:21,n2:31}
{n1:type1,n2:type2} = a;
console.log(type1)//21

[]数组解构:
 互换2个位置,排序时很有用;

实际应用参数解构:

// options 上的属性表示附加参数
function setCookie(name, value, options) {
       options = options || {};
       let secure = options.secure,
       path = options.path,
       domain = options.domain,
       expires = options.expires;
       // 设置 cookie 的代码
}
//可以改写为:对options进行解构并赋予默认值
function setCookie(name, value, { secure, path, domain, expires } = {}) {
// ...
}

8.vue中 ref的作用;
用在普通元素上:绑定一个dom元素,在使用的时候同id一样;用this.ref.name 获取到的是dom元素

<div ref="test">test</div>
console.log(this.$refs.test)

ref 加在子组件上,用this.ref.name 获取到的是组件实例,可以使用组件的所有方法

9.element ui 提交表单,按钮和表单在不同的组件中,如何通过点击

事件触发,其他组件的表单验证;
组件间的事件传递:
子调父: $emit();子组件通过$emit(),调用父组件中的事件;
父调子:在子组件中定义ref, 从父组件中使用this.$ref.name获取到子组件的vue实例,调用子组件中的方法;

水滴一面
1.看过vue源码吗?
2.axios封装?
3.MVVM?
4.开发的时候什么数据存储在vuex中?
5.store中数据更新在vue的哪个生命周期?

本组件内data的数据和prop传递过来的数据能同步双向绑定和更新视图
 vuex 中store的数据需要放到computed 里面才能同步更新视图

生命周期:

Vue生命周期
beforeCreate(创建前): 在数据观测和初始化事件还未开始,data、watcher、methods都还不存在,但是$route已存在,可以根据路由信息进行重定向等操作。

created(创建后):在实例创建之后被调用,该阶段可以访问data,使用watcher、events、methods,也就是说 数据观测(data observer) 和event/watcher 事件配置 已完成。但是此时dom还没有被挂载。该阶段允许执行http请求操作。

beforeMount (挂载前):将HTML解析生成AST节点,再根据AST节点动态生成渲染函数。相关render函数首次被调用(划重点)mounted (挂载后):在挂载完成之后被调用,执行render函数生成虚拟dom,创建真实dom替换虚拟dom,并挂载到实例。可以操作dom,比如事件监听

beforeUpdate:v m . d a t a 更 新 之 后 , 虚 拟 d o m 重 新 渲 染 之 前 被 调 用 。 在 这 个 钩 子 可 以 修 改 vm.data更新之后,虚拟dom重新渲染之前被调用。在这个钩子可以修改vm.data更新之后,虚拟dom重新渲染之前被调用。在这个钩子可以修改vm.data,并不会触发附加的冲渲染过程。

updated:虚拟dom重新渲染后调用,若再次修改$vm.data,会再次触发beforeUpdate、updated,进入死循环。

beforeDestroy:实例被销毁前调用,也就是说在这个阶段还是可以调用实例的。

destroyed:实例被销毁后调用,所有的事件监听器已被移除,子实例被销毁。

Vue在哪个生命周期阶段调用异步请求最佳

异步请求在哪个阶段都可以调用,因为会先执行完生命周期的钩子函数之后,才会执行异步函数,但如果考虑用户体验方面的话,在created中调用异步请求最佳,用户就越早感知页面的已加载,毕竟越早获取数据,在mounted实例挂载的时候就越及时。

6.用过vue 的哪些插件?怎么引入的?

图片剪裁(vue-img-cutter)  @click='cut'
pdf预览(vue-pdf),总页数,地址;
链接生成二维码,(qrcodejs2)
热力图(heatmap.js ),
echars。


npm intall XXX --save-dev
import XXX from ...;
定义组件,使用组件;

7.vue-cli 常用插件集合?
插件

8.vue-cli2 和vue-cli3 的区别?

vue-cli3是基于webpack4打造,vue-cli2是基于webpack3

7.用element ui时有什么怪异的问题吗?
表格组件

8.可以说一下实现webpack自动化开发?

我们定义好 entry,入口,webpack会找到入口直接间接的依赖,每个依赖随机被处理,输出到bundles 。
output 将输出文件bundles 放在指定的目录默认为 dist
module ,webpack 中都是模块,会从entry中递归找到所有的依赖的模块
loader:将所有文件类型处理成webpack 可以理解的js代码;然后进行处理
plugin:从打包优化压缩到重新定义环境中的变量,又极其强大的功能; 

9.如何解决浮点数加减法问题?

10.写过插件吗?

1.前后端分离登录实现。
开发单页应用,前端token 存在localStorage 中,会出现的问题,token过期后,刷新页面会直接跳转到后端页面再跳转到登录页面如何解决。
登录过期之后会出现的问题;请求守卫。

 axios.interceptors.response.use(
  response => {
    if (response.data.errno === 999) {
      router.replace('/');
      console.log("token过期");
    }
    return response;
  },
  error => {
    return Promise.reject(error);
  }
);

2.有一个数组查找两个下标相加等于n的下标;
一层循环:

var $arr = [12,31,6,8,19,20,3,5];
先将数组整理成 var obj = {n-12:{k:0,v:12},n-31:{k:1,v:31}}

循环$arr 或者 obj 去查找;

3.css和js是同步加载还是异步加载?
默认情况javascript是同步加载的,javascript的加载时阻塞的,后面的元素要等待javascript加载完毕后才能进行再加载,如何解决这个问题呢?
defer,只支持IE ;
defer 属性规定是否对脚本执行进行延迟,直到页面加载为止。

    <script type="text/javascript" defer="defer"> 
alert(document.getElementById("p1").firstChild.nodeValue); 
</script> 

async的定义和用法(是HTML5的属性)
async 属性规定一旦脚本可用,则会异步执行

<script type="text/javascript" src="demo_async.js" async="async"></script>

注释:async 属性仅适用于外部脚本(只有在使用 src 属性时)。

回调函数
创建一个script标签,然后在什么时候需要加载时候将script标签添加到回调函数中;

css异步加载:
媒体查询:

<link rel="stylesheet" href="./index.css" media="none" onload="this.media='all'">

这样浏览器将会异步加载这个CSS文件(优先度比较低),在加载完毕之后,使用onload属性将link的媒体类型设置为all,然后便开始渲染

<link rel="stylesheet" href="./index1.css" media="screen and (max-width: 800px)">
<link rel="stylesheet" href="./index2.css" media="screen and (min-width: 800px)">
//宽度小于800加载index2.css
//宽度大于800加载index1.css

提前加载资源:浏览器支持率低;

<link rel="preload" href="./index.css" as="style">

//该属性还可以应用于其他资源,当你需要用到这些资源的时候,浏览器会直接从缓存中拿,不再次发送请求了
<link rel="preload" href="./index.js" as="script">
<link rel="preload" href="./index.png" as="image">
<link rel="preload" href="./index.mp4" as="video" type="video/mp4">

还有一种实现

let link = document.createElement("link");
link.rel = "stylesheet";
link.href = "./index1.css";

document.head.appendChild(link);

4.实现一个布局左侧固定宽,右侧随窗口大小改变的;

左浮动,

 <style>
        .box1{
            width:100px;
            height:300px;
            float:left;
            background:red;
        }
        .box2{
            overflow: auto;
            height:300px;
            background: #2efa52;
        }
    </style>

左侧绝对定位

<style>
    .left {
      position: absolute;
      height: 500px;
      width: 300px;
      background: #333;
      color: #ccc;
    }
    .right {
      height: 500px;
      background: #ddd;
      margin-left: 300px;
    }
  </style>
<style>
    .wrapper {
      display: flex;
    }
    .left {
      flex: 0 0 25%;
      width: 25%;
      height: 500px;
      background: #333;
      color: #ccc;
    }
    .right {
      flex: 1;
      height: 500px;
      background: #ddd;
    }
  </style>

1.原型,原型链
2.实现继承
3.数组去重

const myArray = [1,1,2,2,3,3,4,4,5,5]
console.log([...new Set(myArray )]);// [1, 2, 3, 4, 5]
function dedupe(array) {
  return Array.from(new Set(array));
}
dedupe([1, 1, 2, 3]) // [1, 2, 3]

4.promise()原理
5.快速排序
6.MVC、MVVM的区别(MVVM是数据驱动的,实现响应式的双向数据绑定)
7.登录的实现
8.vue优化的方法
9.vue2和vue3的区别,为什么用proxy?
10.vue的缺点:
vue-cli:Vue脚手架

                vue-resource(axios):ajax请求

                vue-router:路由

                vuex:状态管理

                vue-lazyload:图片懒加载

                vue-scroller:页面滑动相关

                mint-ui:基于Vue的UI组件库(移动端)

                element-ui:基于Vue的UI组件库(PC端)

11.从浏览器写一个url 到发生渲染,中间发生了什么?
12.开发移动端如何做的适配?iponeX 适配出现问题怎么解决?
ios 点击事件延迟300ms,怎么处理?

13.vue双向绑定的原理。
14.vue 数据传递,实现2个兄弟组件的事件传递。
15.为什么要把data(){return ;}的形式

不使用return包裹的数据会在项目的全局可见,会造成变量污染;使用return包裹后数据中变量只在当前组件中生效,不会影响其他组件。

如果不用function return。data对象是一个实例对象,存在于栈内存中。所有对它的引用都相当于浅拷贝(只拷贝堆内存地址,不拷贝栈内存对象),因此任意更改一个引用都会造成所有引用的栈内存数据变化。

若使用的function return时, data对象是一个函数对象,当组件复用的时候该函数对象会重新创建新的实例对象,各个组建之间的实例对象是独立的。因此创建组件的时候使用function return 才能解决数据之间的冲突问题。

1.发生一个https请求的时候,客户端和服务端发生了哪些交互?
如果模拟一个https 请求一个资源,如何辨识这个是模拟的?
https请求过程
CA证书提前安装到client;
客户端 申请CA证书后,安装到当前网站;
服务端 nginx 中配置443端口,公钥和私钥;

2.跨站脚本如何预防?XSS 攻击?是为了防止什么?如何防止?
XSS攻击本质是html的注入
在输出和调用的时候进行转码(htmlEncode,JavaScriptEncode)
标签事件白名单

3.为什么要有同源策略,没有同源策略会发生什么攻击,请模拟?
4.你知道rem,em,vh,vw分别是什么吗?手机端为什么要使用rem?

px代表物理屏幕上能显示出的最小的一个点,
em 是相对于父级的字体大小,
rem是相对于HTML根元素的字体大小,
vh 和vw相对于视口的高度和宽度,1vh 等于1/100的视口高度,1vw 等于1/100的视口宽度

5.flex 布局有哪些属性?
6.css 伪类、wei元素有哪些?什么时候用到了
用在了哪些地方
7.闭包是什么?用在哪些地方?
8.在实例化一个对象的时候干了哪些事情?
9.双向绑定怎么实现的?
10.js 是单线程吗,setTimeout(,3)怎么监听到3分钟了
11.hash路由和history路由的区别?请求一个网址的时候怎么知道url发生了变化?
如何检测浏览器的url变化
hash路由和history路由

hash 路由:监听 url 中 hash 的变化,然后渲染不同的内容,这种路由不向服务器发送请求,不需要服务端的支持;
用hashchange 监听到路由的改变,loaction.hash 拿到路由,再渲染路由对应的组件。
hash路由:location.hash;
监听hash路由变化  window.hashChange();

history 路由:监听 url 中的路径变化,需要客户端和服务端共同的支持;
全局的popstate事件监听路由变化(pushState和replaceState被调用时,是不会触发触发 popstate 事件的)
popstate事件只会在浏览器操作如点击前进or后退按钮(JS调用也可), URL"#"后面的字符串改变时触发.

开发常用history路由

hash路由:url中的hash值改变的时候,改变hash不会重新加载页面,向服务器发起请求。

12.transform 是干什么用的
13.聚集索引和非聚集索引的区别?
14.jsonp跨域原理?
15.JS事件委托的优点?
16.JS为什么要进行变量提升?

前端的疑难问题总结:
1.自动化埋点
2.虚拟滚动性能优化
3.大文件上传
4.按需加载
5.图片懒加载方案
6.缓存
7.js基础题

let arr = ['1','2','3'].map(function(item, key, arr){
		//3个参数
		parseInt("1", 0) //0为10进制
		parseInt("2", 1) //radix中没有1进制一说
		parseInt("3", 2) //2进制中超过1的值不存在
	});
	//[1, NaN, NaN]

8.实际问题解决
vue5个组件同时向后端发送请求,当都收到响应时,请求成功组件显示,失败组件隐藏;

尽量将请求单独作为一个函数(不要将请求放到show()函数里面,show()函数只是负责组建的显示);

在进行请求的时候可以加入loading,提高体验;

当请求完毕以后,再通过this.$emit通知父组件请求完毕;

父组件这时在通过this.$refs.child.show() 显示子组件,同时隐藏自己;

9.如何防止脚本获取cookie;

设置httponly属性;
cookie值进行转码和加密

10.promise原理

11.协商缓存和强缓存
强缓存总结

cache-control: max-age=xxxx,public
客户端和代理服务器都可以缓存该资源;
客户端在xxx秒的有效期内,如果有请求该资源的需求的话就直接读取缓存,statu code:200 ,如果用户做了刷新操作,就向服务器发起http请求

cache-control: max-age=xxxx,private
只让客户端可以缓存该资源;代理服务器不缓存
客户端在xxx秒内直接读取缓存,statu code:200

cache-control: max-age=xxxx,immutable
客户端在xxx秒的有效期内,如果有请求该资源的需求的话就直接读取缓存,statu code:200 ,即使用户做了刷新操作,也不向服务器发起http请求

cache-control: no-cache
跳过设置强缓存,但是不妨碍设置协商缓存;一般如果你做了强缓存,只有在强缓存失效了才走协商缓存的,设置了no-cache就不会走强缓存了,每次请求都回询问服务端。

cache-control: no-store
不缓存,这个会让客户端、服务器都不缓存,也就没有所谓的强缓存、协商缓存了。

协商缓存:
怎么设置协商缓存?

response header里面的设置

etag: '5c20abbd-e2e8'
//每个文件有一个,改动文件了就变了,就是个文件hash,每个文件唯一,就像用webpack打包的时候,每个资源都会有这个东西,如: app.js打包后变为 app.c20abbde.js,加个唯一hash,也是为了解决缓存问题

last-modified: Mon, 24 Dec 2018 09:49:49 GMT
//文件的修改时间,精确到秒

每次请求返回来 response header 中的 etag和 last-modified,在下次请求时在 request header 就把这两个带上,服务端把你带过来的标识进行对比,然后判断资源是否更改了,如果更改就直接返回新的资源,和更新对应的response header的标识etag、last-modified。如果资源没有变,那就不变etag、last-modified,这时候对客户端来说,每次请求都是要进行协商缓存了

12.301,302,307

13.vue 优化方式有哪些?

1.对路由进行懒加载
在路由配置文件里,这里是router.js里面引用组件。如果使用同步的方式加载组件,在首屏加载时会对网络资源加载加载比较多,资源比较大,加载速度比较慢。所以设置路由懒加载,按需加载会加速首屏渲染。在没有对路由进行懒加载时,在Chrome里devtool查阅可以看到首屏网络资源加载情况(6requests 3.8MB transfferred Finish:4.67s DOMContentLoaded 2.61s Load 2.70s)。在对路由进行懒加载之后(7requests 800kb transffered Finish2.67s DOMContentLoaded 1.72s Load 800ms),可以看见加载速度明显加快。但是进行懒加载之后,实现按需加载,那么项目打包不会把所有js打包进app.[hash].js里面,优点是可以减少app.[hash].js体积,缺点就是会把其它js分开打包,造成多个js文件,会有多次https请求。如果项目比较大,需要注意懒加载的效果。

在这里插入图片描述

2.代码优化:

v-show,v-if 的使用;
v-show和v-if的区别是:v-if是懒加载,当状态为true时才会加载,并且为false时不会占用布局空间;v-show是无论状态是true或者是false,都会进行渲染,并对布局占据空间对于在项目中,需要频繁调用,不需要权限的显示隐藏,可以选择使用v-show,可以减少系统的切换开销


为item设置唯一key值
在列表数据进行遍历渲染时,需要为每一项item设置唯一key值,方便vuejs内部机制精准找到该条列表数据。当state更新时,新的状态值和旧的状态值对比,较快地定位到diff。

3.内容类系统的图片资源按需加载

对于内容类系统的图片按需加载,如果出现图片加载比较多,可以先使用v-lazy之类的懒加载库或者绑定鼠标的scroll事件,滚动到可视区域先再对数据进行加载显示,减少系统加载的数据

4.ssr服务端渲染

如果项目比较大,首屏无论怎么做优化,都出现闪屏或者一阵黑屏的情况。可以考虑使用SSR(服务端渲染),vuejs官方文档提供next.js很好的服务端解决方案,但是局限性就是目前仅支持Koa、express等Nodejs的后台框架,需要webpack支持。目前自己了解的就是后端支持方面,vuejs的后端渲染支持php,其它的不太清楚。

5.打包优化

修改vue.config.js中的配置项,把productionSourceMap设置为false,不然最终打包过后会生成一些map文件,如果不关掉,生成环境是可以通过map去查看源码的,并且可以开启gzip压缩,使打包过后体积变小。

使用cdn的方式外部加载一些资源,比如vue-router、axios等Vue的周边插件,在webpack.config.js里面,externals里面设置一些不必要打包的外部引用模块。然后在入门文件index.html里面通过cdn的方式去引入需要的插件。

在这里插入图片描述
在这里插入图片描述

1.vuex刷新页面数据丢失怎么解决
store 中的数据是保存在运行内存中的,当刷新页面时,vue实例会重新加载,store中的数据也会重新赋值。

一种是state里的数据全部是通过请求来触发action或mutation来改变

一种是将state里的数据保存一份到本地存储(localStorage、sessionStorage、cookie)中。

localStorage是永久存储在本地,除非你主动去删除;

sessionStorage是存储到当前页面关闭为止;

cookie则根据你设置的有效时间来存储,但缺点是不能储存大数据且不易读取。

我选择的是sessionStorage,选择的原因vue是单页面应用,操作都是在一个页面跳转路由,另一个原因是sessionStorage可以保证打开页面时sessionStorage的数据为空,而如果是localStorage则会读取上一次打开页面的数据。

第一种方案

由于state里的数据是响应式,所以sessionStorage存储也要跟随变化。又由于vuex规定所有state里数据必须通过mutation方法来修改,所以第一种方案就是mutation修改state的同时修改sessionStorage对应存储的属性

第二种方案

第一种方案确实可以解决问题,但这种方法很明显让人觉得怪异,都这样了,那不如直接用sessionStorage来做状态管理。

那怎么才能不用每次修改state时同时也要修改sessionStorage呢?这时我们可以换一个思路,因为我们是只有在刷新页面时才会丢失state里的数据,那有没有办法在点击页面刷新时先将state数据保存到sessionStorage,然后才真正刷新页面?

当然有,beforeunload这个事件在页面刷新时先触发的。那这个事件应该在哪里触发呢?我们总不能每个页面都监听这个事件,所以我选择放在app.vue这个入口组件中,这样就可以保证每次刷新页面都可以触发。
export default {
  name: 'App',
  created () {
    //在页面加载时读取sessionStorage里的状态信息
    if (sessionStorage.getItem("store") ) {
        this.$store.replaceState(Object.assign({}, this.$store.state,JSON.parse(sessionStorage.getItem("store"))))
    } 

    //在页面刷新时将vuex里的信息保存到sessionStorage里
    window.addEventListener("beforeunload",()=>{
        sessionStorage.setItem("store",JSON.stringify(this.$store.state))
    })
  }
}

2.ios 上 click 延迟300ms怎么解决?
出现这个问题是由于,点击第一次的时候不能判断是否会双击;

FastClick
FastClick的实现原理是在检测到touchend事件的时候,会通过DOM自定义事件立即出发模拟一个click事件,并把浏览器在300ms之后的click事件阻止掉
npm install fastclick -S
//引入
import fastClick from 'fastclick'
//初始化FastClick实例。在页面的DOM文档加载完成后
window.addEventListener( "load", function() {
FastClick.attach( document.body );
}, false );

如果你用过FastClick在移动端,就会发现有一个体验很不好的问题,某些ios上,点击输入框想唤启软键盘,触点不是很灵敏,必须重压或长按才能成功唤启,快速点击是不会唤启软键盘的。

/**
  * @param {EventTarget|Element} targetElement
  */
FastClick.prototype.focus = function(targetElement) {
  var length;
  if (deviceIsIOS && targetElement.setSelectionRange && targetElement.type.indexOf('date') !== 0 && targetElement.type !== 'time' && targetElement.type !== 'month' && targetElement.type !== 'email') {
      length = targetElement.value.length;
      targetElement.focus();// 加入这一句话
      targetElement.setSelectionRange(length, length);
  } else {
      targetElement.focus();
  }
};

3.如何实现一个自定义指令?
以上实现的效果是,在输入框输入颜色信息,例如:red,#ddd…组件中的信息,会随着你输入的信息变色

//指令钩子函数:
    /*
    bind   只调用一次,指令第一次绑定到元素的时调用
    inserted 被指令绑定指令的元素插入 父节点的时候调用
    update  被绑定的元素模版只要发生变化,就会触发(通过比较模板变化前后)
    componentUpdated 被绑定元素所在模版完成一次更新周期时被触发
    unbind 指令被解除绑定的时候
    */
/*
定义指令回调函数(钩子函数的几个参数的意义)
第一个参数:绑定指令的元素html
第二个参数:对象的形式输出,自定义指令的信息(指令名字,使用的名字,包括我们传入的值,我们可以利用这个参数,在钩子函数中进行相关操作),
第三个参数:输出绑定指令的元素的虚拟dom节点信息
*/

const selfcomponent={
        template:`<div>
         <p>自定义组件</p>    
         <input v-model="com"/>
         <p v-my-dir="com">组件的内容:跟随变色</p>
        </div>`,
        //props:['color'],
        data(){
            return { com:'#ddd'}//给一个默认值
        },
        directives:{
            "myDir":{//指令的名字
            bind:function(el,binding,nodeDom){
                 console.log(binding);
                 console.log("bind");
                 el.style="color:"+binding.value;
            },

            inserted:function(){
                console.log("instered");
            },
            update:function(el,binding,nodeDom){//每次在input中输入信息,都会触发这个函数
                console.log("update");
                el.style="color:"+binding.value;
            },
            componentUpdated:function(el,bindging,nodeDom){
                console.log("componented");
            
            },        
            unbind:function(el,binding,nodeDom){
                console.log("unbind");
            }    
         }
            
        }
        
    };

  var app =new Vue({
    el:"#app",
    data:{
      color:'red',
     },
    methods:{
  
    },
    components:{
      selfcomponent
    }
  });


</script>

<div id="app">
     <selfcomponent ></selfcomponent>                             
</div>

也可以是全局指令

Vue.directive("mydirective",function(el,pra,a){
        console.log(el);//将元素标签输出
        console.log(pra);//议对象的形式输出,自定义指令的信息,(包括我们传入的值)
        console.log(a);//以对象的形式输出,vue虚拟节点信息
            //console.log(document.getElementsByTagName("li")[0].parentNode);
            el.style="color:"+pra.value;
    });

4.v-for和v-if 使用时有什么问题?
v-if和v-for一般不建议一起使用,如果一定需要用到,最好使用一下两种方法进行替换。

1、当根据遍历的列表中的对象的某一个属性决定展示与否的时候,使用计算属性(computed)进行判断,computed的具体介绍详见:https://cn.vuejs.org/v2/guide/computed.html。

例子:遍历users,如果对象的isShow属性为true时候展示
users: [
        {'name': '111', 'isShow': true},
        {'name': '222', 'isShow': false},
        {'name': '333', 'isShow': false},
        {'name': '444', 'isShow': true}
      ]
改良前:因为v-for优先级比v-if高,所以在每次重新渲染的时候会先遍历整个列表,再进行if判断是否展示,即:每次都需要重新渲染全部列表对象再判断是否需要展示

<ul>
  <li v-for="user in users" v-if="user.isShow">
    {{ user.name }}
  </li>
</ul>
改良后:会先判定列表对象时候需要显示,之后渲染需要显示的对象,效率更高
// 渲染代码
<ul>
  <li v-for="user in showUsers" :key="user.id" >
    {{ user.name }}
  </li>
</ul>
// 计算属性代码
computed: {
    showUsers: function () {
      return this.users.filter(function (user) {
        return user.isShow
      })
    }
  }
2、根据某一个与待循环列表无关的属性决定是否展示渲染后的数组对象时,可以把v-if上移。

例子:根据isShow属性决定是否显示users列表
users: [
        {'name': '111'},
        {'name': '222'},
        {'name': '333'},
        {'name': '444'}
      ],
isShow: true
改良前
<ul>
  <li v-for="user in users" v-if="isShow">
    {{ user.name }}
  </li>
</ul>
改良后
<ul v-if="isShow">
  <li v-for="user in users">
    {{ user.name }}
  </li>
</ul>
  1. currentTarget 和target的区别?
target:触发事件的元素。
currentTarget:事件绑定的元素
  1. 用css 画一条0.5px的线?
    设置成1px,然后使用缩放功能
//画一条0.5px的线
<!DOCType html>
<html>
<head>
    <meta charset="utf-8">
    <style>
        .half-px {
            width: 300px;
            background-color: #000;
            height: 1px;
            transform: scale(0.5)
        }
    </style>
</head>
<body>
    <div class="half-px"></div>
</body>
</html>

采用meta viewport的方式

<meta name="viewport" content="width=device-width,initial-sacle=0.5">
//width=device-width表示将viewport视窗的宽度调整为设备的宽度,这个宽度通常是指物理上宽度。
 
//缩放到原来的0.5倍,如果是1px那么就会变成0.5px
 
//viewport只针对于移动端,只在移动端上才能看到效果

canvas/svg方式画一条0.5px的线

<!DOCTYPE html>
<head>
  <meta charset="UTF-8">
</head>
<body>
  <!-- canvas画布方式 -->
  <canvas id="drawing" width=" 200" height="200">A drawing of something.</canvas>
  <!-- svg方式 -->
  <svg id="svgLineTutorial"  height="200px" width="200px" xmlns="http://www.w3.org/2000/svg">
    <line x1="50" y1="50" x2="200" y2="200" style="stroke:Green;stroke-width:0.5"/>
  </svg>
 
  <script>
    var drawing = document.getElementById("drawing");  
    if (drawing.getContext){ 
      var context = drawing.getContext("2d"); 
      context.lineWidth = 0.5;
      context.beginPath(); 
      context.moveTo(30, 30); 
      context.lineTo(200, 100);
      context.stroke(); 
    }
  </script>
</body>
</html>
  1. 前端的会话缓存有哪些?

10…iframe的优缺点?

优点
1.能够嵌入网页,把内容展示出来
2.模块分离,便于更改,如果有多个网页引用iframe,只需要修改iframe的内容,就可以实现调用的每一个页面内容的更改,方便快捷;
3.网页如果为了统一风格,头部和版本都是一样的,就可以写成一个页面,用iframe来嵌套,增加代码的可重用;
4.如果遇到加载缓慢的第三方内容如图标和广告,这些问题可以由iframe来解决;

5.重载页面时不需要重载整个页面,只需要重载页面中的一个框架页;

6.方便制作导航栏。
缺点
1.样式和脚本需要额外链入,调用外部页面,需要额外调用css,增加页面额外的请求次数,增加服务器的http请求;

2.代码复杂,在网页中使用框架结构最大的弊病是搜索引擎的“蜘蛛”程序无法解读这种页面,会影响搜索引擎优化,不利于网站排名;

3.框架结构有时会让人感到迷惑,滚动条除了会挤占有限的页面空间外会使iframe布局混乱,还会分散访问者的注意力,影响用户体验;

4.链接导航疑问。运用框架结构时,必须保证正确配置所有的导航链接,否则,会给访问者带来很大的麻烦。比如被链接的页面出现在导航框架内,这种情况下访问者便被陷住了,因为此时他没有其他地点可去; 

5.产生多个页面,不易管理;

6.多数小型的移动设备(PDA 手机)无法完全显示框架,设备兼容性差。

二、为什么尽量少用iframe
iframes提供了一个简单的方式把一个网站的内容嵌入到另一个网站中。iframe的创建比其它包括scripts和css的 DOM 元素的创建慢了1-2个数量级。

使用iframe的页面一般不会包含太多iframe,所以创建DOM节点所花费的时间不会占很大的比重。但带来一些其它的问题:onload事件以及连接池(connection pool),即iframe会阻塞主页面的Onload事件及iframe和主页面共享连接池,会影响页面的并行加载。

1.iframes阻塞页面加载,影响网页加载速度

及时触发 window 的 onload 事件是非常重要的。onload 事件触发使浏览器的 “忙” 指示器停止,告诉用户当前网页已经加载完毕。当 onload事件加载延迟后,它给用户的感觉就是这个网页非常慢。

window的onload 事件需要在所有 iframe 加载完毕后(包含里面的元素)才会触发,就会影响网页加载速度。通过 JavaScript 动态设置 iframe的SRC可以避免这种阻塞情况。

2.唯一的连接池

对每个 web 服务器来说,浏览器只打开极少的几个连接数。老的浏览器,包括 IE 6/7 和 Firefox 2,每个主机只有2个连接。在新的浏览器中,连接数增加鸟。Safari 3+和Opera 9+增至4个,Chrome 1+IE 8及Firefox 3增至6个。

在大多数浏览器中,连接被主页面和它的 iframe所共享,这意味着有可能iframe中的资源占用了可用连接而阻塞了主页面的资源加载。如果iframe中的内容同等重要,或比主页面更重要,这很好。然而在通常情况下iframe中的内容对页面来说不太重要,iframe 占用连接数是不可取的。一个解决方案是在优先级更高的资源下载完成后再动态的给iframe的src赋值。

总之,iframe会给你的页面性能带来冲击,尽可能不使用iframe,当确实需要时,谨慎地使用他们。目前框架的优点可以使用Ajax实现,这在某种角度也是一种替代方案。

三、iframe的一些应用场景
iframe的页面和父页面(parent)是分开的,所以它意味着,这是一个独立的区域,不受 parent的CSS或者全局的JavaScript的影响。

1.典型的,比如所见即所得的网页编辑器;

2.跨域通信。JavaScript跨域总结与解决办法 ,类似的还有浏览器多页面通信,比如音乐播放器,用户如果打开了多个tab页,应该只有一个在播放;

3.历史记录管理,解决ajax化网站响应浏览器前进后退按钮的方案,在html5的history api不可用时作为一种替代;

4.纯前端的utf8和gbk编码互转。比如在utf8页面需要生成一个gbk的encodeURIComponent字符串,可以通过页面加载一个gbk的iframe,然后主页面与子页面通信的方式实现转换;

5.用iframe实现无刷新文件上传,在FormData不可用时作为替代方案;

6.创建一个全新的独立的宿主环境。iframe还可以用于创建新的宿主环境,用于隔离或者访问原始接口及对象,比如有些前端安全的防范会覆盖一些原生的方法防止恶意调用,通过创建一个iframe,然后从iframe中取回原始对象和方法来破解这种防范;

7.用来加载广告,例如联盟广告;

8.一般邮箱使用iframe,如QQ邮箱;

9.一些简单的后台页面。

关于iframe在跨域的使用,这里稍微强调一下
首先,我们要了解什么是跨域。简单地理解就是因为JavaScript同源策略的限制,a.com 域名下的js无法操作b.com或是c.a.com域名下的对象。JavaScript出于安全方面的考虑,不允许跨域调用其他页面的对象,但在安全限制的同时也给注入iframe或是ajax应用上带来了不少麻烦。网络上已经有非常多可行的方案,我们只限定在iframe中去讲解几种跨域方案。

1、document.domain+iframe的设置

document.domain,这是浏览器暴露出来的一个准只读属性(之所以说它是准只读属性,是因为它可以设置为当前域名的超级域),利用这个特性,可以实现主域名相同子域名不同的网页实现通信。

2.使用HTML5 postMessage

HTML5提供的API,可以安全的启用跨域通信。

语法:targetWindow.postMessage(data, targetOrigin),data参数是指要传递的数据。

如何在目标窗口接收到数据呢?编写如下代码即可:

window.addEventListener('message', function(evt) {
console.log(evt.data);

}, false);

evt.data即是postMessage中传递过来的数据。

特别注意两点

1.如果是协议和端口造成的跨域问题“前台”是无能为力的。

2.在跨域问题上,域仅仅是通过“URL的首部”来识别而不会去尝试判断相同的ip地址对应着两个域或两个域是否在同一个ip上。

vue 的 diff算法

快速排序

const quickSort = (array) => {
 const sort = (arr, left = 0, right = arr.length - 1) => {
  if (left >= right) {//如果左边的索引大于等于右边的索引说明整理完毕
   return
  }
 let i = left
 let j = right
 const baseVal = arr[j] // 取无序数组最后一个数为基准值
 while (i < j) {//把所有比基准值小的数放在左边大的数放在右边
  while (i < j && arr[i] <= baseVal) { //找到一个比基准值大的数交换
   i++
  }
  arr[j] = arr[i] // 将较大的值放在右边如果没有比基准值大的数就是将自己赋值给自己(i 等于 j)
  while (j > i && arr[j] >= baseVal) { //找到一个比基准值小的数交换
   j--
 }
  arr[i] = arr[j] // 将较小的值放在左边如果没有找到比基准值小的数就是将自己赋值给自己(i 等于 j)
 }
 arr[j] = baseVal // 将基准值放至中央位置完成一次循环(这时候 j 等于 i )
 sort(arr, left, j-1) // 将左边的无序数组重复上面的操作
 sort(arr, j+1, right) // 将右边的无序数组重复上面的操作
 }
 const newArr = array.concat() // 为了保证这个函数是纯函数拷贝一次数组
 sort(newArr)
 return newArr
}

redis 存储速度快的原因?

1、完全基于内存,绝大部分请求是纯粹的内存操作,非常快速。数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1)2、数据结构简单,对数据操作也简单,Redis中的数据结构是专门进行设计的;

3、采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 CPU,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗;

4、使用多路I/O复用模型,非阻塞IO5、使用底层模型不同,它们之间底层实现方式以及与客户端之间通信的应用协议不一样,Redis直接自己构建了VM 机制 ,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求;

以上几点都比较好理解,下边我们针对多路 I/O 复用模型进行简单的探讨:

(1)多路 I/O 复用模型

多路I/O复用模型是利用 select、poll、epoll 可以同时监察多个流的 I/O 事件的能力,在空闲的时候,会把当前线程阻塞掉,当有一个或多个流有 I/O 事件时,就从阻塞态中唤醒,于是程序就会轮询一遍所有的流(epoll 是只轮询那些真正发出了事件的流),并且只依次顺序的处理就绪的流,这种做法就避免了大量的无用操作。

这里“多路”指的是多个网络连接,“复用”指的是复用同一个线程。采用多路 I/O 复用技术可以让单个线程高效的处理多个连接请求(尽量减少网络 IO 的时间消耗),且 Redis 在内存中操作数据的速度非常快,也就是说内存内的操作不会成为影响Redis性能的瓶颈,主要由以上几点造就了 Redis 具有很高的吞吐量。

下面是硬盘数据库的工作模型,需要先从数据读取数据到内存,内存中的数据保存到硬盘,我们更改硬盘的数据后在保存到数据库。这里的步骤较多,而且还占用我们的硬盘容量
在这里插入图片描述

内存数据库的工作模式,这种方式相比硬盘数据库的方式少了内存到硬盘这一步,速度回快很多,而且不占用我们的硬盘容量。我们用的Redis就是基于这种方式的,看完Redis简介(一)和上面的描述,我们对于Redis有了一定的了解。下面我们再介绍Redis作为缓存为什么速度这么快。

在这里插入图片描述

Redis采用的是基于内存的采用的是单进程单线程模型的 KV 数据库,由C语言编写,官方提供的数据是可以达到100000+的QPS(每秒内查询次数)。
在这里插入图片描述
横轴是连接数,纵轴是QPS。此时,这张图反映了一个数量级,希望大家在面试的时候可以正确的描述出来,不要问你的时候,你回答的数量级相差甚远。

1、vue-router params 和query 传参方式;
2、获取query和params的方式;
3、如何让一个页面不刷新,用hash 方式;
4、混入的作用:三个组件中都使用一个方法;
5、promise.all();执行顺序;和输出顺序
6、为什么使用组合继承,用原型链继承有什么问题,浅拷贝;
https://www.cnblogs.com/sarahwang/p/9098044.html
7、如何在获取一个对象的属性过程中打印一段代码;
https://www.jianshu.com/p/8fe1382ba135添加链接描述
8、判断是否是自身的属性还是继承来的属性;
9、判断一个对象是不是一个原型的实例;
二面:
1、在Vue中,当你利用索引值直接设置一个数组项时,例如:
vm.item[indexOfItem] = newValue,可以用哪些方法实现视图的更新

this.$set(item, indexOfItem,newValue)

声明响应式的数组和对象
https://cn.vuejs.org/v2/guide/reactivity.html#%E5%AF%B9%E4%BA%8E%E6%95%B0%E7%BB%84

js中或者vue中 Object.assign()用法详解
Object.assign()是浅拷贝。

合并对象
    var o1 = { a: 1 };
    var o2 = { b: 2 };
    var o3 = { c: 3 };

    var obj = Object.assign(o1, o2, o3);
    console.log(obj); // { a: 1, b: 2, c: 3 }
    console.log(o1); // { a: 1, b: 2, c: 3 }, 注意目标对象自身也会改变。

注意,具有相同属性的对象,同名属性,后边的会覆盖前边的。

Vue中的使用技巧
  由于Object.assign()有上述特性,所以我们在Vue中可以这样使用:
Vue组件可能会有这样的需求:在某种情况下,需要重置Vue组件的data数据。此时,我们可以通过this.$data获取当前状态下的data,通过this.$options.data()获取该组件初始状态下的data。然后只要使用Object.assign(this.$data, this.$options.data())就可以将当前状态的data重置为初始状态,非常方便!

2、限制一个input 输入框,只能输入数字或者字母
3、实现一个vue 的自定义指令,例如,一个input输入框,当页面加载的时候是输入框自动获取焦点;

directive: {
 	focus: {
 	//被绑定元素插入DOM中时(beforeMount),
 		inserted: function(el){
			el.focus();
		}
 	}
}

 // bind/inserted /updated/componentUpdated/unbind有四个参数:
 //1.绑定DOM 
 //2.binding(指令名称 name,指令值 value,指令表达式:expression, 指令参数:arg, modifiers:一个包含修饰符的对象)
//3.Vnode 虚拟节点 
//4.oldVnode 上一个虚拟节点

4、如果项目是一个SPA单页应用,有哪些方式优化入口文件的大小,让其加载速度更快;
从代码方面:使用路由懒加载;(有哪些写法,怎么写)
从webpack 打包方面:

webpack文件有哪些模块?
loader 的编译顺序?
webpackChunkName的注释到底是什么?
在这里插入图片描述
简单了解:webpackChunkName 是为预加载的文件取别名,作用就是webpack在打包的时候,对异步引入的库代码(lodash)进行代码分割时(需要配置webpack的SplitChunkPlugin插件),为分割后的代码块取得名字

import异步加载的写法实现页面模块lazy loading懒加载(Vue中的路由异步加载):
Vue中运用import的懒加载语句以及webpack的魔法注释,在项目进行webpack打包的时候,对不同模块进行代码分割,在首屏加载时,用到哪个模块再加载哪个模块,实现懒加载进行页面的优化

5、JS中防抖和节流;
如何实现监听滚动条滑动到页面底部;
如何实现输入框输入停止后去查询;

1.实现一个div水平垂直都居中;
2.实现响应式布局:flex、媒体查询、rem、em;
3.为什么要跨域,跨域的解决方案,我说了nginx 配置,nginx如何配置?
4.vue 组件之间的通信有哪些?
5.vue router 有哪两种路由,这两种路由有什么区别?
6.如何优化单页应用?
7.节流和防抖?并实现任意一种
8.实现深度克隆?
9.写一个轮播图?

1.webpack 中都需要配置些什么;env 除外,其他环境变量怎么配置;
2.addeventListener实现;
3.vuex修改的时候其他也能监听到修改怎么做,除了watch
4.router如何配置,路由守卫,redirect()重定向;
5.混入,怎么使用,混入一个对象,和组件中的执行优先级。

1.你们用element-ui是如何实现组件的按需加载的,webpack使用什么配置?
babel-plugin-component
2.vue写一个提示框的组件;
https://blog.csdn.net/hamsterknight/article/details/103992069

1.v-once,v-if,v-show 的区别
https://blog.csdn.net/qq_34115899/article/details/104406693
2.router ,history 和 hash的区别
3.对象实现继承,原型链?

1.v-for /v-of区别

for of无法循环遍历对象
遍历输出结果不同
for in 会遍历自定义属性,for of不会
forin会遍历对象的整个原型链,性能非常差不推荐使用,forof只遍历当前对象不会遍历原型链

https://www.cnblogs.com/hexiaobao/p/12108572.html
2.foreach/formap
3.用set获取两个数组的差集、交集、并集
4、form提交表单的类型
5、class和ES5的类的区别
6、自定义指令埋点:
http://www.cppcns.com/wangluo/javascript/253871.html
https://blog.csdn.net/sayoko06/article/details/107400859
7.ES6 新增了哪些新特性
MAP;https://blog.csdn.net/gao_xu_520/article/details/79977909
二面:
1.浏览器兼容性问题,请举例;
2.如何优化首页
3.keep-alive 和active生命周期
4.如何解决线上问题,http状态码
5.解决跨域
6.请求有哪些类型
7.请求头响应头都有哪些

1.axios半路拦截
2.找出所有回文字符串
3.promise、async,awit, genterator得区别
4.typescript/nodejs

console.log(1);
    setTimeout(()=>{
      console.log(2);
      Promise.resolve().then(data => {
        console.log(3)
      })
    })
    new Promise(reject =>{
      reject();
      console.log(4)
    }).then(()=> {
      console.log(5)
      setTimeout(() => {
        console.log(6)
      });
    }).then(()=>
        console.log(7))

    console.log(8)

//1,4,8,5,7,2,3,6
---------------------------
console.log(f1,f2,f3);
    var f1 = function () {
      console.log('welcome to p1')
    }
    function f2() {
      console.log('welcome to p2')
    }
    var f3 = 'welcome to p3';
    var f1,f2,f3;
    console.log(f1,f2,f3)
--------------------
var nickname = 'LiLei';
    function Person(name) {
      this.nickname = name;
      this.sayHi = function () {
        console.log(this.nickname);
        setTimeout(function () {
          console.log(this.nickname)
        },1000)
      }
    }
    var Male = {
      nickname: 'xiaofang',
      sayHi: function ()  {
        console.log(this.nickname)
      }
    }

   var obj =  new (Person.bind(Male,'xiaohong'))
    obj.sayHi();
------------------------------------------
 let object = {a:0};
   function fun(obj) {
     obj.a = 1;
     obj = {a:2};
     obj.b = 2;
   }
    fun(object);
    console.log(object)


需要准备的:
1、promise的实现原理;
https://zhuanlan.zhihu.com/p/102017798
2、promiseAll()实现原理;
3、addEventListener()的实现
4、vuex的实现
5、写一个弹框组件
6、自定义指令
7、打点实现
8、双向绑定实现原理
9、v-model实现原理,v-model实现父子组件双向绑定
https://www.cnblogs.com/elsonww/p/11305806.html
10、plugin和loader 的区别
11、element-ui打包按需引入?babel-plugin-component
12、HTTPS 是如何加密的?客户端服务端之间的交互
13、TCP 三次握手、四次挥手,在网络层7层里的哪一层

Java微服务面试的问题非常广泛,以下是一些可能会被问到的问题和回答: 1. 微服务是什么?为什么使用微服务架构? 微服务是一种软件架构模式,它将一个大型应用程序拆分成一组小型、相互独立的服务。每个服务都有自己的业务逻辑和数据存储,可以独立开发、部署和扩展。微服务架构具有许多优点,包括灵活性、可扩展性、模块化和团队自治。 2. 在微服务中如何处理服务之间的通信? 微服务之间的通信可以使用RESTful API或消息队列来实现。RESTful API是一种基于HTTP协议的轻量级通信机制,它可以通过GET、POST、PUT和DELETE等HTTP方法来发送和接收数据。消息队列则可以实现异步通信,并提供更高的可靠性和可伸缩性。 3. 如何保证微服务架构的可靠性和容错性? 为了保证可靠性和容错性,可以使用负载均衡、故障转移和容错机制来处理微服务的请求。负载均衡可以将请求分发到多个服务实例上,以提高性能和可伸缩性。故障转移可以在某个服务实例失败时自动切换到备用实例。容错机制可以处理网络故障和服务不可用的情况。 4. 如何测试微服务? 在测试微服务时,可以使用单元测试、集成测试和端到端测试来确保每个服务的功能和性能都达到预期。单元测试可以测试单个服务的业务逻辑。集成测试可以测试多个服务之间的协作和通信。端到端测试可以模拟真实用户场景,并测试整个系统的功能和性能。 5. 在微服务中如何处理数据一致性? 于微服务之间的数据存储是分散的,确保数据一致性可能会成为一个挑战。可以使用分布式事务或事件驱动的架构来处理数据一致性。分布式事务可以确保多个服务在进行数据更新时的一致性。事件驱动的架构则可以通过发布和订阅事件来实现数据同步。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值