日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

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

發(fā)布時(shí)間:2023/12/31 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 用于微信小程序的图文编辑器 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

由于微信小程序不能使用常規(guī)的圖文編輯器(比如百度的UEditor?)編輯新聞內(nèi)容之類的,所以用vue寫(xiě)了個(gè)針對(duì)小程序用的圖文編輯器。效果如下

?

多圖上傳圖片用到了??ajaxfileupload.js (不知道哪位仁兄寫(xiě)的,拿來(lái)用了,很好用)

?

最終形成一串Json數(shù)據(jù)(轉(zhuǎn)成字符串,傳入后臺(tái)存入數(shù)據(jù)庫(kù),小程序端用JSON.parse 轉(zhuǎn)成JSON ,按照后臺(tái)一樣的方式渲染即可【小程序端代碼還沒(méi)寫(xiě),后面再貼出來(lái)吧】)

json格式如

[{"mytype":1,"content":"測(cè)試數(shù)據(jù)\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};//初始化vuevar vmMenu = new Vue({el: '.vue-container',data: pageData,methods: {//生成一個(gè)fileidbuildfileid: 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) {//用于強(qiáng)制重新渲染 input.file 用于清空之前的文件 ^_^pageData.reload = false;//添加一個(gè)組ID,方便后面上傳完成后識(shí)別應(yīng)該更新哪條數(shù)據(jù)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")', //用于文件上傳的服務(wù)器端請(qǐng)求地址secureuri: false, //是否需要安全協(xié)議,一般設(shè)置為falsefileElementId: fileid, //文件上傳域的IDdataType: 'json', //返回值類型 一般設(shè)置為jsonsuccess: function (data) //服務(wù)器成功響應(yīng)處理函數(shù){//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)//服務(wù)器響應(yīng)失敗處理函數(shù){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);},//添加一個(gè)新的模塊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 //是否已經(jīng)成功上傳};break;case 3:itemData = {mytype: 3,content: ""};break;default:alert('暫不支持');break;}if (itemData) {if (groupid) itemData.groupid = groupid;pageData.editorData.splice(index, 0, itemData);}},//一個(gè)用于阻止冒泡的事件stopclick: function () { },},//實(shí)例被調(diào)用后created: function () {},//el 被新創(chuàng)建的 vm.$el 替換,并掛載到實(shí)例上去之后調(diào)用該鉤子。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代碼

?

后臺(tái)代碼 .net (有些方法沒(méi)有放出來(lái),后面我有時(shí)間整理一個(gè)單獨(dú)的demo出來(lái)放到云盤(pán))

/// <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的圖片,等比 清晰度 100ST.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>保存結(jié)果</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 = Image.FromStream(stream);string dateDir = DateTime.Now.ToString("yyyyMMdd");string saveName = ST.Tool.ExpandString.GetNonceNumberT(16) + _tp;string filePath = $"{BaseConfig.headpath}{_path}/{dateDir}/";string path = Server.MapPath(filePath);if (!Directory.Exists(path)) Directory.CreateDirectory(path);//_file[0].SaveAs(Server.MapPath($"{filePath}{saveName}"));//初始化圖片對(duì)象//Image image = new Bitmap(Server.MapPath($"{filePath}{saveName}"));foreach (var p in image.PropertyItems){if (p.Id == 0x112){var rft = p.Value[0] == 6 ? RotateFlipType.Rotate90FlipNone: p.Value[0] == 3 ? RotateFlipType.Rotate180FlipNone: p.Value[0] == 8 ? RotateFlipType.Rotate270FlipNone: p.Value[0] == 1 ? RotateFlipType.RotateNoneFlipNone: RotateFlipType.RotateNoneFlipNone;p.Value[0] = 0; //旋轉(zhuǎn)屬性值設(shè)置為不旋轉(zhuǎn)image.SetPropertyItem(p); //回拷進(jìn)圖片流 image.RotateFlip(rft);}}//重新保存為正常的圖片image.Save(Server.MapPath($"{filePath}{saveName}"));result.Data = $"{filePath}{saveName}";}else result.errorMsg = "只能上傳圖片。";}else result.errorMsg = "未選擇文件";return result;}/// <summary>/// 上傳多張圖片/// </summary>/// <param name="_path"></param>/// <returns></returns>private rData<List<string>> UpLoadPicArray(string _path = "public"){rData<List<string>> result = new rData<List<string>>();result.Data = new List<string>();HttpFileCollectionBase _file = Request.Files;if (_file.Count > 0)for (int i = 0; i < _file.Count; i++){//Thread.Sleep(500);long size = _file[i].ContentLength;string type = _file[i].ContentType;string name = _file[i].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[i].InputStream;Image image = Image.FromStream(stream);string dateDir = DateTime.Now.ToString("yyyyMMdd");string saveName = ST.Tool.ExpandString.GetNonceNumberT(16) + _tp;string filePath = $"{BaseConfig.headpath}{_path}/{dateDir}/";string path = Server.MapPath(filePath);if (!Directory.Exists(path)) Directory.CreateDirectory(path);//_file[0].SaveAs(Server.MapPath($"{filePath}{saveName}"));//初始化圖片對(duì)象//Image image = new Bitmap(Server.MapPath($"{filePath}{saveName}"));foreach (var p in image.PropertyItems){if (p.Id == 0x112){var rft = p.Value[0] == 6 ? RotateFlipType.Rotate90FlipNone: p.Value[0] == 3 ? RotateFlipType.Rotate180FlipNone: p.Value[0] == 8 ? RotateFlipType.Rotate270FlipNone: p.Value[0] == 1 ? RotateFlipType.RotateNoneFlipNone: RotateFlipType.RotateNoneFlipNone;p.Value[0] = 0; //旋轉(zhuǎn)屬性值設(shè)置為不旋轉(zhuǎn)image.SetPropertyItem(p); //回拷進(jìn)圖片流 image.RotateFlip(rft);}}//重新保存為正常的圖片image.Save(Server.MapPath($"{filePath}{saveName}"));result.Data.Add($"{filePath}{saveName}");//result.Data = $"{filePath}{saveName}"; }else result.errorMsg = "只能上傳圖片。";}else result.errorMsg = "未選擇文件";return result;}

?現(xiàn)在增加上微信小程序端的代碼?

js:(對(duì)從接口返回的數(shù)據(jù)進(jìn)行處理)

//將后臺(tái)返回的數(shù)據(jù)轉(zhuǎn)成JSON格式。ProductDesc = JSON.parse(ProductDesc);if (ProductDesc)for (var p = 0; p < ProductDesc.length; p++) {ProductDesc[p].style = "";//如果是文字類型,需要設(shè)置樣式if (ProductDesc[p].mytype == 1 && ProductDesc[p].font) {if (ProductDesc[p].font.del == 1) ProductDesc[p].style += "text-decoration:line-through;"if (ProductDesc[p].font.line == 1) ProductDesc[p].style += "text-decoration:underline;"if (ProductDesc[p].font.center == 1) ProductDesc[p].style += "text-align:center;"if (ProductDesc[p].font.weight == 1) ProductDesc[p].style += "font-weight:bold;"if (ProductDesc[p].font.color) ProductDesc[p].style += "color:" + ProductDesc[p].font.color + ';'if (ProductDesc[p].font.size) ProductDesc[p].style += "font-size:" + (30 + 6 * ProductDesc[p].font.size) + 'rpx'}}

  view:(按照預(yù)定格式展現(xiàn)視圖)

<block wx:for="{{ProductDesc}}" wx:for-item="item" wx:key="index"><block wx:if="{{item.mytype==1&&item.font}}"><view class='ProductDesctext' style='{{item.style}}'>{{item.content}}</view></block><block wx:if="{{item.mytype==3}}"><view class='ProductDescline'></view></block><block wx:if="{{item.mytype==2}}"><image src='{{hostimg}}{{item.content}}' mode='widthFix'></image></block></block>

  

?

轉(zhuǎn)載于:https://www.cnblogs.com/shitian-net/p/9366896.html

總結(jié)

以上是生活随笔為你收集整理的用于微信小程序的图文编辑器的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。