前端面试汇总

一、CSS相关

1. 盒模型
①标准的盒模型:width指content部分的宽度;
②在IE盒模型(怪异盒子)中:width表示content+padding+border这三个部分的宽度。
③切换盒模型:box-sizing: content-box 是W3C盒子模型,box-sizing: border-box 是IE盒子模型。
当盒子形成怪异盒模型之后,当前padding值不会撑大容器的大小 不需要减去相应的padding值
2. BFC
①定义:BFC就是为元素提供一个独立的容器,在该容器里按照一定的规则进行布局排列,该容器内的元素不会影响外部的元素,同理,外部的元素也不会影响内部的元素
②触发条件:
1.float 不为 none
2.position 为 absolute 或 fixed
3.overflow 不为 visible
4.display 为 inline-block 或 table 或 flow-root
③用处:
1.清除浮动
2.解决margin-top导致高度塌陷
3.自适应布局
3. css3 新增
背景和边框
border-radius、box-shadow、border-image、
background-size:规定背景图片的尺寸
background-origin:规定背景图片的定位区域
background-clip:规定背景的绘制区域
文本效果(常用)
text-shadow:设置文字阴影
word-wrap:强制换行
word-break
css3提出@font-face规则,规则中定义了font-family、font-weight、font-style、font-stretch、src、unicode-range
2/3D转换
transform:向元素应用2/3D转换
transition:过渡
动画
@keyframes规则:
animation、animation-name、animation-duration等
用户界面(常用)
box-sizing、resize
css3新增伪类
:nth-child()
:nth-last-child()
:only-child
:last-child
:nth-of-type()
:only-of-type()
:empty
:target 这个伪类允许我们选择基于URL的元素,如果这个元素有一个识别器(比如跟着一个#),那么:target会对使用这个ID识别器的元素增加样式。
:enabled
:disabled
:checked
:not
4. h5新增的标签
video,audio、canvas、svg、code、menu、progress、mark、nav、aside、article、header、footer等
5. 元素水平垂直居中
5.1.已知宽高 如300px x 300px
①子元素:position:absolute/fixed;margin:auto;top:0;bottom:0;left:0,;right:0;
②子元素:position:absolute/fixed;top:50%;margin-top:-150px;left:50%;margin-left:-150px;
③子元素:position:absolute/fixed;top:calc(50% - 150px); left:calc(50% - 150px);
5.2.未知宽高
④子元素:position:absolute/fixed;top:50%;left:50%;transform:translate(-50%,-50%)
⑤ html,body {height:100%}
body {display:flex;align-items:center;justify-content:center}
⑥html,body {height:100%}
body{display:flex;}
div{margin:auto;}
6. css 清除浮动的方法
背景:页面布局当中,在无法确定子元素的高度(height)时,我们无法给父级标签一个固定的高度(height),我们想要的是,由子元素的高度去控制父元素的高度。所以,当子元素设置了浮动(float)属性之后,父元素的高度没有进行设置,这样就会导致父元素的高度塌陷(原本的height被重置为0),这就涉及到了清除浮动的重要性。
1.在子元素后面添加空白标签,样式加clear:both;

<div class="clear" style="clear: both;"></div>  <!-- 添加一个空的标签 -->

2.给父元素添加高度;
3.给父元素添加overflow:hidden;
4.万能清除法给父元素添加css代码: .container :after {content:’ ';display:block;clear:both;}
5.给父元素添加浮动
7. 画三角形
#triangle-up {
width: 0;
height: 0;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-bottom: 100px solid red;
}

二、JS相关

一、基础部分
1.数据类型
基本数据类型:
⭐数值型(number)
⭐字符串型(string)
⭐布尔型(boolean)
⭐未定义(undefined)
⭐空(null)
⭐符号型(symbol)
引用数据类型:
⭐对象(Object)
注:数组(Array)、函数(Function),还有两个特殊的对象:正则(RegExp)和日期(Date)不是数据类型,它们都属于对象 Object 。
特点
1.基本数据类型的主要特点是赋值方式是传值,赋值后不会相互影响,并且值存在栈中。
2.引用数据类型的主要特点是赋值方式是传址,赋值后会相互影响,并且值存在堆中。
3.栈:栈内存在JS中是存放基本数据类型的值引用数据类型的指针

二、es6新增
1. let和const
①let 声明变量,要先定义后使用;存在块级作用域({}, for(){}, while(){}, do{}while(), if(){}, switch(){});存在暂时性死区(所声明的变量或常量就自动“绑定”这个区域,不再受到外部作用域的影响);不能变量提升;在同一个作用域中同一个变量let 只能声明一次,而var可以多次声明;
②const 是用来定义常量的,块级作用域、不存在声明提升、同一个常量只能声明一次;
常量一旦声明其值不能改变,但要注意:如果常量的值为数组、对象时其值是可以被改变的

2. 解构赋值
①定义:ES6提供了更简洁的赋值模式,将数组、对象中的数据按照一定模式提取出来并赋值给变量
②好处:使用const { state } = this.props;
无论使用let还是const都会有可能存在变量被改变的情况,例如const 虽然为常量,但是他的地址不会改变就算被push数据或obj.name,他也不会报错,但他会增加这个属性,那么原来的值就被改变了。而采用解构赋值,不会改变原来的值。
③对象解构赋值的应用如下代码:交换数据、从函数返回多个值、提取JSON数据

let x = 18,
    y = 5;
[y, x] = [x, y];
console.log(x, y);	//	5 18
// 返回一个数组
function example() {
  return [1, 2, 3];
}
let [a, b, c] = example();

// 返回一个对象
function example() {
  return {
    foo: 1,
    bar: 2
  };
}
let { foo, bar } = example();

let jsonData = {
  id: 42,
  status: "OK",
  data: [867, 5309]
};

let { id, status, data: number } = jsonData;
console.log(id, status, number);
// 42, "OK", [867, 5309]

3. 模板字符串
在模板字符串中可以引用变量、函数调用、运算、换行

let usr = "李四";
let age = 21;
 
// let str = "<a href=''>姓名:</a>" + usr + " 年龄:" + age;
let str = `<a href='www.baidu.com'>姓名:${usr}</a>  
        年龄:${age}
        函数调用结果为:${tst()}
        运算结果为:${age - 3}`;
console.log(str);
 
function tst() {
	return 'Hello web';
}
//	输出结果
/*
	<a href='www.baidu.com'>姓名:李四</a>  
                      年龄:21
                      函数调用结果为:Hello web
                      运算结果为:18
*/

4. 扩展运算符
①概念:取出参数对象中的所有可遍历属性,拷贝到当前对象之中
②作用:实现数组合并深拷贝

<script>
    // 数组合并
    let arr = [1, 2, 3];
    let arr2 = [...arr, 7, 9];
    console.log(arr2);
    // 1,2,3,7,9
</script>
// 深拷贝
const arr1 = [1, 2];
const arr2 = [...arr1];

5.Symbol数据类型
①特点:唯一性、不能参与运算(包括字符串拼接)、for…in或for…of不能遍历;
②声明方式:使用Symbol()函数申明创建变量;

var s1 = Symbol();
var s2 = Symbol();
//	两者一定不相等
console.log(s1, s2, s1 === s2); 
//Symbol() Symbol() false

6. Set数据类型
概念:ES6中内置了Set对象(构造函数),通过new字符进行实例化
应用:实现数组去重
注意:set使用后会变成对象,此时需要配合使用Array.from扩展运算符
Array.from()方法就是将一个类数组对象或者可遍历对象转换成一个真正的数组,也是ES6的新增方法。

// set配合Array.from 实现数组去重
let curset = new Set([1, 3, 5, 3, 7, 5, 9]);
console.log(curset);    
//Set(5) {1, 3, 5, 7, 9}
let arr = Array.from(curset)
console.log(arr); 
//[1,3,5,7,9]
// set配合扩展运算符 实现数组去重
let arr = [1,1,2,2,3,4,4];
let newArr = [...new Set(arr)]; 			// [1,2,3,4];

7. 箭头函数
① 用途:箭头函数通常用于回调函数,回调函数通常都是匿名函数,可以简化匿名函数;
② 区别于一般函数的特点:
一般函数可以先调用后定义,而箭头函数只能先定义后调用;
箭头函数没有arguments
this指向:指向宿主对象
箭头函数不能重复命名参数,普通函数可以重复命名参数

fn();   //普通函数 
 
function fn() {
    console.log('普通函数');
}
 
fn();   //普通函数
 
arrowFn();  //TypeError: arrowFn is not a function
var arrowFn = (n) => {
    console.log('箭头函数');
}
arrowFn();  //  箭头函数

8. promise对象
①定义:Promise是ES6中的一个内置对象,是一个构造函数
三种状态:pending(进行中)、resolved(已完成)、rejected(已失败)
②解决多层嵌套,回调地狱的问题;使用then的回调,避免传统方法需要传回调参数
③promise链式传递;因为then() 方法的返回值是一个promise对象;
成功的回调函数可以调用多次,失败的回调函数只会执行一次;
④Promise.all()并发方法:
要么所有Promise实例都成功、要么都失败;
如果都成功则返回所有Promise实例结果,并且该结果是数组,数组中的元素与all()方法中的值与Promise实例中的一一对应;
如果有一个Promise实例执行失败则都失败,并且只返回最先失败的那个Promise实例结果。
⑤Promise.race()方法:
哪个promise实例最先执行完成返回哪个promise的结果,不管这个结果是resolve还是reject,只比谁最快;

9. async函数和await关键字
①async/await是ES8新特性
②async/await是写异步代码的新方式,以前的方法有回调函数和Promise
③async/await是基于Promise实现的,它不能用于普通的回调函数
④async/await与Promise一样,是非阻塞的
⑤async/await使得异步代码看起来像同步代码
Async/await进一步优化了Promise.then()的缺点,使代码更简洁
async关键字:
1)表明程序里面可能有异步过程
2)非阻塞
3)async函数返回类型为Promise对象
4)无等待:在没有await的情况下执行async函数,它会立即执行
await关键字:
1)await只能在async函数内部使用

async function 函数名(){
    await 异步操作1; 
    await  异步操作2; 
}

10. es6中的类
ES6的class可以看作只是一个语法糖,它的绝大部分功能,ES5都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。
优点:面向对象相对面向过程来说可以提高代码重用度、降低系统耦合性
构造器方法在类实例化时会被自动调用

class  类名{
    constructor(){
        // 构造器
    }
    //属性
    //方法 
}   
 
///=============================================
class Star {
    // 属性方法的集合
    // 构造器:当实例化类时会自动被调用 
    constructor(names, age) {
        this.age = age;
        this.names = names;
    }
    sing() {
        console.log(this.names + '唱歌');
    }
    dance() {
        console.log(this.age + '岁的' + this.names + '跳舞');
    }
}
//创建对象
let p = new Star (1,'小红');
console.log(p.dance());

11. 防抖和节流
1.防抖:n秒内只执行最后一次
2.节流:高频事件触发后,但在n秒内只会执行一次(vn开大)
总结:防抖:n秒后执行一次
节流:n秒内只执行一次

12. this指向
函数中指向window
方法中指向当前对象
回调函数中指向当前节点对象
箭头函数中没有固定指向,一般指向宿主对象
构造函数中指向实例化对象
13. new操作符

①帮你创建空的临时对象
②帮你绑定原型
③根据上下文绑定this指向
④return 临时对象

14. 原型和原型链
原型对象:在js中,每一个函数类型的数据,都有一个叫做prototype的属性,这个属性指向的是一个对象,就是原型对象。
原型对象来说有一个constructor属性,指向它的构造函数,用来存放实例对象的公有属性和公有方法
原型(分两种):
显示原型:就是利用prototype属性查找原型,只是这个是函数类型数据的属性
隐式原型:是利用__proto__属性查找原型,这个属性指向当前对象的构造函数的原型对象,这个属性是对象类型数据的属性,所以可以在实例对象上面使用。
原型链
如果某个对象查找属性,自己和原型对象上都没有,那就会继续往原型对象的原型对象上去找,整个查找过程都是顺着__proto__属性,一步一步往上查找,形成了像链条一样的结构,这个结构,就是原型链。所以,原型链也叫作隐式原型链。
总结:
构造函数是使用了new关键字的函数,用来创建对象,所有函数都是Function()的实例;
原型对象是用来存放实例对象的公有属性和公有方法的一个公共对象,所有原型对象都是Object()的实例;
原型链又叫隐式原型链,是由__proto__属性串联起来,原型链的尽头是Object.prototype。

15. 深浅拷贝
①for in遍历循环
②json.parse( json.stringify(obj) )会造成方法的丢失
③object.assign()合并
④扩展运算符…,在对象前面加…

三、Vue相关

编辑补充的知识放这儿:
1.vue2中data为什么是函数?
根的实例对象 data 可以是对象也可以是函数 (根实例是单例), 不会产生数据污染;
组件实例对象 data 必须为函数,目的是为了防止多个组件实例对象之间共用一个data,产生数据污染。
(Object是引用数据类型,如果不用function 返回,每个组件的data 都是内存的同一个地址,一个数据改变了其他也改变了, javascipt只有函数构成作用域,data是一个函数时,每个组件实例都有自己的作用域,每个实例相互独立,不会相互影响。)

2.vue路由知识

可以理解为,一个是用来获取路由信息的,一个是用来操作路由的
$route:
route是路由信息对象,包含路由基本信息,包括name、meta、path、query、params、hash、fullPath、matched、redirectedFrom;
$router:
router是VueRouter的实例,包含了一些路由的跳转方法,(push,replace,back,forward,go)钩子函数等。

3. 刷新页面vuex丢失数据
vuex存储的数据只是在页面中,相当于全局变量,页面刷新的时候vuex里的数据会重新初始化,导致数据丢失。
因为vuex里的数据是保存在运行内存中的,当页面刷新时,页面会重新加载vue实例,vuex里面的数据就会被重新赋值;
解决:存储到localStorage或sessionStorage中

4. Vue的双向数据绑定原理
vue.js 是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。
第一步: observer(观察者)对数据对象进行递归遍历,包括子属性对象的属性,都加上 setter和getter,这样的话,给这个对象的某个值赋值,就会触发setter,那么就能监听到了数据变化;
第二步: compile解析模板指令,将模板中的变量替换成数据,然后初始化渲染页面视图,并将每个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据有变动,收到通知,更新视图;
第三步: Watcher(订阅者)是Observer和Compile之间通信的桥梁,主要做的事情是:
1、在自身实例化时往属性订阅器(dep)里面添加自己
2、自身必须有一个update()方法
3、待属性变动dep.notice()通知时,能调用自身的update()方法,并触发Compile中绑定的回调
第四步: MVVM作为数据绑定的入口,整合Observer、Compile和Watcher三者,通过Observer来监听自己的model数据变化,通过Compile来解析编译模板指令,最终利用Watcher搭起Observer和Compile之间的通信桥梁,达到数据变化 -> 视图更新;视图交互变化(input) -> 数据model变更的双向绑定效果。

一、什么是MVVM?
MVVM是Model-View-ViewModel的缩写。MVVM是一种设计思想。Model 层代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑;View 代表UI 组件,它负责将数据模型转化成UI 展现出来,ViewModel 是一个同步View 和 Model的对象。
在MVVM架构下,View 和 Model 之间并没有直接的联系,而是通过ViewModel进行交互,Model 和 ViewModel 之间的交互是双向的, 因此View 数据的变化会同步到Model中,而Model 数据的变化也会立即反应到View 上。
ViewModel 通过双向数据绑定把 View 层和 Model 层连接了起来,而View 和 Model 之间的同步工作完全是自动的,无需人为干涉,因此开发者只需关注业务逻辑,不需要手动操作DOM, 不需要关注数据状态的同步问题,复杂的数据状态维护完全由 MVVM 来统一管理

二、mvvm和mvc区别?它和其它框架(jquery)的区别是什么?哪些场景适合?
mvc和mvvm其实区别并不大。都是一种设计思想。主要就是mvc中Controller演变成mvvm中的viewModel。mvvm主要解决了mvc中大量的DOM 操作使页面渲染性能降低,加载速度变慢,影响用户体验。
区别:vue数据驱动,通过数据来显示视图层而不是节点操作。
场景:数据操作比较多的场景,更加便捷

三、vue的优点是什么?
低耦合。视图(View)可以独立于Model变化和修改,一个ViewModel可以绑定到不同的"View"上,当View变化的时候Model可以不变,当Model变化的时候View也可以不变。
可重用性。你可以把一些视图逻辑放在一个ViewModel里面,让很多view重用这段视图逻辑。
独立开发。开发人员可以专注于业务逻辑和数据的开发(ViewModel),设计人员可以专注于页面设计。
可测试。界面素来是比较难于测试的,而现在测试可以针对ViewModel来写。

四、 组件之间的传值?
父子组件的关系可以总结为 prop 向下传递,事件向上传递。父组件通过 prop 给子组件下发数据,子组件通过事件给父组件发送消息
父传子
父组件中引入子组件,在子组件标签上绑定变量,
子组件里用props接收
子传父
1.子组件中绑定事件,通过 e m i t 方法传递数据;父组件中,在子组件标签上绑定方法,接收子组件数据。 2. 父组件通过 r e f 得到子组件的值,如: t h i s . emit方法传递数据; 父组件中,在子组件标签上绑定方法,接收子组件数据。 2.父组件通过ref得到子组件的值,如:this. emit方法传递数据;父组件中,在子组件标签上绑定方法,接收子组件数据。2.父组件通过ref得到子组件的值,如:this.refs.children.msg。
兄弟组件通信: eventBus;Vuex
跨级通信:Bus;Vuex;provide / inject API、 a t t r s / attrs/ attrs/listeners,
爷孙组件也可以一直用 e m i t 一层层往上传,在父组件中绑定方法,承担中间桥梁,接收子组件触发的 emit一层层往上传,在父组件中绑定方法,承担中间桥梁,接收子组件触发的 emit一层层往上传,在父组件中绑定方法,承担中间桥梁,接收子组件触发的emit,然后自己也用$emit去触发爷组件的方法

五、路由之间跳转
方式一、利用标签,path路径跳转,且可以使用params和query传值

//写法1
<router-link to="/artlist">小说列表</router-link> 
//router-link解析出来其实是a标签


方式二:利用标签,命名式路由跳转(name)

<router-link :to="{name:'shop',query:{city:cityObj}}">购物车</router-link> 
...
//js文件中配置路由
{
	path:'/shop',
	//该path路径不能少。因为命名式路由跳转是通过name找到该path
	name:'shop',
	component:Shop
}

方式三:编程式路由跳转 ($router.push) 最常用的,不受时机、条件的限制

jumpHome() {
        this.$router.push({
            path:"/home"query:{
            	id:this.id
            }
        })
      }
 ...
 
 //接收值如果进入另一个页面,一般在created中接收
 this.$route.query.id
 
 //路由配置
 { path: "/home", component: ()=>import("../Home") }
 
  //或者name和params搭配,接收值 this.$route.params.id

六、vue.cli中怎样使用自定义的组件?有遇到过哪些问题吗?
第一步:在components目录新建你的组件文件(indexPage.vue),script一定要export default {}
第二步:在需要用的页面(组件)中导入:import indexPage from ‘@/components/indexPage.vue’
第三步:注入到vue的子组件的components属性上面,components:{indexPage}
第四步:在template视图view中使用,
例如有indexPage命名,使用的时候则index-page

七、vue如何实现按需加载配合webpack设置
1、 es6提案的import()
推荐使用这种方式(需要webpack > 2.4)
webpack官方文档:webpack中使用import()
vue官方文档:路由懒加载(使用import())

  const Login=()=>import('../component/login/login')
  {
      path:'/login',
      name:'Login',
      component:Login
  }
  //或者 自己常用的:
  {
      path:'/login',
      name:'Login',
      component:()=>import('@/views/innovate/page/customerDetail'),
      meta: {
        title:'客户详情'
      }
  }

2、webpack的require.ensure()

 {
     path: '/login',
     name: 'Login',
     component: resolve => require.ensure([], () => resolve(require('../components/Login')), 'demo')
 },
 {
     path: '/hello',
     name: 'Hello',
     // component: Hello
     component: resolve => require.ensure([], () => resolve(require('../components/Hello')), 'demo')

八、vuex面试相关
(1)vuex是什么?怎么使用?哪种功能场景使用它?
vue框架中状态管理。在main.js引入store,注入。新建一个目录store,…… export 。场景有:单页应用中,组件之间的状态。音乐播放、登录状态、加入购物车
(2)vuex有哪几种属性?
有五种,分别是 State、 Getter、Mutation 、Action、 Module
vuex的State特性
A、Vuex就是一个仓库,仓库里面放了很多对象。其中state就是数据源存放地,对应于一般Vue对象里面的data
B、state里面存放的数据是响应式的,Vue组件从store中读取数据,若是store中的数据发生改变,依赖这个数据的组件也会发生更新
C、它通过mapState把全局的 state 和 getters 映射到当前组件的 computed 计算属性中
vuex的Getter特性
A、getters 可以对State进行计算操作,它就是Store的计算属性
B、 虽然在组件内也可以做计算属性,但是getters 可以在多组件之间复用
C、 如果一个状态只在一个组件内使用,是可以不用getters
vuex的Mutation特性
Action 类似于 mutation,不同在于:Action 提交的是 mutation,而不是直接变更状态;Action 可以包含任意异步操作。
(3)不用Vuex会带来什么问题?
可维护性会下降,想修改数据要维护三个地方;
可读性会下降,因为一个组件里的数据,根本就看不出来是从哪来的;
增加耦合,大量的上传派发,会让耦合性大大增加,本来Vue用Component就是为了减少耦合,现在这么用,和组件化的初衷相背。

九、 v-show和v-if指令的共同点和不同点?
v-show指令是通过修改元素的display的CSS属性让其显示或者隐藏;
v-if指令是直接销毁和重建DOM;
v-show 由更高的初始渲染消耗,v-if 有更高的切换消耗;频繁切换使用v-show。

十、 如何让CSS只在当前组件中起作用?
将当前组件的style中添加scoped

十一、keep-alive的作用是什么?
包裹动态组件时,会缓存不活动的组件实例,主要用于保留组件状态或避免重新渲染。

十二、Vue中引入组件的步骤?
1)采用ES6的import … from …语法或CommonJS的require()方法引入组件
2)对组件进行注册,代码如下

// 注册
Vue.component('my-component', {
 	 template: '<div>A custom component!</div>'
})

3)使用组件

十三、指令v-el的作用是什么?
提供一个在页面上已存在的 DOM 元素作为 Vue 实例的挂载目标.可以是 CSS 选择器,也可以是一个 HTMLElement 实例

十四、在Vue中使用插件的步骤
采用ES6的import … from …语法或CommonJSd的require()方法引入插件
使用全局方法Vue.use( plugin )使用插件,可以传入一个选项对象Vue.use(MyPlugin, { someOption: true })

十五、请列举出3个Vue中常用的生命周期钩子函数
created: 实例已经创建完成之后调用,有数据,属性和方法,但是没有dom,常用于简单的ajax请求,页面的初始化; before mount:rander函数首次被调用,mounted : 可以操作dom,activated: keep-alive组件激活时调用

十六、active-class是哪个组件的属性?
vue-router模块的router-link组件。

十七、怎么定义vue-router的动态路由以及如何获取传过来的动态参数?
在router目录下的index.js文件中,对path属性加上/:id。
使用router对象的params.id。

十八、vue-router有哪几种导航钩子?
三种,一种是全局导航钩子:router.beforeEach(to,from,next),作用:跳转前进行判断拦截。
第二种:组件内的钩子;
第三种:单独路由独享组件

十九、生命周期相关面试题
总共分为8个阶段创建前/后,载入前/后,更新前/后,销毁前/后。
创建前/后: 在beforeCreate阶段,vue实例的挂载元素el和数据对象data都为undefined,还未初始化。在created阶段,vue实例的数据对象data有了,el还没有。
载入前/后:在beforeMount阶段,vue实例的$el和data都初始化了,但还是挂载之前为虚拟的dom节点,data.message还未替换。在mounted阶段,vue实例挂载完成,data.message成功渲染。
更新前/后:当data变化时,会触发beforeUpdate和updated方法。
销毁前/后:在执行destroy方法后,对data的改变不会再触发周期函数,说明此时vue实例已经解除了事件监听以及和dom的绑定,但是dom结构依然存在
(1)、什么是vue生命周期
答: Vue 实例从创建到销毁的过程,就是生命周期。也就是从开始创建、初始化数据、编译模板、挂载Dom→渲染、更新→渲染、卸载等一系列过程,我们称这是 Vue 的生命周期。
(2)、vue生命周期的作用是什么
答:它的生命周期中有多个事件钩子,让我们在控制整个Vue实例的过程时更容易形成好的逻辑。
(3)、vue生命周期总共有几个阶段
答:可以总共分为8个阶段:创建前/后, 载入前/后,更新前/后,销毁前/销毁后
(4)、第一次页面加载会触发哪几个钩子
答:第一次页面加载时会触发 beforeCreate, created, beforeMount, mounted 这几个钩子
(5)、DOM 渲染在哪个周期中就已经完成
答:DOM 渲染在 mounted 中就已经完成了。
(6)、简单描述每个周期具体适合哪些场景
答:生命周期钩子的一些使用方法:
beforecreate : 可以在这加个loading事件,在加载实例时触发
created : 初始化完成时的事件写在这里,如在这结束loading事件,异步请求也适宜在这里调用
mounted : 挂载元素,获取到DOM节点
updated : 如果对数据统一处理,在这里写上相应函数
beforeDestroy : 可以做一个确认停止事件的确认框
nextTick : 更新数据后立即操作dom

二十、说出至少4种vue当中的指令和它的用法?
v-if:判断是否隐藏;v-for:数据循环;v-bind:class:绑定一个属性;v-model:实现双向绑定

二十一、vue-loader是什么?使用它的用途有哪些?
解析.vue文件的一个加载器。
用途:js可以写es6、style样式可以scss或less、template可以加jade等

二十二、scss是什么?在vue.cli中的安装使用步骤是?有哪几大特性?
答:css的预编译。
使用步骤:
第一步:先装css-loader、node-loader、sass-loader等加载器模块
第二步:在build目录找到webpack.base.config.js,在那个extends属性中加一个拓展.scss
第三步:在同一个文件,配置一个module属性
第四步:然后在组件的style标签加上lang属性 ,例如:lang=”scss”
特性:
可以用变量,例如($变量名称=值);
可以用混合器,例如()
可以嵌套

二十三、为什么使用key?
当有相同标签名的元素切换时,需要通过 key 特性设置唯一的值来标记以让 Vue 区分它们,否则 Vue 为了效率只会替换相同标签内部的内容。

二十四、为什么避免 v-if 和 v-for 用在一起?
当 Vue 处理指令时,v-for 比 v-if 具有更高的优先级,通过v-if 移动到容器元素,不会再重复遍历列表中的每个值。取而代之的是,我们只检查它一次,且不会在 v-if 为否的时候运算 v-for。

二十五、VNode是什么?虚拟 DOM是什么?
Vue在 页面上渲染的节点,及其子节点称为“虚拟节点 (Virtual Node)”,简写为“VNode”。“虚拟 DOM”是由 Vue 组件树建立起来的整个 VNode 树的称呼。

二十六、vue-loader是什么?使用它的用途有哪些?
答:解析.vue文件的一个加载器,跟template/js/style转换成js模块。
用途:js可以写es6、style样式可以scss或less、template可以加jade等

二十七、请说出vue.cli项目中src目录每个文件夹和文件的用法?
答:assets文件夹是放静态资源;components是放组件;router是定义路由相关的配置;view视图;app.vue是一个应用主组件;main.js是入口文件

二十八、vue.cli中怎样使用自定义的组件?有遇到过哪些问题吗?
答:
第一步:在components目录新建你的组件文件(smithButton.vue),script一定要export default {undefined
第二步:在需要用的页面(组件)中导入:import smithButton from ‘…/components/smithButton.vue’
第三步:注入到vue的子组件的components属性上面,components:{smithButton}
第四步:在template视图view中使用,
问题有:smithButton命名,使用的时候则smith-button。

二十九、聊聊你对Vue.js的template编译的理解?
答:简而言之,就是先转化成AST树,再得到的render函数返回VNode(Vue的虚拟DOM节点)
详情步骤:
首先,通过compile编译器把template编译成AST语法树(abstract syntax tree 即 源代码的抽象语法结构的树状表现形式),compile是createCompiler的返回值,createCompiler是用以创建编译器的。另外compile还负责合并option。
然后,AST会经过generate(将AST语法树转化成render funtion字符串的过程)得到render函数,render的返回值是VNode,VNode是Vue的虚拟DOM节点,里面有(标签名、子节点、文本等等)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值