【问题标题】:vue - copy password input field to clipboardvue - 将密码输入字段复制到剪贴板
【发布时间】:2020-12-05 04:00:40
【问题描述】:

我的 vue 应用程序中有一个表单输入,用于创建密码。我已经成功添加了一个按钮来显示/隐藏密码。我想将副本添加到剪贴板功能,让用户将密码复制并粘贴到安全的地方,但它不起作用。我在这里做错了什么?

模板代码

      <small class="font-wieght-bold text-success mb-0" v-if="isCopied">Copied</small>
      
      <div class="input-group">
        <input :type="showPassword ? 'text' : 'password'" class="form-control" ref="password" required v-model="password">
        <div class="input-group-append">
          <button class="btn btn-secondary" @click.prevent="copyToClipboard()"><i class="fas fa-clipboard"></i></button>
        </div>
      </div>

Vue 代码

    viewPassword() {
      this.showPassword = !this.showPassword;
    },
    copyToClipboard() {
      this.$refs.password.select();
      document.execCommand('copy');
      this.isCopied = true;
      setTimeout( () => { this.isCopied = !this.isCopied },3000);
    }

【问题讨论】:

  • this 能回答您的问题吗? type=password 时可能不起作用。

标签: javascript vue.js


【解决方案1】:

您需要复制 v-model 的内容,而不是输入本身。

您可以使用这样的函数从变量中复制。

它创建一个新文本框,使用复制命令,然后立即将其删除。所有这些都在一个事件循环中,因此它甚至永远不会呈现。

const copyTextToClipboard = (text) => {
  const textArea = document.createElement('textarea')

  //
  // *** This styling is an extra step which is likely not required. ***
  //
  // Why is it here? To ensure:
  // 1. the element is able to have focus and selection.
  // 2. if element was to flash render it has minimal visual impact.
  // 3. less flakyness with selection and copying which **might** occur if
  //    the textarea element is not visible.
  //
  // The likelihood is the element won't even render, not even a flash,
  // so some of these are just precautions. However in IE the element
  // is visible whilst the popup box asking the user for permission for
  // the web page to copy to the clipboard.
  //

  // Place in top-left corner of screen regardless of scroll position.
  textArea.style.position = 'fixed'
  textArea.style.top = '0'
  textArea.style.left = '0'

  // Ensure it has a small width and height. Setting to 1px / 1em
  // doesn't work as this gives a negative w/h on some browsers.
  textArea.style.width = '2em'
  textArea.style.height = '2em'

  // We don't need padding, reducing the size if it does flash render.
  textArea.style.padding = 0

  // Clean up any borders.
  textArea.style.border = 'none'
  textArea.style.outline = 'none'
  textArea.style.boxShadow = 'none'

  // Avoid flash of white box if rendered for any reason.
  textArea.style.background = 'transparent'

  textArea.value = text

  document.body.appendChild(textArea)

  textArea.select()

  try {
    const successful = document.execCommand('copy')
    const msg = successful ? 'successful' : 'unsuccessful'
    console.log('Copying text command was ' + msg)
  } catch (err) {
    console.log('Oops, unable to copy')
  }

  document.body.removeChild(textArea)
}

【讨论】:

  • 感谢您的回答。我将修改方法直接复制v建模的数据,而不是选择输入内容然后复制。还有没有办法避免创建文本区域来复制数据?
  • @newbiedev 不是我所知道的。但它永远不会出现。这一切都发生在一个事件循环中。
【解决方案2】:

作为我尝试使用clipboard API 的已接受答案之一的替代解决方案。特别是我使用了 clipboard.writeText() 方法将 v 建模数据直接复制到剪贴板,它也适用于 &lt;input type="password"&gt; 这是copyToClipboard()方法的重构代码:

    copyToClipboard() {
      navigator.clipboard.writeText(this.password);
      this.isCopied = true;
      setTimeout( () => { this.isCopied = !this.isCopied },3000);
    }

【讨论】:

  • writeText 是一个承诺。您应该 .then 或 await 它。如果用户拒绝许可,它应该会出错。所以你应该尝试/抓住等待,或者 .catch 承诺。
猜你喜欢
  • 2014-01-31
  • 2020-07-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-30
  • 1970-01-01
  • 2020-09-17
  • 1970-01-01
相关资源
最近更新 更多