尝试在 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 中禁用导航按钮时出错的主要内容,如果未能解决你的问题,请参考以下文章

在操作栏上按“向上导航按钮”并返回到父活动时出错

在 Vuejs 问题中使用按钮输入文件

从 xib 内的按钮单击调用 IBAction 时出错

iOS:尝试自定义导航栏时出错

具有 vue-class-components 和 typescript 的 vuejs 实例属性时出错

当我尝试在片段中显示或隐藏浮动操作按钮时出错