面试题答案
一键面试- 将普通JavaScript对象转换为响应式数据:
在Vue中,可以使用
Vue.observable
或者reactive
(Vue 3)来将普通JavaScript对象转换为响应式数据。- Vue 2(使用
Vue.observable
):import Vue from 'vue'; const myObject = { message: 'Hello' }; const reactiveObject = Vue.observable(myObject); export default { data() { return { reactiveObject }; } };
- Vue 3(使用
reactive
):import { reactive } from 'vue'; const myObject = { message: 'Hello' }; const reactiveObject = reactive(myObject); export default { setup() { return { reactiveObject }; } };
- Vue 2(使用
- 添加新属性时遇到的响应式问题:
- Vue 2:在Vue 2中,直接给响应式对象添加新属性,视图不会更新。因为Vue在初始化对象时,会对对象的属性进行递归遍历并使用
Object.defineProperty
进行数据劫持。新添加的属性没有经过这个过程,所以不是响应式的。 - Vue 3:在Vue 3中,使用
reactive
创建的响应式对象是Proxy代理对象,虽然添加新属性时不会像Vue 2那样完全没有响应式,但是如果在模板中直接使用新添加的属性,可能会遇到未在初始化时声明的问题(取决于模板编译等因素)。
- Vue 2:在Vue 2中,直接给响应式对象添加新属性,视图不会更新。因为Vue在初始化对象时,会对对象的属性进行递归遍历并使用
- 解决方法:
- Vue 2:
- 使用
Vue.set
(全局方法)或this.$set
(组件实例方法)来添加新属性。例如:
import Vue from 'vue'; const myObject = { message: 'Hello' }; const reactiveObject = Vue.observable(myObject); // 添加新属性 Vue.set(reactiveObject, 'newProperty', 'New Value'); // 在组件中使用 export default { data() { return { reactiveObject }; }, mounted() { this.$set(this.reactiveObject, 'newPropertyInComponent', 'Value in component'); } };
- 使用
- Vue 3:
- 由于
reactive
返回的是Proxy对象,直接添加新属性通常能保持响应式。但是为了更好的代码结构和避免潜在问题,可以在定义响应式对象时,提前声明可能会使用的属性(即使初始值为null
或undefined
)。如果要动态添加属性,可以直接添加。例如:
import { reactive } from 'vue'; const myObject = { message: 'Hello' }; const reactiveObject = reactive(myObject); // 添加新属性 reactiveObject.newProperty = 'New Value'; export default { setup() { return { reactiveObject }; } };
- 由于
- Vue 2: