如何正确禁用输入类型密码的自动完成

How to correctly disable autocomplete for input type password

您好,我正在实现可以打开几次的 OTP 功能模式,一次是在您导航到应用程序时,第二次是在某些特定操作(例如单击某个操作按钮)时。

如果这很重要,我正在使用 Vue2 和 Buefy,所以问题是一旦我提交代码并再次打开模式,它之前已经添加了填充的代码。我已尝试将自动完成指定为 one-time-codenew-password none 它们的工作。

这是我的实现

输入组件

<b-input
      :name="name"
      :value="value"
      :placeholder="placeholder"
      :disabled="disabled"
      :maxlength="maxLength"
      :type="type"
      :autocomplete="autocomplete"
      :inputmode="inputmode"
      @input="(value) => $emit('input', value)"
    >
 </b-input>

JS部分

export default {
  name: "Input",
  props: {
    name: String,
    label: String,
    placeholder: String,
    value: String,
    autocomplete: String,
    inputmode: {
      type: String,
      default: "text"
    },
    type: {
      type: String,
      default: "text"
    },
    disabled: {
      type: Boolean,
      default: false
    },
    maxLength: Number
  }
};

OTP 模式

<b-modal :active="isOpen" width="200" :can-cancel="canCancel">
    <div>
      <h2>Otp modal</h2>
      <Input
        label="Otp code"
        name="otp"
        v-model="code"
        placeholder="code"
        type="password"
        :maxLength="4"
        autocomplete="one-time-code"
        inputMode="numeric"
      />
      <slot></slot>
      <b-button type="is-primary" @click="close">Submit</b-button>
      <b-button type="is-primary is-light" @click="close">Close</b-button>
    </div>
 </b-modal>

用于可点击演示的 CodeSandbox:https://codesandbox.io/s/buefy-otp-test-onuh1

我认为你对这里发生的事情有点困惑——如果你没有正确设置 autocomplete,浏览器可能会自动填充你的 OTP,但这并不是导致你的数据保持完整的原因.我不明白 为什么 (我不熟悉 Buefy),但即使在关闭模态后,你的 OTP 模态组件的状态也保持不变;浏览器在这里没有做错任何事。

解决此问题的一种方法是使用 watcher.

手动清除 OTP 代码

这不是最干净的解决方案,添加太多观察者会很快使您的代码难以调试,但只使用一个也不会有什么坏处。

将此添加到 OtpModal 组件的末尾 JavaScript:

...
  watch: {
    isOpen() {
      this.code = "";
    }
  }
...

这将告诉 Vue 在 isOpen 的值发生变化时随时清除 code

这是工作代码的片段,您需要 open the snippet fullscreen 才能看到它。

(我删除了输入组件,因为它只是一个包装器,没有别的,如果它只是通过自身传递数据,你也不应该包含它)

Vue.config.productionTip = false;
Vue.config.devtools = false;

const OtpModal = {
  name: "otp-modal",
  template: `
  <b-modal :active="isOpen" width="200" :can-cancel="canCancel">
    <div>
      <h2>Otp modal</h2>
      <b-field>
        <b-input
          label="Otp code"
          name="otp"
          v-model="code"
          placeholder="code"
          type="password"
          :maxLength="4"
          autocomplete="one-time-code"
          inputMode="numeric"
        />
      </b-field>
      <slot></slot>
      <b-button type="is-primary" @click="close">Submit</b-button>
      <b-button type="is-primary is-light" @click="close">Close</b-button>
    </div>
  </b-modal>`,
  props: {
    isOpen: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      code: ""
    };
  },
  computed: {
    canCancel() {
      return ["escape", "x", "outside"];
    }
  },
  methods: {
    close() {
      this.$emit("close");
    }
  },
  watch: {
    isOpen() {
      this.code = "";
    }
  },
};

new Vue({
  name: 'main',
  el: '#app',
  components: {
    OtpModal,
  },
  data() {
    return {
      isModalOpen: false,
    };
  },
  methods: {
    toggleModal() {
      this.isModalOpen = !this.isModalOpen;
    },
    closeModal() {
      this.isModalOpen = false;
    },
  },
});
#app {
  font-family: "Avenir", Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}

div {
  background-color: #ffffff;
  padding: 2rem;
}
<script src="https://unpkg.com/vue@2/dist/vue.js"></script>
<link rel="stylesheet" href="https://unpkg.com/buefy@0.9.7/dist/buefy.min.css">
<script src="https://unpkg.com/buefy/dist/buefy.min.js"></script>

<div id="app">
  <b-button @click="toggleModal">Open modal</b-button>
  <otp-modal :is-open="isModalOpen" @close="closeModal">
    <p>Autocomplete isn't the problem afterall!</p>
  </otp-modal>
</div>

另外,确认一下,one-time-code确实是一个valid autocomplete value,浏览器应该尊重它。 off 也是有效的,浏览器今天也应该尊重这个值(但是,它们并不总是那么好)。