#typescript #vue.js #vuex
#typescript #vue.js #vuex
Вопрос:
Когда я использую Vuex в JavaScript, он работает хорошо, но после того, как я хочу изменить его на TypeScript, он сообщает мне, что Property 'commit' does not exist
в мутациях Vuex:
const mutations = {
methodA (): none {
this.commit('methodB') // raise error here!!! <- Property 'commit' does not exist on type '...'
},
methodB (): nont {
log.console('hello')
}
}
Что я должен сделать, чтобы это работало.
Редактировать:
все еще жду … www
Редактировать:
Вот часть всего файла, возможно, он слишком длинный (200 строк) для вас:
import fs from 'fs'
import * as monaco from 'monaco-editor/esm/vs/editor/editor.api'
import { remote } from 'electron'
// editor_text_C: const state for editor's text
const editor_text_C = {
main: 'Text TODO, enter <kbd>Ctrl Enter</kbd> to submit:',
sub: title => `Text TODO, enter <kbd>Ctrl Enter</kbd> for submit for `
`${JSON.stringify(title)}, and enter <kbd>Esc</kbd> to `
`leave:`
}
interface Bar {
title: string;
time: Date;
OK: boolean;
folding: boolean;
child: Bar[];
}
interface Editor {
text: string;
index: number[];
container?: HTMLElement;
// TODO: ugly type
obj: any;
}
interface State {
bars: Bar[];
editor: Editor;
filePath: string;
}
const state = (): State => ({
bars: [],
editor: {
text: editor_text_C.main,
index: [],
container: undefined,
obj: null
},
filePath: ''
})
// make the bar/bars be normal, be in bars' shape
var normalBar = (bar: any): Bar => {
if (!bar['title']) console.error('Bar require title')
bar['time'] = bar['time'] ? new Date(bar['time']) : new Date()
bar['OK'] = bar['OK'] ? bar['OK'] : false
bar['folding'] = bar['folding'] ? bar['folding'] : false
bar['child'] = normalBars(bar['child'])
return bar
}
var normalBars = (bars: any[]): Bar[] => {
var result = []
if (bars) {
for (var i = 0; i < bars.length; i ) {
if(bars[i])
result.push(normalBar(bars[i]))
}
}
return result
}
// get the bar by index
var barByIndex = (bars: Bar[], index: number[]): Bar => {
var result: any = { child: bars }
for (var i = 0; i < index.length; i ) {
result = result.child[index[i]]
}
return result as Bar
}
// mutations
const mutations = {
init (state: State, { filePath }: { filePath: string; }) {
// init Bars for todo application.
// read `json` file form filePath, then init state.bars with update mutations.
// ------------------------------------------------------------------------
state.filePath = filePath
fs.readFile(state.filePath, (err, data) => {
if (err) {
this.update(state, {
bars: normalBars([
{title: '1. Click on my text to set my state (OK/Todo)'},
{title: ['2. Want to set a new Todo? Edit at below editor, then press',
' `Ctrl Enter`'].join('')},
{title: ['3. A Useless Todo bar? move on me and you can find a bin ',
'icon, then click on the my delete bin icon'].join('')}
])
})
return
}
state.bars = normalBars(JSON.parse(data.toString()))
})
// init the Editor
// ------------------------------------------------------------------------
state.editor.container = document.createElement('div')
state.editor.container.style.height = '5em'
state.editor.obj = monaco.editor.create(state.editor.container, {
value: '',
language: 'markdown',
folding: true,
foldingStrategy: 'indentation',
automaticLayout: true,
overviewRulerBorder: false,
scrollBeyondLastLine: false,
minimap: {
enabled: false
}
})
// Set the command for edit to enter the message
state.editor.obj.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.Enter, () => {
this.commit('todolist/submit', { message: state.editor.obj.getValue() })
state.editor.obj.setValue('')
})
// Set the command for enter the message for root
state.editor.obj.addCommand(monaco.KeyCode.Escape, () => {
this.commit('todolist/addBar', { index: undefined })
})
},
// update Bars and save
// set the state.bars' value to `bars`, then write it to filePath
update (state: State, { bars }: { bars: Bar[]; }) {
state.bars = bars
fs.writeFile(state.filePath, JSON.stringify(state.bars), (err) => {
if (err) {
console.error(`Cannot write to ${state.filePath}!`)
}
})
},
// kill bar by index
killBar (state: State, { index }: { index: number[] }) {
// reset the editor's index
this.commit('todolist/addBar', { index: undefined })
var index_ = index.slice()
if (index.length != 1) {
var i = index_.pop()
var aim = barByIndex(state.bars, index_)
remote.clipboard.writeText(aim.child[i].title)
aim.child.splice(i, 1)
this.commit('todolist/update', { bars: state.bars })
} else {
remote.clipboard.writeText(state.bars[index[0]].title)
state.bars.splice(index[0], 1)
this.commit('todolist/update', { bars: state.bars })
}
},
// change the bay's OK state by index
changeState (state: State, { index }: { index: number[] }) {
var aim = barByIndex(state.bars, index)
aim.OK = !aim.OK
this.commit('todolist/update', { bars: state.bars })
},
// add Bar for todo list:
// - if index == undef, add bar to the root
// - else, add bar for bars[index[0]][index[1]]...
addBar (state: State, { index }: { index: number[] }) {
state.editor.index = index
if (state.editor.index != undefined) {
var aim = barByIndex(state.bars, state.editor.index)
state.editor.text = editor_text_C.sub(aim.title)
} else {
state.editor.text = editor_text_C.main
}
// focus on the editor auto
state.editor.obj.focus()
this.commit('todolist/update', { bars: state.bars })
},
// fold Bar for todo list
foldBar (state: State, { index }: { index: number[]; }) {
var aim = barByIndex(state.bars, index)
aim.folding = !aim.folding
this.commit('todolist/update', { bars: state.bars })
},
// submit by message and index, and then update it:
// - if index == undef, add bar to the root
// - else, add bar for bars[index]
submit (state: State, { message }: { message: string; }) {
if (state.editor.index != undefined) {
var aim = barByIndex(state.bars, state.editor.index)
aim.child.unshift(normalBar({title: message}))
this.commit('todolist/update', { bars: state.bars })
} else {
state.bars.unshift(normalBar({title: message}))
this.commit('todolist/update', { bars: state.bars })
}
}
}
const getters = {
state: (state: State) => (index: number[]) => {
var aim = barByIndex(state.bars, index)
if (aim.child.length != 0) {
return aim.folding ? 'folding' : 'unfolding'
} else {
return aim.OK ? 'OK' : 'not OK'
}
},
folding: (state: State) => (index: number[]) => {
return barByIndex(state.bars, index).folding
},
havechildren: (state: State) => (index: number[]) => {
return barByIndex(state.bars, index).child.length != 0
},
OK: (state: State, getters: any) => (index: number[]) => {
var aim = barByIndex(state.bars, index)
if (getters['havechildren'](index)) {
var flag = true
for (var i = 0; i < aim.child.length; i ) {
if (!getters['OK'](index.concat(i))) {
flag = false
}
}
return flag
} else {
return aim.OK
}
}
}
export default {
namespaced: true,
state,
mutations,
getters
}
Вот некоторая информация, которая может помочь или нет: это сборка electron
, и я собираюсь превратить ее в файл typescript, и это файл хранилища Vue в разделе path ./src/store/modules/todolist.vue
.
Комментарии:
1. Вы используете простой vue SPA или что-то с nuxt? Покажите весь ваш файл, пожалуйста
2. @DarioRega привет? Я добавляю весь файл, который предназначен для приложения vue SPA.
3. Ну, извините, но я не знаю electron, и я не большой знаток typescript, не могу помочь, извините
Ответ №1:
Проблема в том, что вы никогда не должны совершать мутацию внутри другой мутации в vuex. Мутация должна вносить только немедленные изменения в состояние, и это разработано таким образом, чтобы лучше хронологически отслеживать атомарные изменения состояния.
Если вы хотите обернуть логику вокруг вызовов мутаций, вам следует вместо этого использовать действие. Действия получают контекстный объект с методом ‘commit’ внутри.
Итак, в вашем простом примере вы могли бы выполнить действие, которое безопасно фиксирует ‘methodA’, а затем ‘methodB’.
const actions = {
actionOne ({commit}): none {
commit('methodA')
commit('methodB')
},
}
Если у вас есть какая-либо дополнительная логика (например. условно фиксируя ту или иную мутацию), вы можете поместить его туда внутри своего действия.