前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【云+社区年度征文】前端实现仿微博@功能&&qrcode根据url转换成二维码

【云+社区年度征文】前端实现仿微博@功能&&qrcode根据url转换成二维码

原创
作者头像
河湾欢儿
修改2020-12-08 14:30:57
7250
修改2020-12-08 14:30:57
举报

首先说下我们的业务场景

我们目前有三个平台 分别是淘宝抖音快手(搞数据爬虫的),看了一下微博的大概发布逻辑,微博是前端给后端一个@马总 或者 #马总真棒# 后端把它转成标签的格式例如 `<a href='www,mazong,com'>马总</href>没有的话则创建一个话题,前端只需要读取就可 但是我们这个不可以这样做 因为我们有三个平台 如果直接给后端传一个名字,并不知道用户想要的哪个平台的名字,跳转的话就会有bug,所以这就需要前端来处理;下面开始说一下如何实现。

首先插件是使用的"tributejs": "^5.1.3", 附git链接:https://github.com/zurb/tribute。(注:还有一些bug作者没有解决,详情见issues)

然后和后台沟通好怎么传输 我们是这个格式 #薇娅#[69226163,taobao] 返回的时候也是这个格式然后自己前端处理一下渲染出来。

里面有一个trigger是触发器 就是触发下拉框的一个事件

触发器触发的下拉框.png
触发器触发的下拉框.png

selectTemplate是点击确定以后渲染到页面的格式 例如我是这样写的:

代码语言:txt
复制
selectTemplate: function (item) {
    if (this.range.isContentEditable(this.current.element)) {
        let tpl = `<a href="javascript:void(0)" 
                    name='${item.original.anchorNickname}'
                    id='${item.original.anchorId}'
                    plantfrom='${item.original.anchorPlatform}'
                    style='color: #FF6B60'
                    contenteditable='true'  target="_blank">
                            #${item.original.anchorNickname}#</a>`
        return tpl
    }
},

menuItemTemplate是下拉框的一些样式:

代码语言:txt
复制
 menuItemTemplate: function (item) {
        return `<div class="menuItem" @click="mx">
                    <em>${item.original.anchorNickname}</em> 
                    <em>粉丝: ${ that.formatNum(item.original.anchorLatestFansNums)}</em> 
                    <span class="${item.original.anchorPlatform == 'kuaishou'?'kuaishou' : (item.original.anchorPlatform == 'douyin' ?'douyin':'taobao')}" >
                        ${item.original.anchorPlatform == 'kuaishou'? '快手平台' : (item.original.anchorPlatform == 'douyin'? '抖音平台' : '淘宝平台') }
                    </span> 
                </div>`
    },

当然还有一些其他的一些配置

例如:

replaceTextSuffix 回车确认以后尾随的值

noMatchTemplate 没有搜索到时显示的文案undefinedlookup 搜索时选择的参数

values数据

values: [{ key: "Phil Heartman", value: "pheartman" },{ key: "Gordon Ramsey", value: "gramsey" } ] 可以填写默认值 也可以写请求方法请求的数据。 接下来会有小伙伴说了,啊 那他是怎么知道我的输入框在哪里的?别着急,看这里-> this.$nextTick(()=>{ tribute.attach(document.querySelectorAll(".mentionable"));// 绑定你所需要的div的class名字 })

接下来样式写完了 开始连接跟后台的api;

代码语言:txt
复制
var tribute = new Tribute({
    values: (text, cb)=> {
        this.remoteSearch(text, users => cb(users));
    }
})

/********************************/

methods:{
    remoteSearch (text, cb) {
                this.text = text;
                if(!text){
                    return;
                }
                if(this.time){//节流防抖
                    this.time = false
                    setTimeout(()=>{
                        this.search_anchor(this.text, cb)
                        this.time = true;
                    },2000)
                }
            },
}

功能到这里其实差不多了,但是我们还有一个点击下面的按钮 添加一个#其实就跟微博@一样,点击会在文本框里添加一个#或者@。(目前无法实现根据上次光标的地方点击插入进去)

点击关联添加#.png
点击关联添加#.png

给需要触发的div绑定事件insertVariable(将文本框原本的内容和#做拼接)

代码语言:txt
复制
insertVariable(value){ //在textarea的光标处插入置顶文字
                var sel = this.$refs.gain;
                sel.innerHTML += " #";
                var range = window.getSelection();
                range.selectAllChildren(sel);
                range.collapseToEnd();
            }

直接这样写是可以尾部插入一个# 但是有一系列的问题 比如换行等 一系列神奇的bug

优化代码如下:

代码语言:txt
复制
insertVariable(value){ //在textarea的光标处插入置顶文字
    var sel = this.$refs.gain;
    if(sel.innerHTML == '<br>'){ //解决莫名其妙换行问题 (里面数据为空时会塞入一个br  没有找到原因)
        sel.innerHTML = " #";
    }else{
        sel.innerHTML += " #";
    }
    var range = window.getSelection();
    range.selectAllChildren(sel);
    range.collapseToEnd();
},

成功解决~;

接下来如何渲染呢;

别着急,上代码!

代码语言:txt
复制
htmlShow(){
    var reg = /#([^#]+?)#\[(.+?),(.+?)\]/g;
    var str = this.content;
    if(!this.content){
        return;
    } else if(!str.match(reg)){
        this.htmlInner = str;
        return;
    }
    var repe = str.replace(reg, function (a, b, c, d) {
        var name = a.split("#[");
        var platform = (name[1].split(",")[1].split("]")[0]).trim();
        var id = name[1].split(",")[0];
        if(platform == 'taobao'){
            return `<span><a href='/taobao/anchorModel/searchAnchor/anchor-detail/${id}' style='color: #FF5353;text-decoration:none;'> ${name[0]}# </a></span>`;
        } else if(platform == 'kuaishou'){
            return `<span><a href='/kuaishou/anchor/anchor-detail/${id}' style='color: #FF5353;text-decoration:none;'> ${name[0]}# </a></span>`;
        } else if(platform == 'douyin'){
            return `<span><a href='/douyin/anchor/anchor-detail/${id}' style='color: #FF5353;text-decoration:none;'> ${name[0]}# </a></span>`;
        }else{
            return ''
        }
    });
    this.htmlInner = repe;
    }  

使用正则配合来筛选出所有的带#xxx#xxx,xxxx 的格式然后使用字符串拼接起来把数据return出去就可以了。

发布文章可以啦,接下来还有一个需求是分享发布到微博和朋友圈,

分享微博的话直接用https://service.weibo.com/share/share.php?url=分享地址?&sharesource=weibo&title=分享内容 拼接即可 使用npm包来引入 qrcode ,返回的参数里面第二个参数就是返回的base64

代码语言:txt
复制
var url = `http://beta2.dev.pangqiu.com/omni/content-details/${item.articleId}`
                QRCode.toDataURL(url, (err, url) => {
                    if(!err){
                        this.imgUrl = url;
                    }
                })

转换成功

image.png
image.png

里面有好多坑 踩了一个星期,才算搞完,头皮发麻。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档