Vue中级面试题汇总(二)

Vue组件里写的原生addEventListeners监听事件,要手动去销毁吗?为什么?

要,不然会造成多次绑定和内存泄露 

Vue组件里的定时器要怎么销毁? 

  • 如果页面上有很多定时器,可以在data选项中创建一个对象timer,给每个定时器取个名字一一映射在对象timer中,

beforeDestroy构造函数中for(let k in this.timer){clearInterval(k)}

  • 如果页面只有单个定时器,可以这么做。
const timer = setInterval(() =>{}, 500);
this.$once('hook:beforeDestroy', () => {
   clearInterval(timer);
})

 Vue中能监听到数组变化的方法有哪些?为什么这些方法能监听到呢?

  • push()pop()shift()unshift()splice()sort()reverse(),这些方法在Vue中被重新定义了,故可以监听到数组变化;
  • filter()concat()slice(),这些方法会返回一个新数组,也可以监听到数组的变化。

在Vue中那些数组变化无法监听,为什么,怎么解决? 

  • 利用索引直接设置一个数组项时;

  • 修改数组的长度时。

    • 第一个情况,利用已有索引直接设置一个数组项时Object.defineProperty()可以监听到,利用不存在的索引直接设置一个数组项时Object.defineProperty()不可以监听到,但是官方给出的解释是由于JavaScript的限制,Vue不能检测以上数组的变动,其实根本原因是性能问题,性能代价和获得的用户体验收益不成正比。
    • 第二个情况,原因是Object.defineProperty()不能监听到数组的length属性。
  • this.$set(this.items, indexOfItem, newValue)this.items.splice(indexOfItem, 1, newValue)来解决第一种情况;

  • this.items.splice(newLength)来解决第二种情况。

在Vue中那些对象变化无法监听,为什么,怎么解决? 

  • 对象属性的添加
  • 对象属性的删除

因为Vue是通过Object.defineProperty来将对象的key转成getter/setter的形式来追踪变化,但getter/setter只能追踪一个数据是否被修改,无法追踪新增属性和删除属性,所以才会导致上面对象变化无法监听。

  • this.$set(this.obj,"key","newValue")来解决第一种情况;
  • Object.assign来解决第二种情况。

删除对象用delete和Vue.delete有什么区别? 

  • delete:只是被删除对象成员变为' 'undefined,其他元素键值不变;
  • Vue.delete:直接删了对象成员,如果对象是响应式的,确保删除能触发更新视图,这个方法主要用于避开 Vue 不能检测到属性被删除的限制。

watch和计算属性有什么区别? 

  • watch:一个数据影响多个数据,当需要在数据变化时执行异步或开销较大的操作时;
  • 计算属性:一个数据受多个数据影响。是基于它的响应式依赖进行缓存的,只在相关响应式依赖发生改变时它才会重新求值。

计算属性和方法有什么区别? 

  • 计算属性:是基于它们的响应式依赖进行缓存的,只在相关响应式依赖发生改变时它们才会重新求值。
  • 方法:每当触发重新渲染时,调用方法将总会再次执行函数。当我们不希望有缓存,可以使用方法,但是如果求值开销大时建议用计算属性。

Vue怎么定义全局方法

挂载在Vue的prototype上 

// base.js
const install = function (Vue, opts) {
    Vue.prototype.demo = function () {
        console.log('我已经在Vue原型链上')
    }
}
export default {
    install
}
//main.js
//注册全局函数
import base from 'service/base';
Vue.use(base);
  • 利用全局混入mixin

  • this.$root.$on绑定方法,用this.$root.$off解绑方法,用this.$root.$emit全局调用。

this.$root.$on('demo',function(){
    console.log('test');
})
this.$root.$emit('demo');
this.$root.$off('demo');

 <template></template>有什么用?

当做一个不可见的包裹元素,减少不必要的DOM元素,整个结构会更加清晰。 

Vue怎么改变插入模板的分隔符? 

delimiters选项,其默认是["{{", "}}"] 

// 将分隔符变成ES6模板字符串的风格
new Vue({
  delimiters: ['${', '}']
})

 Vue变量名如果以_、$开头的属性会发生什么问题?怎么访问到它们的值?

以 或 $ 开头的属性 不会 被 Vue 实例代理,因为它们可能和 Vue 内置的属性、API 方法冲突,你可以使用例如 vm.$data._property 的方式访问这些属性。 

怎么捕获Vue组件的错误信息? 

  • errorCaptured是组件内部钩子,当捕获一个来自子孙组件的错误时被调用,接收errorvminfo三个参数,return false后可以阻止错误继续向上抛出。
  • errorHandler为全局钩子,使用Vue.config.errorHandler配置,接收参数与errorCaptured一致,2.6后可捕捉v-onpromise链的错误,可用于统一错误处理与错误兜底。

Vue.observable你有了解过吗?说说看 

让一个对象可响应。可以作为最小化的跨组件状态存储器 

Vue项目中如何配置favicon? 

  • 静态配置 <link rel="icon" href="<%= BASE_URL %>favicon.ico">,

其中<%= BASE_URL %>等同vue.config.js中publicPath的配置;

  • 动态配置<link rel="icon" type="image/png" href="">
import browserImg from 'images/kong.png';//为favicon的默认图片
const imgurl ='后端传回来的favicon.ico的线上地址'
let link = document.querySelector('link[type="image/png"]');
if (imgurl) {
    link.setAttribute('href', imgurl);
} else {
    link.setAttribute('href', browserImg);
}

 怎么修改Vue项目打包后生成文件路径?

  • 在Vue CLI2中修改config/index.js文件中的build.assetsPublicPath的值;
  • 在Vue CLI3中配置publicPath的值。

怎么解决Vue项目打包后静态资源图片失效的问题? 

在项目中一般通过配置alias路径别名的方式解决,下面是Vue CLI3的配置。 

configureWebpack: {
    resolve: {
        extensions: ['.js', '.vue', '.json'],
        alias: {
            '@': resolve('src'),
            'assets': resolve('src/assets'),
            'css': resolve('src/assets/css'),
            'images': resolve('src/assets/images'),
        }
    },
},

 怎么解决Vue中动态设置img的src不生效的问题?

因为动态添加src被当做静态资源处理了,没有进行编译,所以要加上require。 

<template>
    <img class="logo" :src="logo" alt="公司logo">
</template>
<script>
export default {
    data() {
        return {
            logo:require("assets/images/logo.png"),
        };
    }
};
</script>

 在Vue项目中如何引入第三方库(比如jQuery)?有哪些方法可以做到?

  • 先在主入口页面 index.html 中用 script 标签引入<script src="./static/jquery-1.12.4.js"></script>,如果你的项目中有用ESLint检测,会报'$' is not defined,要在文件中加上/* eslint-disable */
  • 先在主入口页面 index.html 中用 script 标签引入<script src="./static/jquery-1.12.4.js"></script>,然后在webpack 中配置一个 externals,即可在项目中使用。
externals: {
    'jquery': 'jQuery'
}

 先在webpack中配置alias,最后在main.js中用import $ from 'jquery',即可在项目中使用

resolve: {
    extensions: ['.js', '.vue', '.json'],
    alias: {
        '@': resolve('src'),
        'jquery': resolve('static/jquery-1.12.4.js')
    }
}

 在webpack中新增一个plugins,即可在项目中使用

plugins: [
         new webpack.ProvidePlugin({
             $:"jquery",
             jQuery:"jquery",
             "windows.jQuery":"jquery"
         })
     ]

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值