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
是组件内部钩子,当捕获一个来自子孙组件的错误时被调用,接收error
、vm
、info
三个参数,return false
后可以阻止错误继续向上抛出。errorHandler
为全局钩子,使用Vue.config.errorHandler
配置,接收参数与errorCaptured
一致,2.6后可捕捉v-on
与promise
链的错误,可用于统一错误处理与错误兜底。
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"
})
]