MST

星途 面试题库

面试题:Vue Provide/Inject复杂场景下的数据污染规避

在一个多层嵌套的Vue组件结构中,顶层组件通过Provide传递了一个包含多个属性和方法的复杂对象。中间层和底层组件都通过Inject使用这个对象。在底层组件中,由于业务逻辑需要,可能会在某些情况下意外改变对象的属性值,导致整个数据链路的数据污染。请阐述如何设计一个方案,既能让底层组件在需要时操作数据,又能有效避免数据污染其他使用该数据的组件。
37.2万 热度难度
前端开发Vue

知识考点

AI 面试

面试题答案

一键面试
  1. 数据拷贝
    • 在底层组件inject获取对象后,使用JSON.parse(JSON.stringify())或者lodashcloneDeep方法对该对象进行深拷贝。例如:
import _ from 'lodash';
export default {
    inject: ['parentObject'],
    data() {
        return {
            localObject: _.cloneDeep(this.parentObject)
        };
    }
};
- 这样底层组件操作的是本地的拷贝对象,不会影响到原对象,也就避免了数据污染其他组件。

2. 使用Vuex(状态管理工具) - 将顶层组件传递的复杂对象放在Vuex的状态中进行管理。 - 底层组件通过mapState辅助函数获取状态数据,并通过mapMutations触发Vuex中的mutation来操作数据。 - 例如,在store.js中定义:

const store = new Vuex.Store({
    state: {
        complexObject: { /* 具体属性和方法 */ }
    },
    mutations: {
        updateComplexObject(state, newData) {
            // 对state.complexObject进行更新操作
            Object.assign(state.complexObject, newData);
        }
    }
});
- 在底层组件中:
import { mapState, mapMutations } from 'vuex';
export default {
    computed: {
       ...mapState(['complexObject'])
    },
    methods: {
       ...mapMutations(['updateComplexObject']),
        handleDataChange() {
            // 操作数据
            const newData = { /* 新数据 */ };
            this.updateComplexObject(newData);
        }
    }
};
- 这种方式通过Vuex的集中式状态管理,确保数据的变更遵循一定的规则,避免意外的数据污染。

3. 事件总线(Event Bus) - 在顶层组件中,监听来自底层组件的自定义事件。 - 底层组件在需要操作数据时,通过$emit触发一个自定义事件,并传递需要修改的数据。 - 例如,在顶层组件中:

<template>
    <div>
        <!-- 其他组件结构 -->
        <BottomComponent @update - complex - object="handleUpdate" />
    </div>
</template>
<script>
import BottomComponent from './BottomComponent.vue';
export default {
    components: { BottomComponent },
    data() {
        return {
            complexObject: { /* 具体属性和方法 */ }
        };
    },
    methods: {
        handleUpdate(newData) {
            // 对complexObject进行更新操作
            Object.assign(this.complexObject, newData);
        }
    }
};
</script>
- 在底层组件中:
<template>
    <div>
        <button @click="handleClick">操作数据</button>
    </div>
</template>
<script>
export default {
    methods: {
        handleClick() {
            const newData = { /* 新数据 */ };
            this.$emit('update - complex - object', newData);
        }
    }
};
</script>
- 通过这种方式,底层组件不直接操作传递下来的对象,而是通过事件通知顶层组件进行数据更新,从而避免数据污染其他组件。