vue常见面试题

1、对于MVVM的理解?

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

2、vue的生命周期

(1)什么是vue生命周期?
答: Vue 实例从创建到销毁的过程,就是生命周期。从开始创建、初始化数据、编译模板、挂载Dom→渲染、更新→渲染、销毁等一系列过程,称之为 Vue 的生命周期。

(2)vue生命周期的作用是什么?
答:它的生命周期中有多个事件钩子,让我们在控制整个Vue实例的过程时更容易形成好的逻辑。

(3.)vue生命周期总共有几个阶段?
答:它可以总共分为8个阶段:创建前/后, 载入前/后,更新前/后,销毁前/销毁后。

(4.)第一次页面加载会触发哪几个钩子?
答:会触发 下面这几个beforeCreate, created, beforeMount, mounted 。

(5.)DOM 渲染在 哪个周期中就已经完成?
答:DOM 渲染在 mounted 中就已经完成了。

beforeCreate(创建前) 在数据观测和初始化事件还未开始
created(创建后) 完成数据观测,属性和方法的运算,初始化事件,$el属性还没有显示出来
beforeMount(载入前) 在挂载开始之前被调用,相关的render函数首次被调用。实例已完成以下的配置:编译模板,把data里面的数据和模板生成html。注意此时还没有挂载html到页面上。
mounted(载入后) 在el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用。实例已完成以下的配置:用上面编译好的html内容替换el属性指向的DOM对象。完成模板中的html渲染到html页面中。此过程中进行ajax交互。
beforeUpdate(更新前) 在数据更新之前调用,发生在虚拟DOM重新渲染和打补丁之前。可以在该钩子中进一步地更改状态,不会触发附加的重渲染过程。
updated(更新后) 在由于数据更改导致的虚拟DOM重新渲染和打补丁之后调用。调用时,组件DOM已经更新,所以可以执行依赖于DOM的操作。然而在大多数情况下,应该避免在此期间更改状态,因为这可能会导致更新无限循环。该钩子在服务器端渲染期间不被调用。
beforeDestroy(销毁前) 在实例销毁之前调用。实例仍然完全可用。
destroyed(销毁后) 在实例销毁之后调用。调用后,所有的事件监听器会被移除,所有的子实例也会被销毁。该钩子在服务器端渲染期间不被调用。

3、常用命令

(1)插值语法  {{}}、v-once、v-html、v-text、v-pre

(2)动态绑定 v-bind、语法糖:、

(3)时间监听 v-on、监听用户发出的点击、拖拽、键盘事件,语法糖@,

(4)条件判断 v-if 、v-if v-else、v-elseif、还有v-show、也是判断显示不显示,和v-if的区别就是,当v-if为false时,虚拟dom中是不存在v-if所判断的元素,但是v-show为false时,就会出现在虚拟dom中,作用:当需要在显示隐藏之间频繁切换时,使用v-show的效率会更高

(5)循环遍历 v-for 遍历数组、遍历对象时,用到v-for

(6)双向绑定 v-model、mustache语法只是单项绑定、他是双向的,v-model其实是一个语法糖,将v-bind和v-on结合使用

4、vue组件之间数据传递

方法一

(1)父组件向子组件中传值

父组件A通过props的方式向子组件B传递,B to A 通过在 B 组件中 $emit, A 组件中 v-on 的方式实现。父组件通过props向下传递数据给子组件。注:组件中的数据共有三种形式:data、props、computed

//App.vue父组件
<template>
  <div id="app">
    <users v-bind:users="users"></users>//前者自定义名称便于子组件调用,后者要传递数据名
  </div>
</template>
<script>
import Users from "./components/Users"//首先引入子组件
export default {
  name: 'App',
  data(){
    return{
      users:["Henry","Bucky","Emily"]
    }
  },
  components:{
    "users":Users //声明在子组件中的名字
  }
}
//users子组件
<template>
  <div class="hello">
    <ul>
      <li v-for="user in users">{{user}}</li>//遍历传递过来的值,然后呈现到页面
    </ul>
  </div>
</template>
<script>
export default {
  name: 'HelloWorld',
  props:{
    users:{           //这个就是父组件中子标签自定义名字
      type:Array,
      required:true
    }
  }
}
</script>

(2)子组件向父组件传值(方法有很多种,常用就这一种,父子组件通信)

子组件通过events给父组件发送消息,实际上就是子组件把自己的数据发送到父组件

// 子组件
<template>
  <header>
    <h1 @click="changeTitle">{{title}}</h1>//绑定一个点击事件
  </header>
</template>
<script>
export default {
  name: 'app-header',
  data() {
    return {
      title:"Vue.js Demo"
    }
  },
  methods:{
    changeTitle() {
      this.$emit("titleChanged","子向父组件传值");//自定义事件  传递值“子向父组件传值”
    }
  }
}
</script>
// 父组件
<template>
  <div id="app">
    <app-header v-on:titleChanged="updateTitle" ></app-header>//与子组件titleChanged自定义事件保持一致
   // updateTitle($event)接受传递过来的文字
    <h2>{{title}}</h2>
  </div>
</template>
<script>
import Header from "./components/Header"
export default {
  name: 'App',
  data(){
    return{
      title:"传递的是一个值"
    }
  },
  methods:{
    updateTitle(e){   //声明这个函数
      this.title = e;
    }
  },
  components:{
   "app-header":Header,
  }
}
</script>

方法二:$emit  和  $on

方法三:vuex

方法四:$attlrs / $listenters

方法五:provide /inject

方法六:$parent / $children 和ref

  • ref:如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例
  • $parent / $children:访问父 / 子实例

需要注意的是:这两种都是直接得到组件实例,使用后可以直接调用组件的方法或访问数据。我们先来看个用 ref来访问组件的例子:

// component-a 子组件
export default {
  data () {
    return {
      title: 'Vue.js'
    }
  },
  methods: {
    sayHello () {
      window.alert('Hello');
    }
  }
}


// 父组件
<template>
  <component-a ref="comA"></component-a>
</template>
<script>
  export default {
    mounted () {
      const comA = this.$refs.comA;
      console.log(comA.title);  // Vue.js
      comA.sayHello();  // 弹窗
    }
  }
</script>


//不过,这两种方法的弊端是,无法在跨级或兄弟间通信
// parent.vue
<component-a></component-a>
<component-b></component-b>
<component-b></component-b>

我们想在 component-a 中,访问到引用它的页面中(这里就是 parent.vue)的两个 component-b 组件,那这种情况下,就得配置额外的插件或工具了,比如 Vuex 和 Bus 的解决方案。

总结

常见使用场景可以分为三类:

  • 父子通信:
    父向子传递数据是通过 props,子向父是通过 events($emit);通过父链 / 子链也可以通信($parent / $children);ref 也可以访问组件实例;provide / inject API;$attrs/$listeners
  • 兄弟通信:
    Bus;Vuex
  • 跨级通信:
    Bus;Vuex;provide / inject API、$attrs/$listeners

5、vue中路由实现

路由就是SPA(单页应用)的路径管理器,适合用于构建单页面应用。vue的单页面应用是基于路由和组件的,路由用于设定访问路径,并将路径和组件映射起来。传统的页面应用,是用一些超链接来实现页面切换和跳转的。在vue-router单页面应用中,则是路径之间的切换,也就是组件的切换。路由模块的本质 就是建立起url和页面之间的映射关系。

SPA(single page application):单一页面应用程序,只有一个完整的页面;它在加载页面时,不会加载整个页面,而是只更新某个指定的容器中内容。单页面应用(SPA)的核心之一是: 更新视图而不重新请求页面;vue-router在实现单页面前端路由时,提供了两种方式:Hash模式和History模式;根据mode参数来决定采用哪一种方式。

(1)、Hash模式:

vue-router 默认 hash 模式 —— 使用 URL 的 hash 来模拟一个完整的 URL,于是当 URL 改变时,页面不会重新加载。 hash(#)是URL 的锚点,代表的是网页中的一个位置,单单改变#后的部分,浏览器只会滚动到相应位置,不会重新加载网页,也就是说 #是用来指导浏览器动作的,对服务器端完全无用,HTTP请求中也不会不包括#;同时每一次改变#后的部分,都会在浏览器的访问历史中增加一个记录,使用”后退”按钮,就可以回到上一个位置;所以说Hash模式通过锚点值的改变,根据不同的值,渲染指定DOM位置的不同数据

(2)、History模式:

由于hash模式会在url中自带#,如果不想要很丑的 hash,我们可以用路由的 history 模式,只需要在配置路由规则时,加入"mode: 'history'",这种模式充分利用 history.pushState API 来完成 URL 跳转而无须重新加载页面。

6、路由中的钩子函数

全局钩子函数

局部钩子函数

组件内钩子函数

7、一句话就能回答的问题

(1.)css只在当前组件起作用
答:在style标签中写入scoped即可 例如:<style scoped></style>

(2.)v-if 和 v-show 区别
答:v-if按照条件是否渲染,v-show是display的block或none;

(3.)$route$router的区别
答:$route是“路由信息对象”,包括path,params,hash,query,fullPath,matched,name等路由信息参数。而$router是“路由实例”对象包括了路由的跳转方法,钩子函数等。

(4.)vue.js的两个核心是什么?
答:数据驱动、组件系统

(5.)vue几种常用的指令
答:v-for 、 v-if 、v-bind、v-on、v-show、v-else

(6.)vue常用的修饰符?
答:.prevent: 提交事件不再重载页面;.stop: 阻止单击事件冒泡;.self: 当事件发生在该元素本身而不是子元素的时候会触发;.capture: 事件侦听,事件发生的时候会调用

(7.)v-on 可以绑定多个方法吗?
答:可以

(8.)vue中 key 值的作用?
答:当 Vue.js 用 v-for 正在更新已渲染过的元素列表时,它默认用“就地复用”策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序, 而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。key的作用主要是为了高效的更新虚拟DOM。

(9.)什么是vue的计算属性?
答:在模板中放入太多的逻辑会让模板过重且难以维护,在需要对数据进行复杂处理,且可能多次使用的情况下,尽量采取计算属性的方式。好处:①使得数据处理结构清晰;②依赖于数据,数据更新,处理结果自动更新;③计算属性内部this指向vm实例;④在template调用时,直接写计算属性名即可;⑤常用的是getter方法,获取数据,也可以使用set方法改变数据;⑥相较于methods,不管依赖的数据变不变,methods都会重新计算,但是依赖数据不变的时候computed从缓存中获取,不会重新计算。

(10.)vue等单页面应用及其优缺点
答:优点:Vue 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件,核心是一个响应的数据绑定系统。MVVM、数据驱动、组件化、轻量、简洁、高效、快速、模块友好。
缺点:不支持低版本的浏览器,最低只支持到IE9;不利于SEO的优化(如果要支持SEO,建议通过服务端来进行渲染组件);第一次加载首页耗时相对长一些;不可以使用浏览器的导航按钮需要自行实现前进、后退。

(11.)怎么定义 vue-router 的动态路由? 怎么获取传过来的值
答:在 router 目录下的 index.js 文件中,对 path 属性加上 /:id,使用 router 对象的 params.id 获取。

(12)vue的路由使用步骤?

1.下载vue-router路由模块;2.创建路由对象;3.配置路由规则;4.将路由对象注册为vue实例对象的成员属性;

(13)vue创建组件的时候data中为什么会被return出一个对象?

可以保证组件的每一次调用都是创建一个新对象,组件之间不会产生影响

8、vue如何定义一个过滤器

比如后台给我们返回用户的性别,一般来说吧 数据库不会存储男和女的 会存储一个 1 和 0 假设 1代表男性 0代表女性,这个时候 我们不能展示一个 1 和 0到页面上给客户看吧 这个时候 用过滤器就很好了,过滤器可以用在两个地方:双花括号插值和v-bind表达式

<div>
		{{sex | changeSex}}
</div>

filters:{
	changeSex(value){
		if(value===''){
			return false;
		}
		return value==0? '女' : '男';
	}
}

9、vue基础问题

1. Vue 优点

·轻量级框架
  值关注视图层,是一个构建数据的视图集合,大小只有几十kb;
  Vue.js 通过简介的API 提供高效的数据绑定和灵活的组件系统;
·简单易学
  国人开发,中文文档;
·双向数据绑定
  通过MVVM 思想实现数据的双向绑定,让开发者不用再操作DOM 对象,有更多的时间去思考业务逻辑;
·组件化
  Vue.js 通过组件,把一个单页面应用中的各种模块拆分到一个一个单独的组件(component)中,
  我们只要现在父级应用中写好各种组件标签(占坑),并且在组件标签中写好要传入组件的参数,
  然后再分别写好各种组件的实现(填坑),然后整个应用就算完成了;
·虚拟DOM
  把最终的DOM 操作计算出来并优化,由于这个DOM 操作属于预处理操作,并没有真实的操作DOM,
  所以叫做虚拟DOM ,最后在计算完毕才真正将DOM 操作提交,将DOM 操作变化反映到DOM 树上;
·视图,数据,结构分离
  使数据的更改更为简单,不需要进行逻辑代码的修改,只需操作数据就能完成相关操作;
·运行速度更快
  像比较与react 而言,同样都是擦欧总虚拟DOM,就性能而言, Vue 存在很大的优势;

2. 为什么Vue 采用异步渲染?

·因为如果不采用异步更新,那么每次更新数据都会对当前组件进行重新渲染,所以为了性能考虑,
  Vue 会在本轮数据更新后,再去异步更新数据;

3. 请说一下响应式数据的原理?

·采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter, getter
·默认Vue 在初始化数据时,会给data 中的属性使用Object.defineProperty 重新定义所有属性,
  当页面到对应属性时,会进行依赖收集(收集当前组件中的watcher ),
  如果属性发生变化会通知相关依赖进行更新操作;

10.computed和watch有什么区别

computed

computed是计算属性,也就是计算值,它更多用于计算值的场景
computed具有缓存性,computed的值在getter执行后是会缓存的,只有在它依赖的属性值改变之后,下一次获取computed的值时重新调用对应的getter来计算
computed适用于计算比较消耗性能的计算场景

watch

watch更多的是[观察]的作用,类似于某些数据的监听回调,用于观察props $emit或者本组件的值,当数据变化时来执行回调进行后续操作
无缓存性,页面重新渲染时值不变化也会执行 

小结

当我们要进行数值计算,而且依赖于其他数据,那么把这个数据设计为computed
如果你需要在某个数据变化时做一些事情,使用watch来观察这个数据变化。

11、插槽solt---使我们原来的设备具有更多的拓展性

from表单常用、

12、webpack的编译原理

webpack的作用

①、依赖管理:方便引用第三方模块、让模块更容易复用,避免全局注入导致的冲突、避免重复加载或者加载不需要的模块。会一层一层的读取依赖的模块,添加不同的入口;同时,不会重复打包依赖的模块。
②、合并代码:把各个分散的模块集中打包成大文件,减少HTTP的请求链接数,配合UglifyJS(压缩代码)可以减少、优化代码的体积。
③、各路插件:统一处理引入的插件,babel编译ES6文件,TypeScript,eslint 可以检查编译期的错误。
一句话总结:webpack 的作用就是处理依赖,模块化,打包压缩文件,管理插件。
一切皆为模块,由于webpack只支持js文件,所以需要用loader 转换为webpack支持的模块,其中plugin 用于扩张webpack 的功能,在webpack构建生命周期的过程中,在合适的时机做了合适的事情。

webpack怎么工作的过程

①解析配置参数,合并从shell(npm install 类似的命令)和webpack.config.js文件的配置信息,输出最终的配置信息;
②注册配置中的插件,让插件监听webpack构建生命周期中的事件节点,做出对应的反应;
③解析配置文件中的entry入口文件,并找出每个文件依赖的文件,递归下去;
④在递归每个文件的过程中,根据文件类型和配置文件中的loader找出对应的loader对文件进行转换;
⑤递归结束后得到每个文件最终的结果,根据entry 配置生成代码chunk(打包之后的名字);
⑥输出所以chunk 到文件系统。

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值