实现vue移动端的复制粘贴

第一种使用 vue-clipboard2

1、npm i vue-clipboard2 – save 安装后,在main.js中引入

// vue剪切板功能
import VueClipboard from 'vue-clipboard2'
Vue.use(VueClipboard)

2、在组件中使用

// template中
<div class="flex-center"><div class="info-left">订单号</div><div class="fs-24 color-333 font-bold">{{orderDetailData.orderId}}</div><div class="copy ml-20"><img src="../../assets/images/order/order-copy.png" alt="" v-clipboard:copy="orderDetailData.orderId" v-clipboard:success="onCopySuccess" v-clipboard:error="onCopyError"/></div>
</div>// script的methods中
// 复制粘贴onCopySuccess(){this.$toast("复制成功");},onCopyError(){this.$toast("复制失败");},

第二种使用自己写

封装一个写法:

export function copyText(text) {// 动态创建 textarea 标签const textarea = document.createElement('textarea')// 将该 textarea 设为 readonly 防止 iOS 下自动唤起键盘,同时将 textarea 移出可视区域textarea.readOnly = 'readonly'textarea.style.position = 'absolute'textarea.style.left = '-9999px'// 将要 copy 的值赋给 textarea 标签的 value 属性textarea.value = text// 将 textarea 插入到 body 中document.body.appendChild(textarea)// 选中值并复制textarea.select()const result = document.execCommand('Copy')document.body.removeChild(textarea)return result
}

引入使用

<template><div><div class="c-container"><div class="c-title">评论</div><div class="c-item" v-for="(item, index) in comments" :key="index"><!-- 评论 --><divclass="c-info"@touchstart="touchstart(item.id, item.commentatorId, item.content, 'comment')"@touchend="touchend"@click="handleIptClick(item.id, item.commentatorId)"><div class="title"><div class="author">{{ item.commentator }}</div><div class="c-time">{{ parseTime(item.commentTime, '{m}月{d}日 {h}:{i}') }}</div></div><div class="content">{{ item.content }}</div></div><!-- 回复 --><divclass="r-info"v-for="(repItem, repIndex) in item.replyList"@click="handleIptClick(item.id, repItem.sentorId)"@touchstart="touchstart(repItem.id, repItem.sentorId, repItem.content, 'reply')"@touchend="touchend":key="repIndex"><div class="title"><div class="author">{{ repItem.sentor }}<span class="mid-text">回复</span>{{ repItem.receivor }}</div><div class="c-time">{{ parseTime(repItem.replyTime, '{m}月{d}日 {h}:{i}') }}</div></div><div class="content">{{ repItem.content }}</div></div></div><div class="c-ipt"><inputtype="text"v-model="commentContent"maxlength="100"placeholder="评价内容,文字上限100"@keydown.enter="handleSent"@click="handleIptClick(null)"/><imgclass="icon"src="@/assets/img/icon-sent.png"@click="handleSent"/></div><div class="inputing" v-show="isInputing" @click="$refs.inputing.focus()"><div class="c-title">评论</div><div class="c-ipt"><inputtype="text"v-model="commentContent"maxlength="100"ref="inputing"placeholder="评价内容,文字上限100"@keydown.enter="handleSent"/><imgclass="icon"src="@/assets/img/icon-sent.png"@click.stop="handleSent"/></div></div></div><van-overlay :show="isInputing || isShowCtxBtns" @click="isInputing = isShowCtxBtns = false"/><div class="ctx-btns" v-show="isShowCtxBtns"><div class="btn" @click="handleCopy">复制</div><div class="btn" @click="handleRemove" v-show="userAccountId === ownerUserId">删除</div><div class="btn" @click="resetOption">取消</div></div></div>
</template><script>
import {getComments,createComment,createReply,removeComment,removeReply
} from '@/api/comment'import { copyText, parseTime } from '@/utils'
const originResizeFn = window.onresize
export default {props: {id: {type: String,default: ''}},data() {return {comments: [],commentContent: '',selectedCommentId: '',selectedType: '',selectContent: '', // 用于复制receivorId: '',ownerUserId: '',isInputing: false,isShowCtxBtns: false,pressTimer: null}},created() {this.parseTime = parseTime},mounted() {// 禁用浏览器长按默认事件document.oncontextmenu = function (e) {e.preventDefault()}const clientHeight =document.documentElement.clientHeight || document.body.clientHeightwindow.onresize = () => {// 防止两个事件冲突originResizeFn && originResizeFn()const nowClientHeight =document.documentElement.clientHeight || document.body.clientHeight// 键盘收起if (clientHeight === nowClientHeight) {this.isInputing = false}}this.initComments()},methods: {async initComments() {try {$loading.show()const res = await getComments({ taskDetailId: this.id })if (res.code === 0) {this.comments = res.item}$loading.hide()} catch (error) {$loading.hide()}},handleIptClick(id, receivorId) {this.isInputing = truethis.selectedCommentId = id || ''this.receivorId = receivorId || ''this.$nextTick(() => {this.$refs.inputing.focus()})},async handleSent() {if (!this.commentContent) returntry {$loading.show()// 有选中的评论,则是回复,否则就是评论if (this.selectedCommentId) {const res = await createReply({commentId: this.selectedCommentId,content: this.commentContent,receivor: this.receivorId})if (res.code === 0) {this.$toast('回复成功')this.resetOption()this.initComments()} else {this.$toast(res.message)}} else {const res = await createComment({taskDetailId: this.id,content: this.commentContent})if (res.code === 0) {this.$toast('评论成功')this.resetOption()this.initComments()} else {this.$toast(res.message)this.resetOption()}}} catch (error) {this.$toast('操作失败')this.resetOption()console.error(error)}$loading.hide()},handleOpenCtx(id, ownerUserId, content, selectedType) {this.isShowCtxBtns = truethis.selectedType = selectedType || ''this.selectedCommentId = id || ''this.ownerUserId = ownerUserId || ''this.selectContent = content || ''},handleCopy() {const rst = copyText(this.selectContent)rst && this.$toast('复制成功')this.resetOption()},async handleRemove() {try {$loading.show()let res// 删除回复if (this.selectedType === 'reply') {res = await removeReply({id: this.selectedCommentId})} else {// 删除评论res = await removeComment({id: this.selectedCommentId})}if (res.code === 0) {this.$toast('删除成功')this.resetOption()this.initComments()} else {this.resetOption()this.$toast(res.message)}} catch (error) {this.$toast('操作失败')this.resetOption()console.error(error)}$loading.hide()},resetOption() {this.isInputing = falsethis.isShowCtxBtns = falsethis.commentContent = ''this.selectedCommentId = nullthis.receivorId = nullthis.selectedType = ''this.ownerUserId = ''},touchstart(id, ownerUserId, content, selectedType) {this.pressTimer && clearTimeout(this.pressTimer)this.pressTimer = setTimeout(() => {this.handleOpenCtx(id, ownerUserId, content, selectedType)}, 600)},touchend() {this.pressTimer && clearTimeout(this.pressTimer)}},computed: {userAccountId() {return this.$store.getters.userAccountID}},destroyed() {window.onresize = originResizeFn}
}
</script><style lang="scss" scoped>
.c-container {width: 100%;background: #f5f6fb;padding: 0.3rem;.c-title {font-size: 0.28rem;color: #36395c;font-weight: 600;padding-bottom: 0.2rem;}.c-item {padding: 0.2rem 0;~ .c-item {border-top: 1px solid #eee;}.title {display: flex;height: 0.4rem;line-height: 0.4rem;.author {color: #4646e6;font-weight: 600;font-size: 0.28rem;margin-right: 0.26rem;.mid-text {color: #65687f;font-size: 0.24rem;font-weight: 300;margin: 0 0.14rem;}}.c-time {font-size: 0.22rem;font-weight: 300;color: #cccdd8;}}.content {color: #65687f;font-size: 0.26rem;font-weight: 400;line-height: 0.36rem;margin-top: 0.1rem;}.r-info {margin-top: 0.4rem;}}.c-ipt {display: flex;justify-content: space-between;align-items: center;height: 0.72rem;margin-top: 0.4rem;input {height: 100%;width: 6rem;padding-left: 0.24rem;font-weight: 300;font-size: 0.26rem;border-radius: 0.16rem;border: 0.01rem solid #efeff6;background: #ffffff;&::placeholder {color: #cccdd8;}/* IE 10–11 */&:-ms-input-placeholder {color: #cccdd8;}/* Firefox 19-50 */&::-moz-placeholder {color: #cccdd8;}::-webkit-input-placeholder {color: #cccdd8;}}.icon {height: 0.56rem;}}.inputing {background: #f5f6fb;z-index: 999;position: fixed;width: 100%;max-width: 450px;bottom: 0;left: 0;right: 0;margin: 0 auto;padding: 0.3rem;width: 100%;.c-ipt {margin: 0;}input {background-color: #fff;}}
}.ctx-btns {width: 100%;background-color: #fff;border-radius: 0.24rem 0.24rem 0rem 0rem;position: fixed;width: 100%;max-width: 450px;bottom: 0;left: 0;right: 0;margin: 0 auto;z-index: 999;.btn {color: #36395c;font-size: 0.34rem;font-weight: 300;text-align: center;line-height: 1.14rem;transition: all 0.3s;cursor: pointer;&:first-of-type {border-bottom: 0.02rem solid #f5f6fb;border-radius: 0.24rem 0.24rem 0rem 0rem;}&:last-of-type {border-top: 0.12rem solid #f5f6fb;}&:active,&:hover {background-color: #f5f6fb;}}
}.c-info,
.r-info,
.ctx-btns {-webkit-touch-callout: default;-moz-user-select: -moz-none;-moz-user-select: none;-o-user-select: none;-khtml-user-select: none;-webkit-user-select: none;-ms-user-select: none;user-select: none;
}
</style>

主要代码如下:

<div class="btn" @click="handleCopy">复制</div>import { copyText } from '@/utils'export default {data() {return {selectContent: '', // 用于复制}methods: {handleCopy() {const rst = copyText(this.selectContent)rst && this.$toast('复制成功')this.resetOption()},}
}

vue之实现移动端的复制粘贴功能(两种写法)相关推荐

  1. 本机远程Windows服务器远程桌面不能相互复制粘贴的两种解决方案

    方案1 首先我们连接远程桌面得时候需要设置一下剪贴板,如果不设置的话不管怎么复制都是不行的 这个D盘就是自己电脑的D盘 可以在Windows系统之间相互拷贝 设置完了之后可以去试试是否可以正常复制粘贴 ...

  2. vue点击复制链接功能两种方法实现

    今天在写需求的时候有个复制链接功能给实现下,有两种方式可实现 第一种用原生实现 <Button type="success" @click="copyLink(ro ...

  3. luckysheet移动端添加复制粘贴(批量粘贴)操作按钮

    需求: 移动端的luckysheet需要有类似钉钉写作文档中的选中一块区域后弹出复制.剪切等按钮. 操作: luckysheet滑动选中一块区域后会在左上角和右下角有小圆点,点击小圆点或者滑动选择区域 ...

  4. clipboard + element-ui +vue 实现复制粘贴功能与提示

    结合 clipboard.js 实现复制.粘贴功能 剪切功能参考官方文档,个人认为用不太上(有富文本编辑器的时候可能才用得上,也或许不需要自己实现) 想要知道怎么使用,优先参考官方文档(如何指定要复制 ...

  5. 网页端无法复制粘贴的解决方案

    由于瑞格系统无法复制粘贴,写java代码比较难受,所以就找了一些方法来解决网页端无法复制粘贴的问题 1.打开浏览器的设置界面,并打开拓展程序 2.在拓展程序中选择左上角的拓展程序,并打开Chrome网 ...

  6. vue element 表格内的复制粘贴功能

    最近项目里面 为了方便用户 增加了复制粘贴功能 来更方便的处理数据 要求如下: 点击复制 把此条的数据复制 点击粘贴 粘贴到最后一行 复制粘贴按钮做个权限 该出现的出现 不该出现的消失 <el- ...

  7. 最新js实现复制粘贴功能实例

    功能:实现鼠标点击复制内容 描述:使用与手机网站.pc等端. 实现点击复制粘贴功能的代码实例: function common_copy(text){if(text.indexOf('-') !== ...

  8. html5屏蔽ios长按复制,html5+CSS 实现禁止IOS长按复制粘贴功能

    html5+CSS 实现禁止IOS长按复制粘贴功能 因为在移动端APP需要实现长按执行别的事件,但是在iOS系统有默认的长按选择复制粘贴,禁止此功能在网上找了很多资料,最终整理出目前最好的解决方法. ...

  9. 软件测试面试题-如何测试复制粘贴功能

    复制粘贴是电脑最普遍的两个操作了,在面试的过程中,有学生被问到如何测试复制粘贴功能的时候,我个人觉得你可以这样去回答 更多学习资源,公众号主页点击领取资料 查看我评论区置顶 首先,这道题目你甚至可以发 ...

最新文章

  1. C# 获取指定目录下所有文件信息、移动目录、拷贝目录
  2. 连接网络计算机密码错误,局域网电脑连接提示网络错误怎么解决
  3. MFC CEdit 自动换行功能
  4. 【背包】逃亡的准备 (ssl 1236)
  5. .NET开发Silverlight程序:界面和对象模型
  6. nginx限制请求之一:(ngx_http_limit_conn_module)模块
  7. .NET程序不需要受SVN版本控制的文件类型
  8. Oracle中NB的中文处理
  9. 任意多边形的最大内切圆算法
  10. 【学习笔记】数据结构-单链表
  11. 小学期云效能训练营-Day01
  12. 使用 软考免费真题app刷题库 手机小程序版
  13. [斜率优化] 特别行动队 commando
  14. 课题申请的技术指标是什么
  15. Clean Code(整洁代码)
  16. Ngnix配置config
  17. 用HTML和CSS3制作3D动画
  18. Unity3D 角色基本行走和旋转动画控制Demo
  19. 【应用实战】各种串口转USB转串口方案参考2020-3-18
  20. win2008r2hpc无盘服务器配置,20台无盘网吧服务器配置

热门文章

  1. Hive窗口函数小结
  2. 【烂笔头】android 左上角三角形 右上角三角形
  3. MATLAB中曲线拟合方法总结(包括对数正态分布函数)
  4. 《AMCap网络摄像头测试软件》
  5. 微雪A20 配置 红外遥控器
  6. java 资源映射访问本地磁盘的文件或者访问项目静态资源
  7. jQuery+Bootstrap美化弹出框
  8. 土壤水分传感器与介电常数的区别
  9. 【系统分析师之路】2019年上系统分析师下午论文真题
  10. 山重水复疑无路,柳暗花明又一村(12.15一周总结)