美文网首页
前端实现仿微博@功能(tributejs)&&qrcode根据u

前端实现仿微博@功能(tributejs)&&qrcode根据u

作者: 奶瓶SAMA | 来源:发表于2020-12-10 11:16 被阅读0次

    首先说下我们的业务场景

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

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

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

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

    [图片上传失败...(image-3e5e3d-1607570108175)]

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

    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是下拉框的一些样式:

     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;

    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)
                    }
                },
    }
    

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

    image.png

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

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

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

    优化代码如下:

    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();
    },
    

    成功解决~;

    接下来如何渲染呢;

    别着急,上代码!

    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

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

    转换成功

    image.png

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

    相关文章

      网友评论

          本文标题:前端实现仿微博@功能(tributejs)&&qrcode根据u

          本文链接:https://www.haomeiwen.com/subject/qpvlgktx.html