2020面试题笔记(实训期间亲身经过)-04

148 阅读8分钟

--小编第一家面试的公司是一家刚建俩年的创业型公司(洞幺),经历过四轮面试很可惜没有被面试上,现在将面试题整理出来。

一、关于vue

1、父组件与子组件传值?

答: 1.1 父传子:父组件通过v-bind在子组件上绑定数据(数据在data里面定义好了的),子组件通过props自定义属性来接受父组件传过来的值。props属性是单向绑定,可以指定验证要求(那就props必须是对象);子组件还可以通过$parent来接受父组件传过来的值

 <div id="app">
    <div>
      <input v-model="parentMsg">
      <br>
      <child v-bind:message="parentMsg"></child>
    </div>
</div>
<script>
// 注册
Vue.component('child', {
  // 声明 props
  props: ['message'],
  // 同样也可以在 vm 实例中像 "this.message" 这样使用
  template: '<span>{{ message }}</span>'
})
// 创建根实例
new Vue({
  el: '#app',
  data: {
    parentMsg: '父组件内容'
  }
})
</script> 

1.2 子传父:子组件不能直接修改父组件传过来的值,所以通过$emit()发送事件数据给父组件,父组件通过v-on来监听子组件传过来的事件数据进行相对应的操作

 <div id="app">
    <div id="counter-event-example">
      <p>{{ total }}</p>
      <button-counter v-on:increment="incrementTotal"></button-counter>
      <button-counter v-on:increment="incrementTotal"></button-counter>
    </div>
</div>

<script>
Vue.component('button-counter', {
  template: '<button v-on:click="incrementHandler">{{ counter }}</button>',
  data: function () {
    return {
      counter: 0
    }
  },
  methods: {
    incrementHandler: function () {
      this.counter += 1
      this.$emit('increment')
    }
  },
})
new Vue({
  el: '#counter-event-example',
  data: {
    total: 0
  },
  methods: {
    incrementTotal: function () {
      this.total += 1
    }
  }
})
</script>

ps:非父子组件之间传值,需要定义个公共的公共实例文件bus.js,作为中间仓库来传值,不然路由组件之间达不到传值的效果。

公共文件:bus.js
//bus.js
import Vue from 'vue'
export default new Vue()

组件A:

<template>
  <div>
    A组件:
    <span>{{elementValue}}</span>
    <input type="button" value="点击触发" @click="elementByValue">
  </div>
</template>
<script>
  // 引入公共的bug,来做为中间传达的工具
  import Bus from './bus.js'
  export default {
    data () {
      return {
          elementValue: 4
      }
    },
    methods: {
      elementByValue: function () {
          Bus.$emit('val', this.elementValue)
      }
    }
  }
</script>

组件B:

 <template>
  <div>
    B组件:
    <input type="button" value="点击触发" @click="getData">
    <span>{{name}}</span>
  </div>
 </template>
<script>
  import Bus from './bus.js'
  export default {
    data () {
      return {
      	name: 0
      }
    },
    mounted: function () {
      var vm = this
      // 用$on事件来接收参数
      Bus.$on('val', (data) => {
        console.log(data)
        vm.name = data
      })
    },
    methods: {
      getData: function () {
      	this.name++
      }
   	}
  }
</script>

2、组件缓存用什么标签?

答:

2.1 组件缓存用:<keep-alive>标签(用来包裹动态组件)。主要用于保留组件状态避免重新渲染

2.2 属性:

include - 字符串或正则表达式。只有名称匹配的组件会被缓存。
exclude - 字符串或正则表达式。任何名称匹配的组件都不会被缓存。
max - 数字。最多可以缓存多少组件实例。(一旦这个数字达到了,在新实例被创建之前,已缓存组件中最久没有被访问的实例会被销毁掉。)

2.3 用法:<keep-alive>包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。和 <transition> 相似,<keep-alive> 是一个抽象组件:它自身不会渲染一个 DOM 元素,也不会出现在组件的父组件链中。

当组件在 <keep-alive> 内被切换,它的 activateddeactivated 这两个生命周期钩子函数将会被对应执行。

主要用于保留组件状态避免重新渲染

  <!-- 基本 -->
  <keep-alive>
    <component :is="view"></component>
  </keep-alive>

<!-- 多个条件判断的子组件 -->
<keep-alive>
  <comp-a v-if="a > 1"></comp-a>
  <comp-b v-else></comp-b>
</keep-alive>

<!-- 和 `<transition>` 一起使用 -->
<transition>
  <keep-alive>
    <component :is="view"></component>
  </keep-alive>
</transition>

注意<keep-alive> 不会在函数式组件中正常工作,因为它们没有缓存实例。

3、v-if和v-show的区别?

答:

3.1 都是用于通过条件显示隐藏组件。

3.2 区别 : v-if在条件切换时,会对标签进行适当的创建和销毁。而v-show则仅在初始化时加载一次,因此v-if的开销相对来说会比v-show大。

v-if是惰性的,只有当条件为真时才会真正渲染标签,而v-show则无论初始条件是否成立,都会渲染标签,它仅仅做的只是简单的CSS切换。

3.3 什么时候用v-if?

当我不需要频繁的显示元素时,用v-if;需要频繁的显示元素,则用v-show,性能高些。

4、vue中如何解决页面不重新渲染问题?

答:

4.1 : 修改对象属性后页面未重新渲染可以使用 this.$set(对象名称, '属性名', '属性值')(向响应式对象中添加一个 property,并确保这个新 property 同样是响应式的,且触发视图更新。)

--修改对象的某一属性
<template>
  <div>
      <div v-for='item in list'>{{item}}</div>
      <button @click='click'>改变</button>
      <button @click='hadelClick'>解决方法</button>
  </div>
</template>
<script>
  export default({
    data(){
      return{
        list:{a:'a',b:'b'},
      }
    },
    methods: {
          click() {
          //  未声明不触发渲染
           this.list.c='c'

          },
          hadelClick(){
            // 解决方法,使用vue提供的$set方法来触发渲染
            this.$set(this.list,'d','d')
          }
        }
  })

</script>

4.2 : 使用this.$forceUpdate()实例方法(强制刷新)可重新渲染页面.(迫使 Vue 实例重新渲染。注意它仅仅影响实例本身和插入插槽内容的子组件,而不是所有子组件。)

你页面不刷新但你的数据缺实修改了,可以使用this.$forceUpdate()方法 (强制刷新)
<template>
  <div>
      <div v-for='item in list'>{{item.a}}</div>
      <button @click='click'>改变</button>
      <button @click='hadelClick'>解决方法</button>
  </div>
</template>
<script>
  export default({
    data(){
      return{
        list:[{a:'vue'},{a:'react'},{a:'js'}],
      }
    },
    methods: {
          click() {
            this.list[0] = {a:'css'} //页面不渲染
            console.log(this.list)  //[{a:'css'},{a:'react'},{a:'js'}]
          },
          hadelClick(){
            this.list[0] = {a:'css'} //页面不渲染
            console.log(this.list)  //[{a:'css'},{a:'react'},{a:'js'}]
              this.$forceUpdate();//强制刷新
          }
        }
  })

</script>
	
    

5、如何让css只在当前组件起作用?

答: 5.1 : 当前组件<style>写成<style scoped>

scoped三条渲染规则

1、给HTML的DOM节点加一个不重复data属性(形如:data-v-2311c06a)来表示他的唯一性

2、在每句css选择器的末尾(编译后的生成的css语句)加一个当前组件的data属性选择器(如[data-v-2311c06a])来私有化样式

3、如果组件内部包含有其他组件,只会给其他组件的最外层标签加上当前组件的data属性

实例:

//实际上的
<template>
    <div class="button-warp">
        <button class="button">text</button>
    </div>
</template>
...
<style scoped>
    .button-warp{
        display:inline-block;
    }
    .button{
        padding: 5px 10px;
        font-size: 12px;
        border-radus: 2px;
    }
</style>

渲染后的HTML

 <div data-v-2311c06a class="button-warp">
    <button data-v-2311c06a class="button">text</button>
</div>

渲染后的css

 .button-warp[data-v-2311c06a]{
  display:inline-block;
  }
.button[data-v-2311c06a]{
    padding: 5px 10px;
    font-size: 12px;
    border-radus: 2px;
}

注意:scoped的这一操作,虽然达到了组件样式模块化的目的,但是会造成一种后果:每个样式的权重加重了:理论上我们要去修改这个样式,需要更高的权重去覆盖这个样式。这是增加复杂度的其中一个维度。

6、vue-router 路由模式有几种?

答:有3种

1、hash: 使用 URL hash 值来作路由。支持所有浏览器,包括不支持 HTML5 History Api 的浏览器;

2、history : 依赖 HTML5 History API 和服务器配置。具体可以查看 HTML5 History 模式

3、abstract : 支持所有 JavaScript 运行环境,如 Node.js 服务器端。如果发现没有浏览器的 API,路由会自动强制进入这个模式.

7、vue的俩个核心?

答:数据驱动组件系统

数据驱动:数据的双向绑定。数据发生变化后,会重新对页面渲染,这就是Vue响应式

组件系统:组件相互构成的系统

组件的核心选项:

1 模板(template):模板声明了数据和最终展现给用户的DOM之间的映射关系。

2 初始数据(data):一个组件的初始数据状态。对于可复用的组件来说,这通常是私有的状态。

3 接受的外部参数(props):组件之间通过参数来进行数据的传递和共享。

4 方法(methods):对数据的改动操作一般都在组件的方法内进行。

5 生命周期钩子函数(lifecycle hooks):一个组件会触发多个生命周期钩子函数,最新2.0版本对于生命周期函数名称改动很大。

6 私有资源(assets):Vue.js当中将用户自定义的指令、过滤器、组件等统称为资源。一个组件可以声明自己的私有资源。私有资源只有该组件和它的子组件可以调用。

7、promise是什么?有什么用?

二、css面试题

1、css样式覆盖规则?

答:

规则一:由于继承而发生样式冲突时,最近祖先获胜。

<html>

  <head>

  <title>rule 1</title>

  <style>

    body {color:black;}

    p {color:blue;}

  </style>

  </head>

  <body>

      <p>welcome to <strong>gaodayue的网络日志</strong></p>

  </body>

</html>
注意:strong分别从bodyp中继承了color属性,但是由于p在继承树上离strong更近,因此strong中的文字最终继承p的蓝色

规则二:继承的样式和直接指定的样式冲突时,直接指定的样式获胜。

接着在以上案例,指定给元素加上此样式
strong {color:red;}
注意:那么根据规则二,strong中的文字最终显示为红色。

规则三:直接指定的样式发生冲突时,样式权值高者获胜。

样式的权值取决于样式的选择器:内联样式的权值1000>>ID选择器100>>类选择器10>>标签选择器1,除此以外,后代选择器的权值为每项权值之和

规则四:样式权值相同时,后者获胜。

<p class="byline">Written by 
  <a class="email" href="mailto:jean@cosmofarmer. com">
  	Jean Graine de Pomme
  </a>
</p>


.byline a {color:red;}

p .email {color:blue;}

注意:“.byline a”与”p .email”都直接指定了上面的a元素,且权值都为11,根据规则四,最终显示蓝色。

规则五:!important的样式属性不被覆盖

!important可以看做是万不得已的时候,打破上述四个规则的”金手指”。
大多数情况下都可以通过其他方式来控制样式的覆盖,不能滥用!important。

2、px、em、rem的区别?

答:

px:是像素,即相对于当前显示器屏幕分辨率而言的相对长度单位。

特点:1、ie无法调整哪些使用px为单位的字体大小;
	2、国外大部分网站能够调整的原因在于使用了em和rem作为字体单位;
    	3、火狐能够调整px、em、rem,但是大部分的中国网民都是使用的IE浏览器和内核。
        

em:是相对于当前对象内的文本尺寸而言的相对长度单位。

特点:1em的值不是固定的;
      2em会继承父级元素的字体大小;
      3、任意浏览器的默认字体都是16px,且未做调整的浏览器都是1em=16px4、为了简化em的运算,需要在body里面设置font-size=62.5%,使得1em=10px,便于运算。

rem:css3新增的相对长度单位。相对于HTML根元素。

特点:1、除了IE8以下的ie版本,其他浏览器都兼容。

注意:

1、根据你的项目来选择相对应的字体单位,如果你的用户群都使用最新版的浏览器,那推荐使用rem,如果要考虑兼容性,那就使用px,或者也可两者同时使用。

2、只需要适配少部分手机设备,且分辨率对页面影响不大的,使用px即可 

3、对于需要适配各种移动设备,使用rem,例如只需要适配iPhone和iPad等分辨率差别比较挺大的设备。

三、js面试题

1、undefined和null的区别?

答:

undefined:是所有没有赋值变量的默认值,自动赋值;

特点:1、可以设置变量值为undefined用来清空变量
     2、类型是undefined

null:主动释放一个变量引用的对象。表示一个变量不再指向任何对象地址。即该变量变为一个空对象。

 特点:1、可以设置用来清空对象。
      2、类型是object
      3、使用:当使用一个大的对象,需要对其释放内存的时候,可以设置为null

区别

相同:都是原始类型,

不同:1、定义不同
     2、值相等,但类型不同
     3、用法不同

---欢迎观看,觉得总结的还不错的请点个赞哦!更多内容持续更新。