如何将Vuex Store绑定到KendoUI-Vue Grid的transport read?
问题排查与解决方案
首先可以明确,问题出在Kendo DataSource的配置上,而非Vuex部分。Vuex的getter逻辑是正常的,核心问题有两个:this指向错误,以及Kendo数据源未监听Vue响应式数据的变化。
问题根源分析
this指向丢失:在transport.read的普通函数中,this并不指向Vue组件实例,而是指向transport对象本身,所以this.customers自然是undefined。当Kendo Grid尝试读取返回数据的length属性时,就会抛出TypeError: Cannot read property 'length' of undefined。- 响应式同步缺失:即便解决了
this指向问题,直接传入this.customers后,当Vuex中的customers数据更新时,Kendo Grid也不会自动刷新,因为Kendo DataSource没有监听Vue的响应式数据变化。
修复后的完整代码
组件代码修改
<template> <kendo-grid ref="gridRef" :data-source="kendoDataSource"></kendo-grid> </template> <script> export default { computed: { customers() { return this.$store.getters.customers; } }, data() { return { kendoDataSource: { schema: { data: function(response) { return response; }, model: { id: "CustomerID", fields: { CompanyName: { type: "string" } } } }, // 使用箭头函数继承外部组件的this指向 transport: { read: (options) => { options.success(this.customers); } } } }; }, watch: { // 监听Vuex中customers的变化,同步更新Kendo Grid customers(newVal) { if (this.$refs.gridRef) { const grid = this.$refs.gridRef.kendoWidget(); grid.dataSource.data(newVal); } } }, mounted() { // 初始化时手动触发一次数据源读取 if (this.$refs.gridRef) { const grid = this.$refs.gridRef.kendoWidget(); grid.dataSource.read(); } } }; </script>
关键修改说明
- 箭头函数修正
this指向:把transport.read的普通函数改成箭头函数,这样this就会指向Vue组件实例,能正确访问到this.customers(即Vuex getter返回的数据)。 - watch监听响应式变化:通过
watch监听customers的变化,当数据更新时,获取Kendo Grid实例并调用dataSource.data(newVal),强制刷新Grid数据,保证Vuex数据和Grid展示同步。 - mounted初始化读取:在组件挂载完成后手动触发一次数据源读取,确保初始数据能正确渲染到Grid中。
Vuex部分验证
你的Store代码是正常的:
export default { state: { customers: JSON.parse(JSON.stringify(customers)) }, getters: { customers(state) { return state.customers; } } };
只要customers初始数据格式正确(你给出的数组格式没问题),Vuex就能正确返回数据,不需要修改。
测试验证
完成修改后:
- 组件挂载时,Grid会通过
transport.read获取Vuex的初始数据并渲染。 - 当Vuex中的
customers数据更新时,watch会触发Grid数据源更新,页面会自动刷新展示新数据。 - 不会再出现
Cannot read property 'length' of undefined的错误。
内容的提问来源于stack exchange,提问作者Rasik
相关产品推荐
相关产品推荐

