Vue 3 + Typescript + Vuex + DevExtreme 的反应性问题
Reactivity issues with Vue 3 + Typescript + Vuex + DevExtreme
我正在实现一个用作搜索引擎的组件,也就是说,对于我在输入中插入的每个字符,都必须向后面发出请求并且必须更新结果。我正在使用自动完成功能实现它,结果将是我将在下面显示的结果:
这张图是我通过mock后面返回的对象得到的。如果我从 vuex 模块执行相同的过程,我不会得到结果。
我的步骤如下。首先我实现了Vuex模块如下:
export type State = {
results: any[]
}
const state: State = {
results: [],
}
const mutations: MutationTree<State> = {
SET_RESULTS(state: any, payload: any) {
state.results = payload.resultsByType;
console.log(state.results)
}
}
const actions: ActionTree<State, any> = {
async getResults({ commit }: any, query: string) {
await itiHttpService.get(API.documents + '/search/' + query, null, false).then((res: any) => {
commit('SET_RESULTS', res);
});
},
}
const getters: GetterTree<State, any> = {
results: (state: any) => state.results,
}
const searchModule = {
namespaced: true,
state,
mutations,
actions,
getters
}
export default searchModule;
我在突变上设置的 console.log 每个控制台给出以下结果:
setup(){
...
let resultsValue: ResultFilterDto[] = [];
const results = computed(() => { return store.state['searchModule'].results });
function valueChangedGetResults(e: any) {
var textWrited = e.value;
if (textWrited !== null && textWrited !== undefined && textWrited.length >= minQueryLength) {
store.dispatch('searchModule/getResults', textWrited);
}
}
watch(
results,
() => {
resultsValue = results.value;
console.log(resultsValue);
}
);
...
我从我的组件创建了一个计算 属性 来访问我的商店的状态信息,然后我创建了一个手表来观察发生的变化。我还有 valueChangedGetResult 方法,每次我键入一个超过 3 个字符的单词时,都会执行分派以查询后面的内容。后面的查询正确完成,信息在 resultsValue 中更新,因为它从控制台获取所有信息。
我的html中的代码如下
我所解释的自动完成方式不起作用并且不显示任何结果,但是,如果我像下面这样模拟对象并放入 HTML 的数据源变量测试,有效。我究竟做错了什么?非常感谢!
var test: any = [{
key: 'Inbox',
items: [{
id: 17,
name: "test1.txt",
extension: null,
summary: "Name: test1.txt\tInboxName: Inbox 1\t",
highLigths: "Name: <span style='font-weight:bold'>test</span>1.txt \r\n",
creationDate: "0001-01-01T00:00:00Z",
inboxName: "Inbox 1",
inboxId: 1,
folderId: 0,
folderName: null,
categoryId: 0,
categoryName: null,
typeId: 0,
typeName: null,
subTypeId: 0,
subTypeName: null
},
{
id: 17,
name: "test1.txt",
extension: null,
summary: "Name: test1.txt\tInboxName: Inbox 1\t",
highLigths: "Name: <span style='font-weight:bold'>test</span>1.txt \r\n",
creationDate: "0001-01-01T00:00:00Z",
inboxName: "Inbox 1",
inboxId: 1,
folderId: 0,
folderName: null,
categoryId: 0,
categoryName: null,
typeId: 0,
typeName: null,
subTypeId: 0,
subTypeName: null
}
]
}, {
key: 'Archive',
items: [{
id: 17,
name: "test1.txt",
extension: null,
summary: "Name: test1.txt\tInboxName: Inbox 1\t",
highLigths: "Name: <span style='font-weight:bold'>test</span>1.txt \r\n",
creationDate: "0001-01-01T00:00:00Z",
inboxName: "Inbox 1",
inboxId: 1,
folderId: 0,
folderName: null,
categoryId: 0,
categoryName: null,
typeId: 0,
typeName: null,
subTypeId: 0,
subTypeName: null
}]
}];
主要问题是您在模板中使用了 resultsValue
变量,但它不是反应式的...它只是普通数组。更改它不会重新呈现模板...
您可以通过 let resultsValue = ref<ResultFilterDto[]>([]);
修复它(不要忘记从 vue
导入 ref
)并将分配更改为 resultsValue.value = results.value
但是 你根本不需要 resultsValue
变量。您已经有一个被动 computed
值 results
。因此,只需从您的代码中删除 resultsValue
并在模板中使用 results
即可....
setup(){
const results = computed(() => { return store.state['searchModule'].results });
function valueChangedGetResults(e: any) {
var textWrited = e.value;
if (textWrited !== null && textWrited !== undefined && textWrited.length >= minQueryLength) {
store.dispatch('searchModule/getResults', textWrited);
}
}
return {
results
}
}
我正在实现一个用作搜索引擎的组件,也就是说,对于我在输入中插入的每个字符,都必须向后面发出请求并且必须更新结果。我正在使用自动完成功能实现它,结果将是我将在下面显示的结果:
这张图是我通过mock后面返回的对象得到的。如果我从 vuex 模块执行相同的过程,我不会得到结果。
我的步骤如下。首先我实现了Vuex模块如下:
export type State = {
results: any[]
}
const state: State = {
results: [],
}
const mutations: MutationTree<State> = {
SET_RESULTS(state: any, payload: any) {
state.results = payload.resultsByType;
console.log(state.results)
}
}
const actions: ActionTree<State, any> = {
async getResults({ commit }: any, query: string) {
await itiHttpService.get(API.documents + '/search/' + query, null, false).then((res: any) => {
commit('SET_RESULTS', res);
});
},
}
const getters: GetterTree<State, any> = {
results: (state: any) => state.results,
}
const searchModule = {
namespaced: true,
state,
mutations,
actions,
getters
}
export default searchModule;
我在突变上设置的 console.log 每个控制台给出以下结果:
setup(){
...
let resultsValue: ResultFilterDto[] = [];
const results = computed(() => { return store.state['searchModule'].results });
function valueChangedGetResults(e: any) {
var textWrited = e.value;
if (textWrited !== null && textWrited !== undefined && textWrited.length >= minQueryLength) {
store.dispatch('searchModule/getResults', textWrited);
}
}
watch(
results,
() => {
resultsValue = results.value;
console.log(resultsValue);
}
);
...
我从我的组件创建了一个计算 属性 来访问我的商店的状态信息,然后我创建了一个手表来观察发生的变化。我还有 valueChangedGetResult 方法,每次我键入一个超过 3 个字符的单词时,都会执行分派以查询后面的内容。后面的查询正确完成,信息在 resultsValue 中更新,因为它从控制台获取所有信息。
我的html中的代码如下
我所解释的自动完成方式不起作用并且不显示任何结果,但是,如果我像下面这样模拟对象并放入 HTML 的数据源变量测试,有效。我究竟做错了什么?非常感谢!
var test: any = [{
key: 'Inbox',
items: [{
id: 17,
name: "test1.txt",
extension: null,
summary: "Name: test1.txt\tInboxName: Inbox 1\t",
highLigths: "Name: <span style='font-weight:bold'>test</span>1.txt \r\n",
creationDate: "0001-01-01T00:00:00Z",
inboxName: "Inbox 1",
inboxId: 1,
folderId: 0,
folderName: null,
categoryId: 0,
categoryName: null,
typeId: 0,
typeName: null,
subTypeId: 0,
subTypeName: null
},
{
id: 17,
name: "test1.txt",
extension: null,
summary: "Name: test1.txt\tInboxName: Inbox 1\t",
highLigths: "Name: <span style='font-weight:bold'>test</span>1.txt \r\n",
creationDate: "0001-01-01T00:00:00Z",
inboxName: "Inbox 1",
inboxId: 1,
folderId: 0,
folderName: null,
categoryId: 0,
categoryName: null,
typeId: 0,
typeName: null,
subTypeId: 0,
subTypeName: null
}
]
}, {
key: 'Archive',
items: [{
id: 17,
name: "test1.txt",
extension: null,
summary: "Name: test1.txt\tInboxName: Inbox 1\t",
highLigths: "Name: <span style='font-weight:bold'>test</span>1.txt \r\n",
creationDate: "0001-01-01T00:00:00Z",
inboxName: "Inbox 1",
inboxId: 1,
folderId: 0,
folderName: null,
categoryId: 0,
categoryName: null,
typeId: 0,
typeName: null,
subTypeId: 0,
subTypeName: null
}]
}];
主要问题是您在模板中使用了 resultsValue
变量,但它不是反应式的...它只是普通数组。更改它不会重新呈现模板...
您可以通过 let resultsValue = ref<ResultFilterDto[]>([]);
修复它(不要忘记从 vue
导入 ref
)并将分配更改为 resultsValue.value = results.value
但是 你根本不需要 resultsValue
变量。您已经有一个被动 computed
值 results
。因此,只需从您的代码中删除 resultsValue
并在模板中使用 results
即可....
setup(){
const results = computed(() => { return store.state['searchModule'].results });
function valueChangedGetResults(e: any) {
var textWrited = e.value;
if (textWrited !== null && textWrited !== undefined && textWrited.length >= minQueryLength) {
store.dispatch('searchModule/getResults', textWrited);
}
}
return {
results
}
}