Vuetify 开关与模型同步

Vuetify switch sync with model

我有数据 table,里面有 vuetify v-switch。当用户点击 v-switch 时,它会自动切换。当用户取消 swal(甜蜜警报)时,我想将其恢复到以前的状态。如果开关处于非活动状态,则开关应恢复为活动状态,反之亦然。

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<v-data-table :headers="headers" :items="users" item-key="pk" :loading="loading" hide-default-footer :items-per-page="i_per_page">
  <template v-slot:item.switch="{ item }">
    <v-tooltip bottom v-if="item.is_active=='active'">
       <template v-slot:activator="{ on, attrs }">
          <div v-bind="attrs" v-on="on">
             <v-switch :id="String(item.user_id)" :loading='switchLoader'   true-value="active" false-value="null" v-model="item.is_active" @click="toggle_status(item.user_id, item.is_active, $event)"></v-switch>
          </div>
       </template>
     <small v-if="item.is_active">Suspend</small>
   </v-tooltip>
   <v-tooltip bottom v-if="item.is_active=='null'">
     <template v-slot:activator="{ on, attrs }">
       <div v-bind="attrs" v-on="on">
         <v-switch :loading='switchLoader' true-value="active" false-value="null" v-model="item.is_active" @click="toggle_status(item.user_id, item.is_active, $event)"></v-switch>
       </div>
     </template>
     <small>Activate</small>
   </v-tooltip>

 </template>

</v-data-table>

<script>
  methods: {
    toggle_status(user_id, value, e) {
      console.log(e)
      if (value == 'null') {
        this.action = '0'
        swal.fire({
          title: 'Are you sure you want to deactivate user?',
          showDenyButton: true,
          confirmButtonText: `Deactivate`,
          denyButtonText: `Cancel`
        }).then(result => {
          if (result.isConfirmed) {
            this.toggle_user(user_id, value)
          } else {
            return false
          }
        })
      } else if (value == 'active') {
        this.action = '1'
        swal.fire({
          title: 'Are you sure you want to activate user?',
          showDenyButton: true,
          confirmButtonText: `Activate`,
          denyButtonText: `Cancel`
        }).then(result => {
          if (result.isConfirmed) {
            this.toggle_user(user_id, value)
          } else {
            return false
          }
        })
      }
    }
  }
</script>

您可以尝试以下步骤吗?

  1. 删除 v-switch 绑定 (v-model) 到 item.is_active

  2. toggle_status方法上,通过事件获取当前值,改成这样:

    toggle_status: (event) {
      const value = event.target.value
      console.log('value: ', value)
      if (value === 'active') {
        ... // Insert the same code for the swall calls in here
      }
    }
    

当然,在 <template> 你应该这样做 <v-switch ... @click="toggle_status($event)"></v-switch>

v-model 基本上是 value@input 的缩写标签。 你需要自己处理 v-switch 的输入变化,所以你不应该使用 v-model。 现在 v-model 的绑定对于不同的组件是不同的。例如正如我们从 API 中看到的那样,Vuetify v-switch 组件将 v-model 绑定到 input-valuehttps://vuetifyjs.com/en/api/v-switch/#props-input-value

所以基本上,写 v-model="item.is_active" 在内部与 :input-value="item.is_active" @change="item.is_active = $event.target.value"

相同

因此您可以将代码重写为 :input-value="item.is_active @change="toggle_status(item.user_id, item.is_active, $event)" (注意你不应该在这里使用@click 事件,因为它可能在输入值更新之前被触发)

如果用户取消 swal,您可以重置 v-switch:

const i = this.users.findIndex((user) => user.user_id == user_id);
this.users[i].is_active = e;
swal.fire({
  title: 'Are you sure you want to deactivate user?',
  showDenyButton: true,
  confirmButtonText: `Deactivate`,
  denyButtonText: `Cancel`
}).then(result => {
  if (result.isConfirmed) {
    this.toggle_user(user_id, value)
  } else {
    const i = this.users.findIndex((user) => user.user_id == user_id);
    this.users[i].is_active = e == "active" ? "null" : "active"; // reset is_active if user cancels the swal
  }
})