vue-clipboard2在ios,mac的异步方法中无法copy的问题
需求是需要copy从后台接口返回的字符串到剪切板,在mac 的chrome,android 微信,浏览器中测试都可以,但在iphone safari,微信,还有mac 的safari中copy都失败
this.$axios.get(`${this.host}/goods/go/${code}`).then((res) => { console.log('res = ' + res.data); this.taobaoPwd = res.data; console.log('taobaoPwd = ' + res.data); let that = this; this.$copyText(this.taobaoPwd).then( function (e) { console.log(e); that.showing = true; }, function (e) { alert('Can not copy'); console.log(e); }, );
因为this.$copyText是在$axios这个异步方法里的,而在vue-clipboard2主页上有一句话,[https://github.com/Inndy/vue-clipboard2]
Yes, you can do it by using our new method: this.$copyText. See sample2, where we replace the clipboard directives with a v-on directive.
Modern browsers have some limitations like that you can't use window.open without a user interaction. So there's the same restriction on copying things! Test it before you use it.
Make sure you are not using this method inside any async method.
上面已经明确说明这个方法无法用在异步方法里面(原因未知,得花点时间把源码研究一下)
解决办法是不能写在异步方法里,试过用async await,但无法用在带有async的方法里。也在想把axios变成同步的,但无法做到,最后是用了jquery里的$ajax
if (this.isTaoPwd) { $.ajaxSettings.async = false; let that = this; $.ajax({ type: 'get', async: false, url: `${this.host}/goods/go/${code}`, success: function (res) { console.log('res = ' + res); that.taobaoPwd = res; console.log('taobaoPwd = ' + res); that.$q.loading.hide(); }, }); this.$copyText(this.taobaoPwd).then( function (e) { console.log('this.taobaoPwd = ' + that.taobaoPwd); that.showing = true; let t = setTimeout(() => { that.showing = false; }, 1500); }, function (e) { alert('Can not copy'); console.log(e); }, ); }
注意不能把this.$copyText 写在$ajax的回调函数sucss里面(也是异步方法?)
================================================
这个问题折腾了好久,一开始采用[https://github.com/Inndy/vue-clipboard2]第一种方法
<div id="app"></div> <template id="t"> <div class="container"> <input type="text" v-model="message"> <button type="button" v-clipboard:copy="message" v-clipboard:success="onCopy" v-clipboard:error="onError">Copy!</button> </div> </template> <script> new Vue({ el: '#app', template: '#t', data: function () { return { message: 'Copy These Text' } }, methods: { onCopy: function (e) { alert('You just copied: ' + e.text) }, onError: function (e) { alert('Failed to copy texts') } } }) </script>
这种方法的问题是无法copy刚从接口返回的数据,而copy的是点click时绑定的数据”message“,这个数据是滞后的。
后来又改用vue-clipboard2 的前身 clipboard.js
这个的问题是点击第一次的时候没反应,第二次才有
this.clipboard = new Clipboard('.copy-taobao', { text: () => this.taobaoPwd, }); this.clipboard.on('success', (e) => { that.showing = true; console.log('copy success'); // this.$q.loading.hide(); let t = setTimeout(() => { that.showing = false; }, 1500); this.clipboard.destroy(); }); this.clipboard.on('error', (e) => { alert('Can not copy'); console.log(e); // this.clipboard.destroy(); });
因为它实现的方式是要先 new Clipboard 初始化,然后点击button发生click事件,然后 this.clipboard.on()才能触发。而我们的需求需要copy的数据是每次从后台取的,每次在接口回调时才初始化,这时是不会被“success”监听到的,因为初始化是在click事件之后发生的。而如果把初始化放在mount()里,则copy的数据是上一次取的老数据,因为最新的是从接口返回然后t保存在this.taobaoPwd。