gui-editor.vue 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. <template>
  2. <view class="gui-editor">
  3. <view class="gui-border-b">
  4. <textarea class="gui-editor-title" maxlength="-1"
  5. v-model="article.title" placeholder="# 请输入标题" auto-height />
  6. </view>
  7. <!-- 空内容提示 -->
  8. <view v-if="article.contents.length < 1">
  9. <text class="gui-color-gray gui-editor-empty">请点击下面的按钮,添加内容。</text>
  10. </view>
  11. <!-- 内容区域 -->
  12. <view v-for="(item, index) in article.contents" :key="index"
  13. class="gui-editor-items">
  14. <!-- 加粗 -->
  15. <view v-if="item.type == 'h3'">
  16. <textarea class="gui-editor-strong gui-border-box"
  17. :data-index="index" maxlength="-1" :focus="item.focusin"
  18. @input="graceEditorInput" :value="item.content" @blur="blur"
  19. placeholder="请输入标题" />
  20. </view>
  21. <!-- 普通文本 -->
  22. <view v-else-if="item.type == 'txt'">
  23. <textarea class="gui-editor-txt gui-border-box"
  24. maxlength="-1" @blur="blur"
  25. :data-index="index" :focus="item.focusin"
  26. @input="graceEditorInput" :value="item.content"
  27. placeholder="请填写文本内容" />
  28. </view>
  29. <!-- 居中文本 -->
  30. <view v-else-if="item.type == 'center'"
  31. class="gui-flex gui-rows gui-justify-content-center"
  32. style="background-color:#F8F8F8; padding:20rpx;">
  33. <input type="text" class="gui-editor-center"
  34. @blur="blur" maxlength="-1" :data-index="index"
  35. :focus="item.focusin" @input="graceEditorInput"
  36. :value="item.content" placeholder="请填写居中文本" />
  37. </view>
  38. <!-- 图片 -->
  39. <view v-else-if="item.type == 'img'"
  40. class="gui-editor-img-wrap">
  41. <image :src="item.content" class="gui-editor-img"
  42. :data-index="index" mode="aspectFit"></image>
  43. <view v-if="item.error"
  44. class="gui-editor-img-error gui-flex gui-columns gui-justify-content-center">
  45. <text class="gui-editor-img-error-text gui-block-text gui-text-center gui-icons">&#xe6a1; 上传失败,请重试</text>
  46. </view>
  47. </view>
  48. <!-- 引用 -->
  49. <view v-else-if="item.type == 'quote'">
  50. <textarea class="gui-editor-quote gui-border-box"
  51. maxlength="-1" @blur="blur"
  52. :data-index="index" @input="graceEditorInput" :focus="item.focusin"
  53. :value="item.content" placeholder="请输入引用内容" />
  54. </view>
  55. <!-- 代码 -->
  56. <view v-else-if="item.type == 'code'">
  57. <textarea class="gui-editor-quote gui-border-box"
  58. maxlength="-1" @blur="blur"
  59. style="height:300rpx;"
  60. :data-index="index" @input="graceEditorInput" :focus="item.focusin"
  61. :value="item.content" placeholder="请输入代码" />
  62. </view>
  63. <!-- 加粗 -->
  64. <view v-else-if="item.type == 'strong'">
  65. <textarea class="gui-editor-strong gui-border-box"
  66. :data-index="index" maxlength="-1" :focus="item.focusin"
  67. @input="graceEditorInput" :value="item.content" @blur="blur"
  68. placeholder="请输入加粗内容" />
  69. </view>
  70. <!-- 链接 -->
  71. <view v-else-if="item.type == 'link'">
  72. <input type="text" class="gui-editor-link gui-border-box"
  73. :focus="item.focusin"
  74. :data-index="index" @input="graceEditorInput" @blur="blur"
  75. :value="item.content" placeholder="请输入连接地址" />
  76. </view>
  77. <!-- 分割 -->
  78. <view v-else-if="item.type == 'spline'">
  79. <text class="gui-editor-spline gui-block-text"
  80. :data-index="index">● ● ●</text>
  81. </view>
  82. <!-- 功能 -->
  83. <view class="gui-flex gui-rows gui-justify-content-end gui-editor-item-btns-wrap">
  84. <view class="gui-editor-item-btns" hover-class="gui-tap"
  85. :data-index="index" @tap="moveup">
  86. <text class="gui-editor-item-btns-text gui-block-text gui-icons">&#xe654; 上移</text>
  87. </view>
  88. <view class="gui-editor-item-btns" hover-class="gui-tap"
  89. :data-index="index" @tap="movedown">
  90. <text class="gui-editor-item-btns-text gui-block-text gui-icons">&#xe603; 下移</text>
  91. </view>
  92. <view class="gui-editor-item-btns" @tap="deleteItem"
  93. hover-class="gui-tap" :data-index="index">
  94. <text class="gui-editor-item-btns-text gui-block-text gui-icons">&#xe636; 删除</text>
  95. </view>
  96. </view>
  97. </view>
  98. <view class="gui-margin-top-large"
  99. v-if="article.contents.length >= 1"></view>
  100. <!-- 选项类型选择 -->
  101. <view class="gui-flex gui-rows gui-align-items-center gui-space-between gui-editor-menus gui-border-box gui-border-t"
  102. :style="{paddingBottom:ipxHeight}">
  103. <text class="gui-editor-icons gui-icons" data-type="h3"
  104. @tap="graceEditorAddItem" style="font-size:46rpx;">&#xe64d;</text>
  105. <text class="gui-editor-icons gui-icons" data-type="txt"
  106. @tap="graceEditorAddItem" style="font-size:32rpx;">&#xe9e4;</text>
  107. <text class="gui-editor-icons gui-icons" data-type="center"
  108. @tap="graceEditorAddItem">&#xe621;</text>
  109. <text class="gui-editor-icons gui-icons" data-type="img"
  110. @tap="graceEditorAddItem">&#xe63d;</text>
  111. <text class="gui-editor-icons gui-icons" data-type="quote"
  112. @tap="graceEditorAddItem">&#xe620;</text>
  113. <text class="gui-editor-icons gui-icons" data-type="code"
  114. @tap="graceEditorAddItem" style="font-size:40rpx;">&#xe64e;</text>
  115. <text class="gui-editor-icons gui-icons" data-type="strong"
  116. style="font-size:32rpx;"
  117. @tap="graceEditorAddItem">&#xe640;</text>
  118. <text class="gui-editor-icons gui-icons gui-bold" data-type="link"
  119. @tap="graceEditorAddItem" style="font-size:38rpx;">&#xe61e;</text>
  120. <text class="gui-editor-icons gui-icons gui-bold" data-type="spline"
  121. @tap="graceEditorAddItem">&#xe61b;</text>
  122. </view>
  123. </view>
  124. </template>
  125. <script>
  126. export default{
  127. name : "gui-editor",
  128. data() {
  129. return {
  130. article : { title : '', contents:[] },
  131. ipxHeight : 0
  132. }
  133. },
  134. created:function(){
  135. // #ifdef MP
  136. try {
  137. var system = uni.getSystemInfoSync();
  138. system.model = system.model.replace(' ', '');
  139. system.model = system.model.toLowerCase();
  140. var res1 = res.model.indexOf('iphonex');
  141. if(res1 > 5){res1 = -1;}
  142. var res2 = res.model.indexOf('iphone1');
  143. if(res2 > 5){res2 = -1;}
  144. if(res1 != -1 || res2 != -1){
  145. this.ipxHeight = '60rpx';
  146. }
  147. } catch (e){return null;}
  148. // #endif
  149. },
  150. methods:{
  151. graceEditorAddItem : function(e){
  152. var type = e.currentTarget.dataset.type;
  153. if(type == 'img'){
  154. uni.chooseImage({
  155. success:(e)=>{
  156. var imgs = e.tempFilePaths;
  157. for(let i = 0; i < imgs.length; i++){
  158. this.article.contents.push({type:type,content:imgs[i], focusin:false});
  159. }
  160. }
  161. });
  162. }else if(type == 'spline'){
  163. this.article.contents.push({type:type,content:'',focusin:false});
  164. }else{
  165. this.article.contents.push({type:type,content:'',focusin:true});
  166. }
  167. },
  168. graceEditorInput : function(e){
  169. var index = e.currentTarget.dataset.index;
  170. var val = e.detail.value;
  171. this.article.contents[index].content = val;
  172. },
  173. deleteItem : function(e){
  174. var index = e.currentTarget.dataset.index;
  175. uni.showModal({
  176. title:"提示",
  177. content:"确定要删除项目吗?",
  178. success:(e)=>{
  179. if(e.confirm){this.article.contents.splice(index, 1);}
  180. }
  181. })
  182. },
  183. blur : function (e) {
  184. var index = Number(e.currentTarget.dataset.index);
  185. this.article.contents[index].focusin = false;
  186. this.article.contents.splice(index, 1, this.article.contents[index]);
  187. },
  188. moveup : function (e) {
  189. var index = Number(e.currentTarget.dataset.index);
  190. if(index > 0){
  191. this.article.contents[index] = this.article.contents.splice(index - 1, 1, this.article.contents[index])[0];
  192. }
  193. },
  194. movedown : function (e) {
  195. var index = Number(e.currentTarget.dataset.index);
  196. if(index < this.article.contents.length - 1){
  197. this.article.contents[index] = this.article.contents.splice(index + 1, 1, this.article.contents[index])[0];
  198. }
  199. },
  200. getData : function () {
  201. return this.article;
  202. },
  203. setError : function (index) {
  204. this.article.contents[index].error = true;
  205. this.article.contents.splice(index, 1, this.article.contents[index]);
  206. },
  207. setDefault : function (article) {
  208. this.article = article;
  209. }
  210. }
  211. }
  212. </script>
  213. <style scoped>
  214. .gui-editor{padding:10rpx 25rpx; background-color:#FFFFFF; border-radius:6rpx;}
  215. .gui-editor-title{padding:25rpx 0; width:690rpx; font-size:32rpx; line-height:50rpx; color:#2B2E3D;}
  216. .gui-editor-empty{line-height:120rpx; font-size:26rpx;}
  217. .gui-editor-icons{width:80rpx; height:80rpx; color:#898989; line-height:88rpx; text-align:center; font-size:34rpx; margin:5rpx 0;}
  218. .gui-editor-items{margin-top:20rpx;}
  219. .gui-editor-item-btns-wrap{padding:20rpx 5rpx;}
  220. .gui-editor-item-btns{width:100rpx; border-radius:30rpx; margin-left:20rpx; background-color:#898989;}
  221. .gui-editor-item-btns-text{text-align:center; font-size:20rpx; line-height:38rpx; border-radius:30rpx; color:#FFFFFF;}
  222. /* #ifndef APP-NVUE */
  223. .gui-editor-icons{display:block;}
  224. /* #endif */
  225. .gui-editor-txt{width:650rpx; font-size:26rpx; line-height:35rpx; padding:20rpx; height:150rpx;}
  226. .gui-editor-center{width:500rpx; text-align:center; font-size:28rpx; color:#333333; height:60rpx; line-height:60rpx;}
  227. .gui-editor-img-wrap{width:650rpx; height:320rpx; overflow:hidden; position:relative; font-size:0;}
  228. .gui-editor-img{width:650rpx; height:320rpx;}
  229. .gui-editor-quote{width:650rpx; font-size:26rpx; line-height:35rpx; padding:20rpx; background-color:#F9F9F9; height:100rpx;}
  230. .gui-editor-strong{width:650rpx; font-size:26rpx; line-height:35rpx; padding:20rpx; height:100rpx; font-weight:bold;}
  231. .gui-editor-link{width:650rpx; font-size:26rpx; line-height:35rpx; padding:20rpx; height:100rpx; color:#008AFF;}
  232. .gui-editor-spline{width:650rpx; line-height:60rpx; text-align:center; color:#8788A3; font-size:28rpx; opacity:0.6;}
  233. .gui-editor-img-error{position:absolute; width:650rpx; height:320rpx; left:0; top:0; background-color:rgba(0,0,0,0.8);}
  234. .gui-editor-img-error-text{font-size:28rpx; color:#FFFFFF;}
  235. </style>