un9--vue面试题

聊聊对vue的理解

vue是一个渐进式的JS框架。他易用,灵活,高效; 可以把一个页面分隔成多个组件;当其他页面有类似功能时,直接让封装的组件进行复用; 他是构建用户界面的声明式框架,只关心图层;不关心具体是如何实现的

V-model的是什么?

Vue的双向数据绑定是由数据劫持结合发布者订阅者实现的。 数据劫持是通过Object.defineProperty()来劫持对象数据的setter和getter操作。 在数据变动时作你想做的事

  • 通过Observer来监听自己的model数据变化,通过Compile来解析编译模板指令,最终利用Watcher搭起Observer和Compile之间的通信桥梁,达到数据变化->视图更新 在初始化vue实例时,遍历data这个对象,给每一个键值对利用Object.definedProperty对data的键值对新增get和set方法,利用了事件监听DOM的机制,让视图去改变数据
谈谈对生命周期的理解
  • beforeCreate阶段:vue实例的挂载元素el和数据对象data都是undefined,还没有初始化。
  • created阶段:vue实例的数据对象data有了,可以访问里面的数据和方法,未挂载到DOM,el还没有
  • beforeMount阶段:vue实例的el和data都初始化了,但是挂载之前为虚拟的dom节点
  • mounted阶段:vue实例挂载到真实DOM上,就可以通过DOM获取DOM节点
  • beforeUpdate阶段:响应式数据更新时调用,发生在虚拟DOM打补丁之前,适合在更新之前访问现有的DOM,比如手动移除已添加的事件监听器
  • updated阶段:虚拟DOM重新渲染和打补丁之后调用,组成新的DOM已经更新,避免在这个钩子函数中操作数据,防止死循环
  • beforeDestroy阶段:实例销毁前调用,实例还可以用,this能获取到实例,常用于销毁定时器,解绑事件
  • destroyed阶段:实例销毁后调用,调用后所有事件监听器会被移除,所有的子实例都会被销毁
VUE和REACT有什么区别?

react整体是函数式的思想,把组件设计成纯组件,状态和逻辑通过参数传入,所以在react中,是单向数据流;

vue的思想是响应式的,也就是基于是数据可变的,通过对每一个属性建立Watcher来监听,当属性变化的时候,响应式的更新对应的虚拟dom。

vuex的流程
页面通过mapAction异步提交事件到action。action通过commit把对应参数同步提交到mutation。
mutation会修改state中对于的值。 最后通过getter把对应值跑出去,在页面的计算属性中
通过mapGetter来动态获取state中的值

vuex有哪几种状态和属性
  • state中保存着共有数据,数据是响应式的
  • getter可以对state进行计算操作,主要用来过滤一些数据,可以在多组件之间复用
  • mutations定义的方法动态修改state中的数据,通过commit提交方法,方法必须是同步的
  • actions将mutations里面处理数据的方法变成异步的,就是异步操作数据,通store.dispatch来分发actions,把异步的方法写在actions中,通过commit提交mutations,进行修改数据。
  • modules:模块化vuex
vue路由的两种模式
  • hash ——即地址栏URL中的#符号(此hsah 不是密码学里的散列运算) hash 虽然出现URL中,但不会被包含在HTTP请求中,对后端完全没有影响,因此改变hash不会重新加载页面。
  • history ——利用了HTML5 History Interface 中新增的pushState() 和replaceState() 方法

这两个方法应用于浏览器的历史记录站,在当前已有的back、forward、go 的基础之上,它们提供了对历史记录进行修改的功能。只是当它们执行修改是,虽然改变了当前的URL,但你浏览器不会立即向后端发送请求。

vue中 key 值的作用

当 Vue.js 用v-for正在更新已渲染过的元素列表时,它默认用“就地复用”策略。 如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序,而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。

key的作用主要是为了高效的更新虚拟DOM。

$route$router的区别
  • $route是“路由信息对象”,包括path,params,hash,query,fullPath,matched,name等路由信息参数。
  • $router是“路由实例”对象包括了路由的跳转方法,钩子函数等。
vue-router守卫
  • 导航守卫 router.beforeEach 全局前置守卫
  • to: Route: 即将要进入的目标(路由对象)
  • from: Route: 当前导航正要离开的路由
  • next: Function: 一定要调用该方法来 resolve 这个钩子。(一定要用这个函数才能去到下一个路由,如果不用就拦截) 执行效果依赖 next 方法的调用参数。
  • next(): 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。
  • next(false): 取消进入路由,url地址重置为from路由地址(也就是将要离开的路由地址)。
// main.js 入口文件
    import router from './router'; // 引入路由
    router.beforeEach((to, from, next) => { 
      next();
    });
    router.beforeResolve((to, from, next) => {
      next();
    });
    router.afterEach((to, from) => {
      console.log('afterEach 全局后置钩子');
    });


路由独享的守卫 你可以在路由配置上直接定义 beforeEnter 守卫

const router = new VueRouter({
  routes: [
    {
      path: '/foo',
      component: Foo,
      beforeEnter: (to, from, next) => {
        // ...
      }
    }
  ]
})

组件内的守卫 你可以在路由组件内直接定义以下路由导航守卫

const Foo = {
  template: `...`,
  beforeRouteEnter (to, from, next) {
    // 在渲染该组件的对应路由被 confirm 前调用
    // 不!能!获取组件实例 `this`
    // 因为当守卫执行前,组件实例还没被创建
  },
  beforeRouteUpdate (to, from, next) {
    // 在当前路由改变,但是该组件被复用时调用
    // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
    // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
    // 可以访问组件实例 `this`
  },
  beforeRouteLeave (to, from, next) {
    // 导航离开该组件的对应路由时调用,我们用它来禁止用户离开
    // 可以访问组件实例 `this`
    // 比如还未保存草稿,或者在用户离开前,
    将setInterval销毁,防止离开之后,定时器还在调用。
  }
}

axios是什么?怎么使用?描述使用它实现登录功能的流程?

请求后台资源的模块。

$ npm install axios -S装好

然后发送的是跨域,需在配置文件中config/index.js进行设置。后台如果是Tp5则定义一个资源路由。 js中使用import进来,然后.get或.post。返回在.then函数中如果成功,失败则是在.catch函数中

vue修饰符
  • stop:阻止事件的冒泡
  • prevent:阻止事件的默认行为
  • once:只触发一次
  • self:只触发自己的事件行为时,才会执行
vue项目中的性能优化

1.不要在模板里面写过多表达式

2.循环调用子组件时添加key

3.频繁切换的使用v-show,不频繁切换的使用v-if

4.尽量少用float,可以用flex

5.按需加载,可以用require或者import()按需加载需要的组件

6.路由懒加载

vue.extend和vue.component
  • extend 是构造一个组件的语法器。 然后这个组件你可以作用到Vue.component这个全局注册方法里 还可以在任意vue模板里使用组件。 也可以作用到vue实例或者某个组件中的components属性中并在内部使用apple组件。
  • Vue.component 你可以创建 ,也可以取组件。
Vue组件间的参数传递

父组件与子组件传值

父组件传给子组件:子组件通过props方法接受数据;

  • 子组件传给父组件: $emit 方法传递参数

非父子组件间的数据传递,兄弟组件传值

eventBus,就是创建一个事件中心,相当于中转站,可以用它来传递事件和接收事件。项目比较小时,用这个比较合适(虽然也有不少人推荐直接用VUEX,具体来说看需求)

Vue的路由实现:hash模式 和 history模式
  • hash模式:在浏览器中符号“#”,#以及#后面的字符称之为hash,用 window.location.hash 读取。特点:hash虽然在URL中,但不被包括在HTTP请求中;用来指导浏览器动作,对服务端安全无用,hash不会重加载页面。
  • history模式:history采用HTML5的新特性;且提供了两个新方法: pushState()replaceState()可以对浏览器历史记录栈进行修改,以及popState事件的监听到状态变更
v-if 和 v-show 区别
  • v-if按照条件是否渲染,v-showdisplayblocknone
keep-alive的作用是什么
  • 包裹动态组件时,会缓存不活动的组件实例,主要用于保留组件状态或避免重新渲染

比如有一个列表和一个详情,那么用户就会经常执行打开详情=>返回列表=>打开详情…这样的话列表和详情都是一个频率很高的页面,那么就可以对列表组件使用``进行缓存,这样用户每次返回列表的时候,都能从缓存中快速渲染,而不是重新渲染

指令v-el的作用是什么

提供一个在页面上已存在的 DOM元素作为 Vue实例的挂载目标.可以是 CSS 选择器,也可以是一个 HTMLElement 实例,

在Vue中使用插件的步骤
  • 采用ES6import ... from ...语法或CommonJSrequire()方法引入插件
  • 使用全局方法Vue.use( plugin )使用插件,可以传入一个选项对象Vue.use(MyPlugin, { someOption: true })
vue的优点是什么?
  • 低耦合。视图(View)可以独立于Model变化和修改,一个ViewModel可以绑定到不同的"View"上,当View变化的时候Model可以不变,当Model变化的时候View也可以不变
  • 可重用性。你可以把一些视图逻辑放在一个ViewModel里面,让很多view重用这段视图逻辑
  • 可测试。界面素来是比较难于测试的,而现在测试可以针对ViewModel来写
路由之间跳转?

声明式(标签跳转)

<router-link :to="index">

编程式( js跳转)

router.push('index')
Vue 组件 data 为什么必须是函数
  • 每个组件都是 Vue 的实例。
  • 组件共享 data 属性,当 data 的值是同一个引用类型的值时,改变其中一个会影响其他
怎么快速定位哪个组件出现性能问题

timeline 工具。 大意是通过 timeline 来查看每个函数的调用时常,定位出哪个函数的问题,从而能判断哪个组件出了问题

extend 能做什么

这个 API 很少用到,作用是扩展组件生成一个构造器,通常会与 $mount 一起使用。

// 创建组件构造器
let Component = Vue.extend({
  template: '<div>test</div>'
})
// 挂载到 #app 上
new Component().$mount('#app')
// 除了上面的方式,还可以用来扩展已有的组件
let SuperComponent = Vue.extend(Component)
new SuperComponent({
    created() {
        console.log(1)
    }
})
new SuperComponent().$mount('#app')
mixin 和 mixins 区别

mixin 用于全局混入,会影响到每个组件实例,通常插件都是这样做初始化的

Vue.mixin({
    beforeCreate() {
        // ...逻辑
        // 这种方式会影响到每个组件的 beforeCreate 钩子函数
    }
})
  • 虽然文档不建议我们在应用中直接使用 mixin,但是如果不滥用的话也是很有帮助的,比如可以全局混入封装好的 ajax 或者一些工具函数等等。
  • mixins 应该是我们最常使用的扩展组件的方式了。如果多个组件中有相同的业务逻辑,就可以将这些逻辑剥离出来,通过 mixins 混入代码,比如上拉下拉加载数据这种逻辑等等。
  • 另外需要注意的是 mixins 混入的钩子函数会先于组件内的钩子函数执行,并且在遇到同名选项的时候也会有选择性的进行合并,具体可以阅读 文档。
computed 和 watch 区别
  • computed 是计算属性,依赖其他属性计算值,并且 computed 的值有缓存,只有当计算值变化才会返回内容。
  • watch 监听到值的变化就会执行回调,在回调中可以进行一些逻辑操作。
  • 所以一般来说需要依赖别的属性来动态获得值的时候可以使用 computed,对于监听到值的变化需要做一些复杂业务逻辑的情况可以使用 watch
  • 另外 computerwatch 还都支持对象的写法,这种方式知道的人并不多。
vm.$watch('obj', {
    // 深度遍历
    deep: true,
    // 立即触发
    immediate: true,
    // 执行的函数
    handler: function(val, oldVal) {}
})
var vm = new Vue({
  data: { a: 1 },
  computed: {
    aPlus: {
      // this.aPlus 时触发
      get: function () {
        return this.a + 1
      },
      // this.aPlus = 1 时触发
      set: function (v) {
        this.a = v - 1
      }
    }
  }
})


Proxy 相比于 defineProperty 的优势
  • 数组变化也能监听到
  • 不需要深度遍历监听
let data = { a: 1 }
let reactiveData = new Proxy(data, {
	get: function(target, name){
		// ...
	},
	// ...
})

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值