• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

用于微信小程序的图文编辑器

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

由于微信小程序不能使用常规的图文编辑器(比如百度的UEditor )编辑新闻内容之类的,所以用vue写了个针对小程序用的图文编辑器。效果如下

 

多图上传图片用到了  ajaxfileupload.js (不知道哪位仁兄写的,拿来用了,很好用)

 

最终形成一串Json数据(转成字符串,传入后台存入数据库,小程序端用JSON.parse 转成JSON ,按照后台一样的方式渲染即可【小程序端代码还没写,后面再贴出来吧】)

json格式如

[{"mytype":1,"content":"测试数据\n\n11111\n\n","font":{"size":0,"weight":1,"del":1,"line":0,"center":1,"color":"#ED1C24","bgcolor":"#fff","showcolor":0}},{"mytype":3,"content":""},{"mytype":2,"content":"/upload/dyProductImgs/20180725/9841925131090216.jpg_E500_100.jpg","loading":1,"groupid":"627459ec-d372-e372-218e-b93b83cb2d02"},{"mytype":2,"content":"/upload/dyProductImgs/20180725/1574162212592205.jpg_E500_100.jpg","loading":1,"groupid":"627459ec-d372-e372-218e-b93b83cb2d02"},{"mytype":2,"content":"/upload/dyProductImgs/20180725/8745023656415428.jpg_E500_100.jpg","loading":1,"groupid":"627459ec-d372-e372-218e-b93b83cb2d02"},{"mytype":2,"content":"/upload/dyProductImgs/20180725/7027501123579481.jpg_E500_100.jpg","loading":1,"groupid":"627459ec-d372-e372-218e-b93b83cb2d02"}]

  

 

html代码

  1 <div class="editor-box vue-container">
  2     <div class="vuefor" v-for="i in editorData.length+1" v-on:click="hidecolorbox(i-1)">
  3         <div class="tool-box">
  4             <div class="tool-box-sub">
  5                 <div class="tool-list">
  6                     <div v-if="reload">
  7                         <input type="file" v-on:change.stop="uploadfile(i-1)" v-bind:id="buildfileid(i-1)" v-bind:name="buildfileid(i-1)" multiple="multiple">
  8                     </div>
  9                     <label class="tool-item" v-on:click.stop="itemadd(i-1,1)">
 10                         <div class="icon"><img src="~/res/img/icon-font.png" alt="" /></div>
 11                         <div class="text">文字</div>
 12                     </label>
 13                     <!--v-on:click.stop="itemadd(i-1,2)"-->
 14                     <label class="tool-item" v-bind:for="buildfileid(i-1)">
 15                         <div class="icon"><img src="~/res/img/icon-img.png" alt="" /></div>
 16                         <div class="text">图片</div>
 17                     </label>
 18                     <label class="tool-item" v-on:click.stop="itemadd(i-1,3)">
 19                         <div class="icon"><img src="~/res/img/icon-line.png" alt="" /></div>
 20                         <div class="text">分割</div>
 21                     </label>
 22                     <label class="tool-item enabled" v-on:click.stop="itemadd(i-1,4)">
 23                         <div class="icon"><img src="~/res/img/icon-video.png" alt="" /></div>
 24                         <div class="text">视频</div>
 25                     </label>
 26                     <label class="tool-item enabled" v-on:click.stop="itemadd(i-1,5)">
 27                         <div class="icon"><img src="~/res/img/icon-link.png" alt="" /></div>
 28                         <div class="text">链接</div>
 29                     </label>
 30                 </div>
 31             </div>
 32         </div>
 33         <div class="editor-item" v-if="i <= editorData.length">
 34 
 35             <div class="head">
 36                 <div class="h-btn fleft" v-on:click.stop="itemup(i-1)">
 37                     <img src="~/res/img/icon-up.png" />
 38                 </div>
 39                 <div class="h-btn fleft" v-on:click.stop="itembottom(i-1)">
 40                     <img src="~/res/img/icon-bottom.png" />
 41                 </div>
 42                 <div class="h-btn fright" v-on:click.stop="itemdel(i-1)">
 43                     <img src="~/res/img/icon-del.png" />
 44                 </div>
 45             </div>
 46             <div class="content" v-if="editorData[i-1].mytype==1">
 47                 <!--文字类型的输入框-->
 48                 <div class="text-box">
 49                     <div class="head">
 50                         <div title="加粗" v-on:click.stop="fontweight(i-1)" v-bind:class="{ \'head-btn\': true,\'sel\':editorData[i-1].font.weight==1 }"><img src="~/res/img/icon-font-weight.png" alt="" /></div>
 51                         <div title="放大字体" v-on:click.stop="fontda(i-1)" v-bind:class="{ \'head-btn\': true}"><img src="~/res/img/icon-font-da.png" alt="" /></div>
 52                         <div title="缩小字体" v-on:click.stop="fontxiao(i-1)" v-bind:class="{ \'head-btn\': true}"><img src="~/res/img/icon-font-xiao.png" alt="" /></div>
 53                         <div title="删除线" v-on:click.stop="fontdel(i-1)" v-bind:class="{ \'head-btn\': true,\'sel\':editorData[i-1].font.del==1 }"><img src="~/res/img/icon-font-del.png" alt="" /></div>
 54                         <div title="下划线" v-on:click.stop="fontline(i-1)" v-bind:class="{ \'head-btn\': true,\'sel\':editorData[i-1].font.line==1 }"><img src="~/res/img/icon-font-line.png" alt="" /></div>
 55                         <div title="居中" v-on:click.stop="fontcenter(i-1)" v-bind:class="{ \'head-btn\': true,\'sel\':editorData[i-1].font.center==1 }"><img src="~/res/img/icon-font-center.png" alt="" /></div>
 56                         <div title="字体颜色" v-on:click.stop="fontshowcolor(i-1)" v-bind:class="{ \'head-btn\': true }" v-bind:style="initfontcolor(editorData[i-1].font)">
 57                             A
 58                             <div v-on:click.stop="stopclick" class="color-box" v-bind:class="{\'hide\':editorData[i-1].font.showcolor!=1}">
 59                                 <div class="color-title">
 60                                     字体颜色
 61                                 </div>
 62                                 <div class="color-list">
 63                                     <div class="color-item" v-for="color in colors">
 64                                         <span v-on:click.stop="fontsetcolor(i-1,color)" v-bind:style="initbgcolor(color)"></span>
 65                                     </div>
 66                                 </div>
 67                                 <div class="color-title">
 68                                     字体颜色代码
 69                                 </div>
 70                                 <div class="color-input">
 71                                     <input type="text" v-model="editorData[i-1].font.color" />
 72                                 </div>
 73                                 <!--<div class="color-title">
 74                                     字体背景颜色
 75                                 </div>
 76                                 <div class="color-list">
 77                                     <div class="color-item" v-for="color in colors">
 78                                         <span v-on:click.stop="fontsetcolor(i-1,color)" v-bind:style="initbgcolor(color)"></span>
 79                                     </div>
 80                                 </div>
 81                                 <div class="color-title">
 82                                     字体背景颜色代码
 83                                 </div>
 84                                 <div class="color-input">
 85                                     <input type="text" v-model="editorData[i-1].font.bgcolor" />
 86                                 </div>-->
 87                             </div>
 88                         </div>
 89                     </div>
 90                     <div class="line"></div>
 91                     <div class="input">
 92                         <textarea name="" rows="" cols="" v-bind:style="initstyle(editorData[i-1].font)" v-model="editorData[i-1].content"></textarea>
 93                     </div>
 94                     <div class="line"></div>
 95                 </div>
 96             </div>
 97 
 98             <div class="content" v-if="editorData[i-1].mytype==2" style="">
 99                 <!--图片-->
100                 <div class="img-box">
101                     <img v-if="editorData[i-1].loading==1" v-bind:src="editorData[i-1].content" alt="" />
102                     <img class="loading" v-if="editorData[i-1].loading==0" src="~/res/img/img_loading.gif" alt="" />
103                 </div>
104             </div>
105 
106             <div class="content" v-if="editorData[i-1].mytype==3">
107                 <!--分割线-->
108                 <div class="line-box">
109                 </div>
110             </div>
111 
112             <div class="clear" style=""></div>
113         </div>
114     </div>
115 </div>
HTML代码

js 代码

需要引用 jquery、vue、ajaxfileupload

var pageData = {
        editorData: [],
        colors: [
            "#000",
            "#7F7F7F",
            "#880015",
            "#ED1C24",
            "#FF7F27",
            "#FFF200",
            "#22B14C",
            "#3F48CC",
            "#E36C09",
            "#31859B",
            "#5F497A",
            "#76923C",
            "#953734",
            "#366092",
            "#938953",
            "#fff"
        ],
        reload:true
    };

        //初始化vue
    var vmMenu = new Vue({
        el: \'.vue-container\',
        data: pageData,
        methods: {
            //生成一个fileid
            buildfileid: function (index) {
                return "file" + index;
            },
            initstyle: function (font) {
                var stylestr = "";
                var fontsize = 18;
                fontsize += font.size * 3;
                stylestr += "font-size: " + fontsize + "px;"
                if (font.weight == 1) stylestr += "font-weight: bold;"
                if (font.del == 1) stylestr += "text-decoration:line-through;"
                if (font.line == 1) stylestr += "text-decoration:underline;"
                if (font.center == 1) stylestr += "text-align: center;"
                if (font.color) stylestr += ("color:" + font.color + ";");
                if (font.bgcolor) stylestr += ("display: inline;background-color:" + font.bgcolor + ";");
                return stylestr;
            },
            //字体的颜色
            initfontcolor: function (font) {
                var result = "";
                result += "color:";
                result += font.color;
                result += ";";
                result += "background-color:";
                result += font.bgcolor;
                result += ";";
                return result;
            },
            //字体背景的颜色
            initbgcolor: function (color) {
                return "background-color:" + color;
            },
            //加粗或者取消嘉措
            fontweight: function (index) {
                pageData.editorData[index].font.weight = (pageData.editorData[index].font.weight == 1 ? 0 : 1);
            },
            //字体加大
            fontda: function (index) {
                pageData.editorData[index].font.size++;
            },
            //字体减小
            fontxiao: function (index) {
                pageData.editorData[index].font.size--;
            },
            //删除线
            fontdel: function (index) {
                pageData.editorData[index].font.del = (pageData.editorData[index].font.del == 1 ? 0 : 1);
            },
            //下划线
            fontline: function (index) {
                pageData.editorData[index].font.line = (pageData.editorData[index].font.line == 1 ? 0 : 1);
            },
            //居中显示
            fontcenter: function (index) {
                pageData.editorData[index].font.center = (pageData.editorData[index].font.center == 1 ? 0 : 1);
            },
            fontshowcolor: function (index) {
                pageData.editorData[index].font.showcolor = (pageData.editorData[index].font.showcolor == 1 ? 0 : 1);
            },
            //选择字体颜色
            fontsetcolor: function (index, color) {
                pageData.editorData[index].font.color = color;
                this.hidecolorbox(index);
            },
            //隐藏颜色选择框
            hidecolorbox: function (index) {
                if (pageData.editorData && pageData.editorData.length > index && pageData.editorData[index].mytype == 1)
                    pageData.editorData[index].font.showcolor = 0;
            },
            //上传图片
            uploadfile: function (index) {
                //用于强制重新渲染 input.file 用于清空之前的文件 ^_^
                pageData.reload = false;
                //添加一个组ID,方便后面上传完成后识别应该更新哪条数据
                var groupid = guid();
                var that = this;
                var fileid = "file" + index;
                var files = $("#" + fileid)[0].files;
                for (var i = 0; i < files.length; i++) {
                    that.itemadd(index + i, 2, groupid);
                }
                jQuery.ajaxFileUpload({
                    url: \'@Url.Content("~/img/uploadproductdpicArray?path=dyProductImgs")\', //用于文件上传的服务器端请求地址
                    secureuri: false, //是否需要安全协议,一般设置为false
                    fileElementId: fileid, //文件上传域的ID
                    dataType: \'json\', //返回值类型 一般设置为json
                    success: function (data)  //服务器成功响应处理函数
                    {
                        //var result = JSON.parse(data);
                        pageData.reload = true;
                        var result = data;
                        console.log(result);
                        if (result.resultState == "1") {
                            var j = 0;
                            for (var i = 0; i < pageData.editorData.length; i++) {
                                if (pageData.editorData[i].groupid && pageData.editorData[i].groupid == groupid) {
                                    pageData.editorData[i].content = "@Url.Content("~")" + result.Data[j].substring(1);
                                    pageData.editorData[i].loading = 1;
                                    j++;
                                }
                            }
                            console.log(result);
                        }
                        else alert("上传失败!");
                    },
                    error: function (data)//服务器响应失败处理函数
                    {
                        alert("上传失败!");
                    }
                });
            },
            //上升模块
            itemup: function (index) {
                if (index > 0) {
                    var itemData = pageData.editorData[index];
                    pageData.editorData.splice(index, 1);
                    pageData.editorData.splice(index - 1, 0, itemData);

                }
            },
            //下降模块
            itembottom: function (index) {
                if (index + 1 < pageData.editorData.length) {
                    var itemData = pageData.editorData[index];
                    pageData.editorData.splice(index, 1);
                    pageData.editorData.splice(index + 1, 0, itemData);

                }
            },
            //删除模块
            itemdel: function (index) {
                pageData.editorData.splice(index, 1);
            },
            //添加一个新的模块
            itemadd: function (index, type, groupid) {
                var itemData = null;
                switch (type) {
                    case 1:
                        itemData = {
                            mytype: 1,
                            content: "",
                            font: {
                                size: 0, //字体大小 每+1 字体+2px -1同减
                                weight: 0, //是否加粗
                                del: 0, //是否删除线
                                line: 0, //是否下划线
                                center: 0, //是否居中
                                color: "#000", //字体颜色
                                bgcolor: "#fff", //字体颜色
                                showcolor: 0 //是否显示颜色选择框
                            }
                        };
                        break;
                    case 2:
                        itemData = {
                            mytype: 2,
                            content: "res/img/1.jpg",
                            loading: 0 //是否已经成功上传
                        };
                        break;
                    case 3:
                        itemData = {
                            mytype: 3,
                            content: ""
                        };
                        break;
                    default:
                        alert(\'暂不支持\');
                        break;
                }
                if (itemData) {
                    if (groupid) itemData.groupid = groupid;
                    pageData.editorData.splice(index, 0, itemData);
                }
            },
            //一个用于阻止冒泡的事件
            stopclick: function () { },
        },
        //实例被调用后
        created: function () {

        },
        //el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子。
        updated: function () {
            this.$nextTick(function () {
                ////console.log(pageData);
                //var files = this.$refs.feedbakcImg;
                //for (var i = 0; i < files.length; i++) {
                //    files[i].clearFiles();
                //}
            })
        }
    });
JS代码

 

后台代码 .net (有些方法没有放出来,后面我有时间整理一个单独的demo出来放到云盘)

 /// <summary>
        /// 批量上传商品详情图片
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public ContentResult uploadproductdpicArray(string path)
        {
            rData<List<string>> result = new rData<List<string>>();
            result = UpLoadPicArray(path);
            if (result.resultState == 1)
            for (int i = 0; i < result.Data.Count; i++)
            {
                if (ST.Tool.ImageHelp.GetImageSuffix(result.Data[i]) != ".gif")
                {
                     string imgPath = Server.MapPath($"~{result.Data[i]}");
                     string imgPathNoSuffix = imgPath.Substring(0, imgPath.LastIndexOf("."));
                     string imgSuffix = ST.Tool.ImageHelp.GetImageSuffix(imgPath);
                     Image oldimg = Image.FromFile(imgPath); //读取图片
                     //压缩宽度为500的图片,等比 清晰度 100
                     ST.Tool.ImageHelp.PicThumbnail(oldimg, imgPath + "_E500_100" + imgSuffix, 500, 0, 100);
                     oldimg.Dispose();
                     result.Data[i] = result.Data[i] + "_E500_100" + imgSuffix;
                }
            }
           
            var jsonResult = JsonConvert.SerializeObject(result);
            return new ContentResult() { Content = jsonResult };
        }



 /// <summary>
        /// 上传图片
        /// </summary>
        /// <param name="_path">保存图片的文件夹名称</param>
        /// <returns>保存结果</returns>
        private rData<string> UpLoadPic(string _path="public")
        {
            rData<string> result = new rData<string>();
            HttpFileCollectionBase _file = Request.Files;
            if (_file.Count > 0)
            {
                long size = _file[0].ContentLength;
                string type = _file[0].ContentType;
                string name = _file[0].FileName;
                //文件格式
                string _tp = Path.GetExtension(name);

                if (_tp.ToLower() == ".jpg" || _tp.ToLower() == ".jpeg" || _tp.ToLower() == ".gif" || _tp.ToLower() == ".png" || _tp.ToLower() == ".swf")
                {

                    Stream stream = _file[0].InputStream;
                    Image image = 
                       
                    
                    

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
记一次微信小程序开发发布时间:2022-07-18
下一篇:
微信小程序实现富文本编辑器 - Dragon-v发布时间:2022-07-18
热门推荐
    热门话题
    阅读排行榜

    扫描微信二维码

    查看手机版网站

    随时了解更新最新资讯

    139-2527-9053

    在线客服(服务时间 9:00~18:00)

    在线QQ客服
    地址:深圳市南山区西丽大学城创智工业园
    电邮:jeky_zhao#qq.com
    移动电话:139-2527-9053

    Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap