关于 Vue 的一些问题(面试中面试官想听到的答案)
关于vue生命周期(钩子函数)
beforeCreate、created(此时需说明可以在created中首次拿到data中定义的数据)、beforeMount、mounted(此时需说明dom树渲染结束,可访问dom结构)、beforeUpdate、updated、beforeDestroy、destroyed;
watch监听对象
如果只是监听obj内的某一个属性变化,可以直接obj.key进行监听。
watch: {
'obj.question': function(newQuestion, oldQuestion) {
this.answer = 'Waiting for you to stop typing...'
this.debouncedGetAnswer()
}
}
如果对整个obj深层监听
watch: {
obj: {
handler: function(newQuestion, oldQuestion) {
this.answer = 'Waiting for you to stop typing...'
this.debouncedGetAnswer()
},
deep: true,
immediate: true
}
}
immediate的作用:当值第一次进行绑定的时候并不会触发watch监听,使用immediate则可以在最初绑定的时候执行。
$nextTick的作用
在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。(官网解释)
解决的问题:有些时候在改变数据后立即要对dom进行操作,此时获取到的dom仍是获取到的是数据刷新前的dom,无法满足需要,这个时候就用到了$nextTick。
// 修改数据
vm.msg = 'Hello'
// DOM 还没有更新
Vue.nextTick(function() {
// DOM 更新了
})
// 作为一个 Promise 使用 (2.1.0 起新增,详见接下来的提示)
Vue.nextTick().then(function() {
// DOM 更新了
})
$set的作用
向响应式对象中添加一个属性,并确保这个新属性同样是响应式的,且触发视图更新。它必须用于向响应式对象上添加新属性,因为 Vue 无法探测普通的新增属性 (比如 this.myObject.newProperty = 'hi')---来自官网。在实际开发中,data中定义的对象,如果是新增属性比如中数组中push一个值,此时数据虽然是更新了,但是视图没有更新,这时候就需要用到$set;
组件间的传值
组件间的传值分为多种:父传子:props;子传父:$emit;兄弟:eventbus;vuex;其它的比如:sessionStorage和localStorage、路由传参;除开这些,还有以下的方式,比如:
- provide / inject,这对选项需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在起上下游关系成立的时间里始终生效。
const Third = {
template: `
<div>
<div>This is the third component!</div>
provide/inject:{{demo}}
</div>
`,
inject: ['for'],
data() {
return {
demo: this.for
}
}
}
const Two = {
template: `
<div>
<div>This is the second component!</div>
<Third></Third>
</div>
`,
components: { Third }
}
const One = {
template: `
<div>
<div>This is the first component!</div>
<Two></Two>
</div>
`,
components: { Two },
provide: {
for: 'demo'
}
}
new Vue({
el: '#app',
template: '<One></One>',
components: { One }
})
- Vue.observable,让一个对象可响应。Vue 内部会用它来处理 data 函数返回的对象。
返回的对象可以直接用于渲染函数和计算属性内,并且会在发生改变时触发相应的更新。见下面例子:
const state = Vue.observable({ count: 0 });
const Two = {
template: `
<div>
<div>This is the second component!</div>
<p>count:{{state.count}}</p>
<div><button @click="clickMe">click</button></div>
</div>
`,
data() {
return {
state
}
},
methods: {
clickMe() {
this.state.count++;
}
}
}
const One = {
template: `
<div>
<div>This is the first component!</div>
<p>count:{{state.count}}</p>
<Two></Two>
</div>
`,
components: { Two }
}
const vue = new Vue({
el: '#app',
template: '<One></One>',
components: { One }
})
- $attrs,包含了父作用域中不作为 prop 被识别 (且获取) 的特性绑定 (class 和 style 除外)。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (class 和 style 除外),并且可以通过 v-bind="$attrs" 传入内部组件——在创建高级别的组件时非常有用。
- $listeners、包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on="$listeners" 传入内部组件——在创建更高层次的组件时非常有用。