gui-editor.vue 9.5 KB

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