需求是需要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。