最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Vue.js how to replace the text of the button clicked - Stack Overflow

programmeradmin4浏览0评论

I my app UI I have a table with a set of permissions listed. In each row there is a toggle-button that sets the default state of each permission to either "deny" or "grant" in the DB.

If the user clicks the button, async action is triggered in the background. It all works perfectly fine, but what I want to add is when user click the button its inner html changes to a spinner or some sort of "wait..." text and the button get disable while the action runs. This is to prevent user from clicking multiple time is the action take a bit longer to plete, giving impression like nothing is happening.

Now, I know how to do it in jQuery or even plain JS, but I have no idea how to access the button properties in VUE.js

My button look like this:

<button @click="defaultPermissionState(perm.id,'grant',$event)">Deny</button>

I'm only recently started into vue.js, so still learning it ;)

UPDATE: I've actually managed to find a way to do it by exploring the $event and being able to change the text and button properties by doing this:

event.path[0].innerHTML = 'wait...';
event.path[0].disabled = true;

but this does not look like a very elegant solution, so if anyone knows of something better I would still like to hear it

I my app UI I have a table with a set of permissions listed. In each row there is a toggle-button that sets the default state of each permission to either "deny" or "grant" in the DB.

If the user clicks the button, async action is triggered in the background. It all works perfectly fine, but what I want to add is when user click the button its inner html changes to a spinner or some sort of "wait..." text and the button get disable while the action runs. This is to prevent user from clicking multiple time is the action take a bit longer to plete, giving impression like nothing is happening.

Now, I know how to do it in jQuery or even plain JS, but I have no idea how to access the button properties in VUE.js

My button look like this:

<button @click="defaultPermissionState(perm.id,'grant',$event)">Deny</button>

I'm only recently started into vue.js, so still learning it ;)

UPDATE: I've actually managed to find a way to do it by exploring the $event and being able to change the text and button properties by doing this:

event.path[0].innerHTML = 'wait...';
event.path[0].disabled = true;

but this does not look like a very elegant solution, so if anyone knows of something better I would still like to hear it

Share Improve this question edited Apr 9, 2019 at 8:41 ps-hyp-pt asked Apr 9, 2019 at 8:26 ps-hyp-ptps-hyp-pt 151 gold badge2 silver badges5 bronze badges 2
  • bind the disabled attribute :disabled="isLoading" – Socrates Tuas Commented Apr 9, 2019 at 8:39
  • @Socrates Tuas - except that the table can have many row, 50+ even, depending what's in the database, so if I set isLoading to true then all my buttons will change state – ps-hyp-pt Commented Apr 9, 2019 at 8:50
Add a ment  | 

5 Answers 5

Reset to default 2

You can use v-if with :disabled. Check this quick example:

new Vue({
  el: "#app",
  data: {
    isLoadingArray: []
  },
  methods: {
    clicked(index) {
      this.$set(this.isLoadingArray, index, true)

      setTimeout(() => {
        this.$set(this.isLoadingArray, index, false)
      }, 2000)
    }
  }
})
.lds-dual-ring {
  display: inline-block;
  width: 64px;
  height: 64px;
}

.lds-dual-ring:after {
  content: " ";
  display: block;
  width: 46px;
  height: 46px;
  margin: 1px;
  border-radius: 50%;
  border: 5px solid #fff;
  border-color: #fff transparent #fff transparent;
  animation: lds-dual-ring 1.2s linear infinite;
}

@keyframes lds-dual-ring {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}
<script src="https://cdnjs.cloudflare./ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
  <button type="button" @click="clicked(0)" :disabled="isLoadingArray[0]">
    <div v-if="isLoadingArray[0]" class="lds-dual-ring"></div>
    <span v-else>click me</span>
  </button>

  <button type="button" @click="clicked(1)" :disabled="isLoadingArray[1]">
    <div v-if="isLoadingArray[1]" class="lds-dual-ring"></div>
    <span v-else>click me</span>
  </button>

  <button type="button" @click="clicked(2)" :disabled="isLoadingArray[2]">
    <div v-if="isLoadingArray[2]" class="lds-dual-ring"></div>
    <span v-else>click me</span>
  </button>

</div>

You can do it like this

data: function() {
   return {
     waiting: false,
     ...otherstuffs
   }
},
methods: {
   callAsync() {
      this.waiting = true;
      callASYNC()
      .then((result) => {
         this.waiting = false;
      })
   }
}

In your HTML

 <button :disabled="waiting"> {{ waiting ? 'Waiting ...' : 'Deny' }} </button>

So basically, just set a flag before you hit the request, and set it back when the call finishes. Use this flag to set the button value to whatever you want

This should help

<template>
   <button disabled={{disableBtn}} 
     @click="defaultPermissionState(perm.id,'grant',$event)">{{btnText}} 
   </button>
</template>

export default {
   data() {
      return {
         btnText: 'Deny',
         disableBtn: false
      }
   },
   method: {
      defaultPermissionState(id, type, e) {
         this.disableBtn = true;
         this.btnText = 'Clicking.....';
      }
   }
}

Hide the button and show the spinner using a data or puted property. Update the 'busy' property from your async function.

<button v-if='!busy' @click="defaultPermissionState(perm.id,'grant',$event)">Deny</button>
<spinner v-else />

you can use $event to change the inner html for buttons

$event.path[0].innerHTML = "Write the inner html"
发布评论

评论列表(0)

  1. 暂无评论