尝试在 VueJs 中禁用导航按钮时出错
Posted
技术标签:
【中文标题】尝试在 VueJs 中禁用导航按钮时出错【英文标题】:Error when attempting to disable Navigation Buttons in VueJs 【发布时间】:2021-12-06 09:16:06 【问题描述】:在我的工单处理应用程序中,目前我的 TicketRunner.vue 组件中包含一个后退和前进按钮,我想更改它,以便这些按钮仅在我有相关的案例文件时出现,我已经使用过V-如果:
TicketRunner.Vue
<div class="level nav-btns" v-if='!currentTicketCaseFiles.length'>
<div class="buttons has-addons level-left">
<b-button
@click.prevent="navGoPrev()"
:disabled="currentStepIndex === 0 || navWaiting"
size="is-medium"
>
</div>
export default
name: 'TicketRunner',
mixins: [NavStepsByIndexMixin()],
components:
StagePresenter,
CaseFilesStage,
ParticipantsStage,
AttachmentsStage,
CaseFilesRunner,
TicketContextButtons,
,
data: function()
return
firstComponentsInitialization: true,
loadingConfirm: false,
confirmationModalActive: false,
confirmationSucceeded: undefined
,
props:
ticketId:
type: Number,
required: true,
,
,
provide()
return
contextButtons:
capture: (name, callback, title) => this.$refs['contextButtons'].captureButton(name, callback, title),
release: (name) => this.$refs['contextButtons'].releaseButton(name),
enable: (name) => this.$refs['contextButtons'].enableButton(name),
disable: (name) => this.$refs['contextButtons'].disableButton(name),
,
;
,
computed:
...mapGetters(['currentTicket', 'ticketCaseFiles', 'allCurrentTicketAttachments', 'currentTicketCaseFileNotAssociated',
'currentRequesterType', 'currentTicketStage', 'lastCaseFile']),
caseFiles()
return this.ticketCaseFiles(this.ticketId);
,
ticketHasAttachments()
return this.allCurrentTicketAttachments.length > 0;
,
isTicketAssociatedWithCaseFile()
return !this.currentTicketCaseFileNotAssociated;
,
isFirstNavInitializationInProgress()
return !this.navReady && this.firstComponentsInitialization;
,
isShowAttachmentsStep()
return this.ticketHasAttachments && this.currentRequesterType !== 'unknown' &&
(this.isFirstNavInitializationInProgress || this.isTicketAssociatedWithCaseFile)
,
isCurrentTicketResolved()
return this.currentTicket.status === 'resolved';
,
islastStep()
return this.navLastStep() && this.lastCaseFile;
,
watch:
ticketId()
this.navigator.reset();
,
navReady()
this.moveForwardIfReady();
this.firstComponentsInitialization = false;
,
methods:
...mapActions(['confirmTicket']),
moveForwardIfReady()
if (this.navigator.currentIndex === 0 && this.firstComponentsInitialization)
let steps = 0
const step_names = ['case_files_stage']
for(const [_idx, name] of step_names.entries())
const ref_name = `step[$name]`;
if (this.$refs.hasOwnProperty(ref_name) && this.$refs[ref_name].navReady)
steps += 1
else
break
this.navigator.currentIndex += steps
,
confirm()
this.$buefy.dialog.confirm(
message: this.t('tickets.stages.confirmation.simplified_confirm_reply'),
onConfirm: () => this.confirmStep()
)
,
async confirmStep()
this.loadingConfirm = true;
const promise = this.confirmTicket(this.ticketId);
return promise.then((response) =>
this.confirmationModalActive = true;
this.confirmationSucceeded = true;
return true; // true is correct here. for goNext it makes parent to stay on on the current step
).catch(() =>
this.confirmationModalActive = true;
this.confirmationSucceeded = false;
return true; // true is correct here. for goNext it makes parent to stay on on the current step
).finally(() => this.loadingConfirm = false);
,
,
;
然后我收到以下控制台错误:
[Vue warn]: Property or method "currentTicketCaseFiles" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property.
我知道“!currentTicketCaseFiles.length”在组件CaseFilesStage.vue 中成功运行,这让我相信我应该以某种方式将两者联系起来?但是导入它对我来说似乎也不合适。我不太确定如何解决这个问题,因为我是 VueJS 的新手,并且会很高兴任何指针。我将在下面附上 CaseFilesStage.vue 组件。
CaseFilesStage.vue
<template>
<div class="hero">
<div class="block">
<template v-if="!currentTicket.spamTicket">
<b-field>
<b-input
v-model="filter"
:loading="loading"
:placeholder="t('tickets.stages.case_files.search.tooltip')"
v-on:keyup.enter.native="searchCaseFiles"
type="search"
icon="search"
:class=" 'preview-enabled': showAttachmentsPreview"
/>
</b-field>
<template v-if="foundCaseFiles.length">
<h4 class="title is-4 table-title"> t('tickets.stages.case_files.search.table_title') </h4>
<CaseFilesSearchTable
:case-files="foundCaseFilxes"
:found-by-data-points="foundCaseFilesByParticipant"
:show-header="true"
v-slot="cf">
<b-checkbox v-if="cfBelongsToCurrentTicket(cf.id)" :disabled="true" :value="true"></b-checkbox>
<b-checkbox v-else @input="onFoundCaseFile(cf.id, $event)"></b-checkbox>
</CaseFilesSearchTable>
</template>
<div v-else-if="lookupStatus === 'notFound'">
t('tickets.stages.case_files.search.not_found')
<!-- display button here if above is activated -->
</div>
</template>
</div>
<template v-if='currentTicketCaseFiles.length'>
<h4 class="title is-4 table-title"> t('tickets.stages.case_files.table_title') </h4>
<CaseFilesTable :case-files="currentTicketCaseFiles" :show-header="true" v-slot="cf">
<DeleteButton
:model-id="cf.id"
modelName="CaseFile" >
</DeleteButton>
</CaseFilesTable>
</template>
</div>
</template>
<script>
import CaseFilesTable from '../tables/CaseFilesTable';
import CaseFilesSearchTable from '../tables/CaseFilesSearchTable';
import DeleteButton from '../../../../shared/components/controls/DeleteButton';
import mapGetters, mapActions from 'vuex';
import mapServerActions from "../../../../../../_frontend_infrastructure/javascript/lib/crudvuex_new";
export default
name: 'CaseFilesStage',
data()
return
lookupStatus: 'waitingInput',
filter: '',
waiting: ,
foundCaseFiles: [],
foundCaseFilesByParticipant:
;
,
components:
CaseFilesTable,
CaseFilesSearchTable,
DeleteButton
,
computed:
...mapGetters(
['currentTicketCaseFiles', 'currentTicketCaseFileNotAssociated', 'currentTicket', 'showAttachmentsPreview']
),
loading()
return this.lookupStatus === 'waitingServer';
,
allCaseFilesMix()
this.currentTicketCaseFiles + this.foundCaseFiles
,
foundCaseFilesEx()
return this.foundCaseFiles.filter((x) => !this.cfBelongsToCurrentTicket(x.id))
,
checkboxValue()
if(!this.currentTicketCaseFileNotAssociated)
return null;
return true;
,
navReady()
return this.currentTicket.spamTicket || this.currentTicketCaseFiles.length > 0 || this.checkboxValue;
,
markSpam:
get: function()
return this.currentTicket.spamTicket
,
set: function(val)
return this.updateTicket([this.currentTicket.id, spam_ticket: val ]);
,
,
methods:
...mapActions(['updateTicket']),
...mapServerActions(['createCaseFile', 'deleteCaseFile']),
cfBelongsToCurrentTicket(id)
return this.currentTicketCaseFiles.map((x) => x.caseFileId).includes(id);
,
cantAssignCaseFileCheckbox(isChecked)
if(isChecked)
this.createCaseFile( isCfNotAssociated: true );
else
this.deleteCaseFile(this.currentTicketCaseFileNotAssociated);
,
onFoundCaseFile(id, useIt)
console.log("onFoundCaseFile: ", id, useIt);
if(useIt)
this.createCaseFile( caseFileId: id );
else
this.deleteCaseFile(this.currentTicketCaseFiles.find( caseFileId: id ));
,
searchCaseFiles()
const newData = this.filter;
if (newData.length < 3) // TODO: some smarter condition here
this.foundCaseFiles = [];
this.lookupStatus = 'waitingInput';
return;
this.lookupStatus = 'waitingServer';
this.$axios.get('case_files', params: "case_files.filter" : newData )
.then((response) =>
this.foundCaseFiles = response.data.caseFilesSearchResult.caseFiles;
this.foundCaseFilesByParticipant = response.data.caseFilesSearchResult.foundByPrivateInfo;
if(this.foundCaseFiles.length > 0)
this.lookupStatus = 'success';
else
this.lookupStatus = 'notFound';
).catch(() => this.lookupStatus = 'error');
,
;
</script>
</style>
【问题讨论】:
TicketRunner.vue 组件的脚本中有什么内容。看起来你在组件的 props、data 或计算的 props 中没有currentTicketCaseFiles
这里使用双引号v-if='!currentTicketCaseFiles.length'
@transGLUKator 已更新!
@Mr.感谢您的建议,但是出现了同样的错误。
您应该将currentTicketCaseFiles
注入到组件中(它是一个吸气剂)。修改TicketRunner.Vue
中的computed: ...mapGetters(['currentTicketCaseFiles', ......
应该可以解决你的问题
【参考方案1】:
将此添加到您的 TicketRunner.vue
组件脚本中:
computed:
...mapGetters(['currentTicketCaseFiles'])
【讨论】:
以上是关于尝试在 VueJs 中禁用导航按钮时出错的主要内容,如果未能解决你的问题,请参考以下文章