Javascript Vue.JS-如何让按钮在同一父元素上执行两个单独的操作?

Javascript Vue.JS-如何让按钮在同一父元素上执行两个单独的操作?,javascript,vue.js,vue-component,Javascript,Vue.js,Vue Component,关于父母,我有: <template> <b-container> <b-modal id="uw-qb-add-item-modal" ref="uw-qb-add-item-modal" title="Enter Item Number" @ok="handleNewItem"> <form @submit.stop.prevent="handleS

关于父母,我有:

<template>
  <b-container>
    <b-modal id="uw-qb-add-item-modal"
             ref="uw-qb-add-item-modal"
             title="Enter Item Number"
             @ok="handleNewItem">
      <form @submit.stop.prevent="handleSubmit">
        <b-form-input type="text"
                      placeholder="Enter the item number" />
      </form>
    </b-modal>

    <div class="row mb-3">
      <div class="col">
        <nuxt-link to="/">
          <i class="fa fa-chevron-left" aria-hidden="true"></i>
          Quote Build List
        </nuxt-link>
      </div>
    </div>
    <div class="row mb-3">
      <div class="col-md"><h2>Quote Build <b-badge :variant="buildBadgeVariant">{{ buildBadgeText }}</b-badge></h2></div>
      <div class="col-md text-right text-success"><h3><i class="fa fa-usd" aria-hidden="true"></i> {{ buildTotal | formatDollars }}</h3></div>
    </div>

    <div class="row mb-3">
      <div class="col-md form-group">
        <build-customer :buildNumber="buildNumber"/>
      </div>
      <div class="col-md form-group">
        <build-address :buildNumber="buildNumber" />
      </div>
      <div class="col-md form-group">
        <build-contact :buildNumber="buildNumber" />
      </div>
      <div class="col-md form-group">
        <label for="uw-qb-due-date">Due Date</label>
        <date-picker v-model="dueDate"/>
      </div>
    </div>

    <div class="row mb-3">
      <div class="col-sm form-group">
        <div class="form-check">
          <label class="form-check-label">
            <input class="form-check-input" type="checkbox" v-model="internal" />
            Internal Quote
          </label>
        </div>
        <build-requester-id v-if="internal" :buildNumber="buildNumber"/>
      </div>
      <div class="col-sm form-group">
        <label>RFQ Number</label>
        <b-form-input type="text" v-model="rfqNumber"/>
      </div>
      <div class="col-sm form-group">
        <div class="form-check">
          <label class="form-check-label mb-3">
            <input class="form-check-input" type="checkbox" v-model="update" />
            Quote Update
          </label>
          <label class="form-check-label">
            <input class="form-check-input" type="checkbox" v-model="correctiveAction" />
            Corrective Action
          </label>
        </div>
      </div>
      <div class="col-sm form-group">
        <label>Request Date</label>
        <date-picker v-model="requestDate" />
      </div>
    </div>

    <div class="row mb-3">
      <div class="col-md text-right">
        <b-btn variant="primary" 
               v-b-toggle="editId"
               @click="newEditItem">
          <i class="mr-1 fa fa-plus" aria-hidden="true"></i>
          Add Item
        </b-btn>
      </div>
    </div>

    <b-collapse :id="editId">
      <build-item-edit @doOnEmit="expand" :buildNumber="buildNumber"
                       :itemNumber="editItemNumber"/>                   
    </b-collapse>

    <build-item-list @edit="edit" :buildNumber="buildNumber" />

    <build-breakdown-edit :buildNumber="buildNumber" :breakdownNumber="editBreakdownNumber"/>
    <build-breakdown-list :buildNumber="buildNumber"/>

  </b-container>
</template>

<script>
  import BuildCustomer from '@/components/buildCustomer'
  import BuildAddress from '@/components/buildAddress'
  import BuildContact from '@/components/buildContact'
  import BuildRequesterId from '@/components/buildRequesterId'

  import BuildItemEdit from '@/components/buildItemEdit'
  import BuildItemList from '@/components/buildItemList'

  import BuildBreakdownEdit from '@/components/buildBreakdownEdit'
  import BuildBreakdownList from '@/components/buildBreakdownList'

  import DatePicker from '@/components/datePicker'


  export default {
    data () {
      return {
        editItemNumber: null,
        editBreakdownNumber: null
      }
    },
    components: {
      'build-customer': BuildCustomer,
      'build-address': BuildAddress,
      'build-contact': BuildContact,
      'build-requester-id': BuildRequesterId,
      'build-item-edit': BuildItemEdit,
      'build-item-list': BuildItemList,
      'build-breakdown-edit': BuildBreakdownEdit,
      'build-breakdown-list': BuildBreakdownList,
      'date-picker': DatePicker
    },
    computed: {
      // nextItemNumber () {
      //   const itemNumbers = this.$store.getters['build/item/numbers'](this.buildNumber)
      //   return Math.min.apply(null, itemNumbers) - 1
      //  },
      editId () {
        return this.idGen('edit-item-collapse')
      },
      dueDate: {
        get () {
          return this.build.dueDate
        },
        set (value) {
          this.$store.commit('build/setDueDate', { buildNumber: this.buildNumber, dueDate: value })
        }
      },
      requestDate: {
        get () {
          return this.build.requestDate
        },
        set (value) {
          this.$store.commit('build/setRequestDate', { buildNumber: this.buildNumber, requestDate: value })
        }
      },
      internal: {
        get () {
          return this.build.internal
        },
        set (value) {
          this.$store.commit('build/setInternal', { buildNumber: this.buildNumber, internal: !!value })
        }
      },
      update: {
        get () {
          return this.build.update
        },
        set (value) {
          this.$store.commit('build/setUpdate', { buildNumber: this.buildNumber, update: !!value })
        }
      },
      correctiveAction: {
        get () {
          return this.build.correctiveAction
        },
        set (value) {
          this.$store.commit('build/setCorrectiveAction', { buildNumber: this.buildNumber, correctiveAction: !!value })
        }
      },
      requesterId: {
        get () {
          return this.build.requesterId
        },
        set (value) {
          if (value === null || this.$store.getters.employees.hasOwnProperty(value)) {
            this.$store.commit('build/setRequesterId', { buildNumber: this.buildNumber, requesterId: value })
          }
        }
      },
      rfqNumber: {
        get () {
          return this.build.rfqNumber
        },
        set (value) {
          this.$store.commit('build/setRfqNumber', {buildNumber: this.buildNumber, rfqNumber: value })
        }
      },
      employees () {
        const res = [{ value: null, text: 'Select requested by ...' }];
        for (var empId in this.$store.getters['employee/employees']) {
          res.push({ value: empId, text: this.$store.getters.employees[empId] });
        }
        return res;
      },
      buildNumber () {
        return parseInt(this.$route.params.buildNumber, 10);
      },
      build () {
        return this.$store.getters['build/build'](this.buildNumber);
      },
      buildBadgeVariant () {
        if (this.isNewBuild) { return 'primary'; }
        return 'info';
      },
      buildBadgeText () {
        if (this.isNewBuild) { return 'New'; }
        return this.buildNumber;
      },
      isNewBuild () {
        return this.buildNumber < 0;
      },
      buildTotal () {
        return this.$store.getters['build/total'](this.buildNumber);
      }
    },
    methods: {
      fetchData () {
        if (!this.isNewBuild) {
          // TODO - waiting on schema changes
          console.log('Fetching build data for ' + this.$route.params.buildNumber);
        }
      },
      handleNewItem () {
        this.$store.commit('setError', 'Adding items not supported');
      },
      newEditItem () {
        this.editItemNumber = this.nextItemNumber
      },
      edit(eventPayload) {
        this.editItemNumber = eventPayload
    },
      expand() {
      console.log("TEST")
       this.idGen('edit-item-collapse')
    }
    },
    fetch (context) {
      const buildNumber = parseInt(context.params.buildNumber, 10)
      const build = context.store.getters['build/build'](buildNumber)

      if (build === null && buildNumber >= 0) {
        console.log('load build')
      } else if (build === null && buildNumber < 0) {
        // if the build doesn't exist and it is a temp build
        // number, then just redirect to new
        context.app.router.replace('/new')
      }
    }
  }
</script>
buildItemList

<template>
  <b-container>
    <b-row>
      <b-col>
        <h3>Item</h3>
        <p></p>
        <b-row></b-row>
        <p></p>
      </b-col>
    </b-row>
    <b-row>
      <b-col>
        <b-row>
          <b-col>
            <label>Item No.</label>
            <b-form-input v-model='itemNum' type="text" :state="itemNoState" onkeypress='return event.charCode >= 48 && event.charCode <= 57'
            />
          </b-col>
          <b-col>
            <label>Item Type</label>
            <b-form-select v-model="type" :options="itemTypes" class="mb-3" :state="itemTypeState" />
          </b-col>
          <b-col>
            <label>Part No.</label>
            <b-form-input v-model='partNumber' type="text" :state="partNoState" onkeypress='return event.charCode >= 48 && event.charCode <= 57'
            />
          </b-col>
          <b-col>
            <label>Piece Amount</label>
            <b-form-input v-model='pieceCount' type="number" :state="pieceAmountState" onkeypress='return event.charCode >= 48 && event.charCode <= 57'
            />
          </b-col>
        </b-row>
        <b-row>
          <b-col>
            <label>Comments</label>
            <b-form-textarea id="comments" v-model="comments" placeholder="Enter comments here" :rows="3" :max-rows="6"></b-form-textarea>
          </b-col>
        </b-row>
        <p></p>
        <b-row>
          <b-col>
            <b-card-group deck class="mb-3">
              <b-card bg-variant="primary" text-variant="white" class="text-center">
                <p class="card-text">Breakdown 1</p>
              </b-card>
              <b-card bg-variant="secondary" text-variant="white" class="text-center">
                <p class="card-text">Breakdown 2</p>
              </b-card>
              <b-card bg-variant="success" text-variant="white" class="text-center">
                <p class="card-text">Breakdown 3</p>
              </b-card>
            </b-card-group>
          </b-col>
        </b-row>
      </b-col>
    </b-row>
    <b-row>
      <p></p>
    </b-row>
    <b-row>
      <p></p>
    </b-row>
    <b-row>
      <b-col>
        <div v-if="editmsg" class="col-md text-left">
          <b-btn size="" @click="editUpdate" variant='success'>
            <i class='mr-1 fa fa-plus' aria-hidden="true"></i> Save Edit</b-btn>
        </div>
        <p></p>
      </b-col>
      <b-col>
        <div class="col-md text-center">
          <b-btn size="" @click="addItem" variant='primary'>
            <i class='mr-1 fa fa-plus' aria-hidden="true"></i> Break Downs</b-btn>
        </div>
      </b-col>
      <b-col>
        <div class="col-md text-right">
          <b-btn size="" @click="addItem" variant='primary' v-bind:disabled="!canSave">
            <i class='mr-1 fa fa-plus' aria-hidden="true"></i> Save Item</b-btn>
        </div>
      </b-col>
    </b-row>
    <div v-if="existmsg">
      <p></p>
      <b-alert show variant="danger">{{ existmsg }}</b-alert>
    </div>
    <div v-if="editmsg">
      <p></p>
      <b-alert show variant="warning">{{ editmsg }}</b-alert>
    </div>
  </b-container>
</template>

<script>
import Util from '@/lib/util'
export default {
  props: ['buildNumber', 'itemNumber'],
  data() {
    return {
      itemNum: "",
      type: "",
      partNumber: "",
      pieceCount: "",
      comments: "",
      selected: "A",
    }
  },
  watch: {
    itemNumber: function (editItemNumber) {
      if (editItemNumber == null) {
        this.update({})
      } else {
        const item = this.item(editItemNumber)
        this.update(item)
        this.itemNum = editItemNumber
      }
    }
  },
  computed: {
    itemNoState() {
      return !isNaN(parseFloat(this.itemNum)) && isFinite(this.itemNum) ? null : false;
    },
    itemTypeState() {
      return (this.type) ? null : false;
    },
    partNoState() {
      return !isNaN(parseFloat(this.partNumber)) && isFinite(this.partNumber) ? null : false;
    },
    pieceAmountState() {
      return !isNaN(parseFloat(this.pieceCount)) && isFinite(this.pieceCount) ? null : false;
    },
    canSave() {
      return this.itemNumber != '' && this.type != '' && this.partNumber != '' && this.pieceCount != ''
    },
    editmsg: {
      get() {
        return this.$store.getters["build/item/editmsg"];
      },
      set(value) {
        this.$store.commit("build/item/seteditmsg", value);
      }
    },
    existmsg: {
      get() {
        return this.$store.getters["build/item/existmsg"];
      },
      set(value) {
        this.$store.commit("build/item/setexistmsg", value);
      }
    },
    itemTypes() {
      const iTypes = []
      const b = this.$store.getters['itemType/all']
      for (var itemValue in b) {
        iTypes.push({
          value: itemValue,
          text: b[itemValue]
        })
      }
      return iTypes
    }
  },
  methods: {
    item(itemNumber) {
      return this.$store.getters["build/item/item"](
        this.buildNumber,
        itemNumber
      );
    },
    addItem() {
      if (this.item(this.itemNum) == null)
      {
        this.$store.commit('build/item/add', {
        buildNumber: this.buildNumber,
        itemNumber: this.itemNum,
        item: {
          type: this.type,
          partNumber: this.partNumber,
          pieceCount: this.pieceCount,
          comments: this.comments
        }
      })
      this.update({})
      }
      else
      {
        this.existmsg = "Item number " + this.itemNum + " already exists on this quote"
      }
    },
    update(item) {
      this.itemNum = Util.field(item, 'itemNumber', '')
      this.type = Util.field(item, 'type', '')
      this.partNumber = Util.field(item, 'partNumber', '')
      this.pieceCount = Util.field(item, 'pieceCount', '')
      this.comments = Util.field(item, 'comments', '')

      this.existmsg = ""
    },
    editUpdate(item) {
      this.$store.commit('build/item/update', {
        buildNumber: this.buildNumber,
        itemNumber: this.itemNum,
        item: {
          type: this.type,
          partNumber: this.partNumber,
          pieceCount: this.pieceCount,
          comments: this.comments
        }
      })
      this.update({})

      this.editmsg = ""
    }
  }
}
</script>
<template>
  <b-container>
    <div>
      <p></p>
      <h5>Items</h5>
      <p></p>
      <b-table show-empty bordered striped hover :items="itemTableList" :fields="fields">
        <template slot="actions" scope="row">
          <b-btn variant='success' size="sm" v-on:click="edit(row.item,$event.target)">Edit</b-btn>
          <b-btn variant='danger' size="sm" @click.stop="delRow(row.item,row.index,$event.target)">Delete</b-btn>
        </template>
      </b-table>
    </div>
      </b-container>
</template>

<script>
import Util from "@/lib/util";

export default {
  data() {
    return {
      fields: [
        { key: "itemNumber", label: "Item No.", sortable: true },
        { key: "type", label: "Item Type", sortable: false },
        { key: "partNumber", label: "Part No.", sortable: false },
        { key: "pieceCount", label: "Piece Amount", sortable: false },
        { key: "comments", label: "Comments", sortable: false },
        { actions: { label: "Actions" } }
      ]
    };
  },
  props: ["buildNumber"],
  computed: {
    itemNumbers() {
      console.log("DEVELOPER")
      console.log(this.buildNumber)
      const items = this.$store.getters["build/item/items"](this.buildNumber);

      return Util.numSortedKeys(items);
    },
    itemTableList() {
      const itemList = [];
      for (var i of this.itemNumbers) {
        const item = this.item(i);

        itemList.push({
          itemNumber: i,
          type: item.type,
          partNumber: item.partNumber,
          pieceCount: item.pieceCount,
          comments: item.comments
        });
      }
      return itemList;
    },
  editmsg: {
      get() {
        return this.$store.getters["build/item/editmsg"];
      },
      set(value) {
        this.$store.commit("build/item/seteditmsg", value);
      }
    }
  },
  methods: {
    item(itemNumber) {
      return this.$store.getters["build/item/item"](
        this.buildNumber,
        itemNumber
      );
    },
    edit(item) {
         const payload = {
        item
    };
      this.$emit('doOnEmit')
      this.$emit('edit', item.itemNumber);
      // this.editmsg = "Edit your item above and then click 'Save Edit'"
    }   
  }
};
</script>

项目

编辑 删除 从“@/lib/Util”导入Util; 导出默认值{ 数据(){ 返回{ 字段:[ {键:“项目编号”,标签:“项目编号”,可排序:true}, {key:“type”,label:“Item type”,sortable:false}, {键:“零件号”,标签:“零件号”,可排序:false}, {键:“计件计数”,标签:“计件金额”,可排序:false}, {key:“comments”,label:“comments”,sortable:false}, {操作:{标签:“操作”} ] }; }, 道具:[“buildNumber”], 计算:{ 项目编号(){ console.log(“开发人员”) console.log(this.buildNumber) const items=this.$store.getters[“build/item/items”](this.buildNumber); 返回Util.numSortedKeys(项目); }, itemTableList(){ 常量itemList=[]; for(此.itemNumber的变量i){ const item=本项目(i); itemList.push({ 项目编号:i, 类型:item.type, 零件号:item.partNumber, 计件计数:item.pieceCount, 评论:第1项。评论 }); } 返回项目列表; }, 编辑消息:{ 得到(){ 返回此.store.getters[“build/item/editmsg”]; }, 设置(值){ 这个.store.commit(“build/item/seteditmsg”,value); } } }, 方法:{ 项目(项目编号){ 返回此。$store.getters[“build/item/item”]( 这个号码, 项目编号 ); }, 编辑(项目){ 常数有效载荷={ 项目 }; 这个.$emit('doOnEmit')) 此.$emit('edit',item.itemNumber); //this.editmsg=“编辑上面的项目,然后单击“保存编辑” } } };
因此,重申一下,当单击按钮
edit
时,除了当前正在执行的操作之外,如果没有在父组件上展开,我希望展开该切换折叠

这可能吗?

我假设
是您自己的组件,所以只需添加回调事件即可

<build-item-edit @doOnEmit="someFunctionOnTheParent" :buildNumber="buildNumber" :itemNumber="editItemNumber"/>

然后在父组件上,在父组件上定义方法
someFunctionOnTheParent
,并运行处理UI内容的代码

然后在
builditem edit
组件中,在发出值之前,调用
this.$emit('doOnEmit')

我假设
是您自己的组件,所以只需向其添加回调事件即可

<build-item-edit @doOnEmit="someFunctionOnTheParent" :buildNumber="buildNumber" :itemNumber="editItemNumber"/>

然后在父组件上,在父组件上定义方法
someFunctionOnTheParent
,并运行处理UI内容的代码


然后在
builditem edit
组件中,在发出值之前,调用
this.$emit('doOnEmit')
@doOnEmit
Iimagine@robertotom是的,你说得很对,我已经修改了我的例子以适应。@webnoob嗨,谢谢你的回答。这似乎是我为当前发射所做的一切。我有
buildItemEdit
,其中包含按钮
Edit
。单击该按钮时,会将
itemnumber
发送回父级。然而,我只是希望它也能在父对象上切换折叠,如果它没有折叠的话。这就是上面要做的。在调用
this.emit('edit',item.itemNumber')之前,将进行折叠的代码放入单独的
somefunction中调用此。$emit('doOnEmit')
。这将依次调用另一个版本上的
SomeFunctions中的代码,并导致切换操作。@webnoob这样做的目的是复制生成项编辑,使其现在显示两次。
@doOnEmit
Iimagine@robertotom是的,你说得很对,我已经修改了我的例子以适应。@webnoob嗨,谢谢你的回答。这似乎是我为当前发射所做的一切。我有
buildItemEdit
,其中包含按钮
Edit
。单击该按钮时,会将
itemnumber
发送回父级。然而,我只是希望它也能在父对象上切换折叠,如果它没有折叠的话。这就是上面要做的。在调用
this.emit('edit',item.itemNumber')之前,将进行折叠的代码放入单独的
somefunction中调用此。$emit('doOnEmit')
。这将依次调用另一个版本上的
somefunction中的代码,并导致切换操作。@webnoob这样做的目的是复制生成项编辑,因此它现在显示两次。