YEditor2.vue 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. // releaseArticle.vue
  2. <template>
  3. <view class="ashome-article">
  4. <!-- 自定义导航栏 page.json中 设置 "navigationStyle": "custom"-->
  5. <view class="relase-top" :style="{ marginTop: safeAreaInsets!.top + 'px' }">
  6. <uni-icons type="closeempty" size="26" @click="closeExchange"></uni-icons>
  7. <view class="titles">发布文章</view>
  8. <text></text>
  9. </view>
  10. <!-- 发布文章 -->
  11. <view class="release-article">
  12. <view class="article-img">
  13. <uni-file-picker :limit="9" mode="grid" :image-styles="imageStyles" file-mediatype="image" :auto-upload="false"
  14. @select="selectImage" ref="filePickerRef" v-model="imageList" @delete="deletea"></uni-file-picker>
  15. </view>
  16. <!-- 输入标题 -->
  17. <view class="article-title">
  18. <input class="title" type="text" placeholder="输入标题更受欢迎哦~" :maxlength="30" v-model="articleTitle"
  19. @input="inputTitle(1)" />
  20. </view>
  21. <!-- 输入文章内容 -->
  22. <view class="article-content">
  23. <!-- 富文本 -->
  24. <richTextEditor v-model:value="articleContent" />
  25. </view>
  26. </view>
  27. <!-- 发布按钮 -->
  28. <view class="release-btn" hover-class="button-hover" @tap="releaseExchange">
  29. 发布
  30. </view>
  31. </view>
  32. <uni-popup ref="alertDialogRef" type="dialog">
  33. <uni-popup-dialog type="info" cancelText="取消" confirmText="确认" title="提示" content="有内容未发布,是否确认退出?"
  34. @confirm="dialogConfirm"></uni-popup-dialog>
  35. </uni-popup>
  36. </template>
  37. <script setup>
  38. import {
  39. ref
  40. } from 'vue'
  41. import {
  42. onLoad
  43. } from '@dcloudio/uni-app'
  44. // 图片上传
  45. import {
  46. uploadImages
  47. } from '@/utils/public'
  48. import richTextEditor from "./richTextEditor.vue"
  49. // 获取屏幕边界到安全区域距离
  50. const {
  51. safeAreaInsets
  52. } = uni.getSystemInfoSync()
  53. // 弹出层组件
  54. const alertDialogRef = ref()
  55. // 发布文章参数
  56. const articleParams = ref({})
  57. // 标题
  58. const articleTitle = ref < string > ('')
  59. // 内容
  60. const articleContent = ref < string > ('')
  61. // 上传图片组件
  62. const filePickerRef = ref()
  63. // 上传完毕后的图片列表
  64. const imageList = ref([])
  65. // 上传图标样式
  66. const imageStyles = ref({
  67. height: 100, // 边框高度
  68. width: 100, // 边框宽度
  69. })
  70. // 加载
  71. onLoad((option: any) => {})
  72. const inputTitle = (type: number) => {
  73. if (type === 1) {
  74. // 校验输入的标题,如果字数超过30个,则不能继续输入,然后提示最多只能输入30个字
  75. if (articleTitle.value.length > 30) {
  76. uni.showToast({
  77. title: '最多可输入30个字',
  78. icon: 'none',
  79. })
  80. articleTitle.value = articleTitle.value.substring(0, 30)
  81. }
  82. } else {
  83. if (articleContent.value.length > 1000) {
  84. uni.showToast({
  85. title: '最多可输入1000个字',
  86. icon: 'none',
  87. })
  88. articleContent.value = articleContent.value.substring(0, 1000)
  89. }
  90. }
  91. }
  92. // 关闭发布文章页面
  93. const closeExchange = () => {
  94. alertDialogRef.value && alertDialogRef.value.open()
  95. }
  96. // 确认关闭
  97. const dialogConfirm = () => {
  98. uni.navigateBack({
  99. delta: 1,
  100. })
  101. }
  102. // 立即发表
  103. const releaseExchange = async () => {
  104. // 标题和内容必填
  105. if (!articleTitle.value || !articleContent.value) {
  106. uni.showToast({
  107. title: '标题和内容必填!',
  108. icon: 'none',
  109. })
  110. return
  111. }
  112. uni.showToast({
  113. title: '发布成功',
  114. icon: 'success',
  115. })
  116. setTimeout(() => {
  117. uni.navigateBack()
  118. }, 500)
  119. }
  120. // 选择完图片
  121. const selectImage = (e) => {
  122. const tempFiles = e.tempFiles
  123. // 处理每张选中的图片
  124. tempFiles.forEach(async (tempFile) => {
  125. await uploadImages(tempFile, imageList.value)
  126. })
  127. }
  128. // 删除
  129. const deletea = (e) => {
  130. console.log('删除图片', e)
  131. }
  132. </script>
  133. <style scoped lang="scss">
  134. .ashome-article {
  135. height: 100%;
  136. background-color: #fff;
  137. display: flex;
  138. flex-direction: column;
  139. .relase-top {
  140. display: flex;
  141. justify-content: space-between;
  142. align-items: center;
  143. padding: 0 30rpx;
  144. height: 100rpx;
  145. background-color: #fff;
  146. // border-bottom: 1px solid #f5f5f5;
  147. color: #3d3d3d;
  148. font-size: 32rpx;
  149. .titles {
  150. font-weight: bold;
  151. }
  152. }
  153. .release-article {
  154. flex: 1;
  155. padding: 32rpx;
  156. .article-img {
  157. margin-bottom: 20rpx;
  158. // /deep/ .file-picker__box {}
  159. :deep(.uni-file-picker) {
  160. .uni-file-picker__container {
  161. overflow-x: scroll;
  162. white-space: nowrap;
  163. display: block !important;
  164. .file-picker__box {
  165. display: inline-block !important;
  166. .file-picker__box-content {
  167. .file-picker__progress {
  168. display: none;
  169. }
  170. }
  171. }
  172. }
  173. }
  174. }
  175. .article-title {
  176. margin-bottom: 20rpx;
  177. .title {
  178. display: block;
  179. // height: 46rpx;
  180. // font-weight: bold;
  181. font-size: 36rpx;
  182. }
  183. }
  184. .article-content {
  185. height: 62vh;
  186. // overflow: auto;
  187. width: 100%;
  188. .content {
  189. // height: calc(100vh - 500rpx);
  190. height: 100%;
  191. width: 100%;
  192. display: block;
  193. font-size: 28rpx;
  194. }
  195. }
  196. }
  197. // 发布按钮 固定定到底部
  198. .release-btn {
  199. position: fixed;
  200. bottom: 10%;
  201. right: 30rpx;
  202. height: 100rpx;
  203. width: 100rpx;
  204. display: flex;
  205. z-index: 99;
  206. border-radius: 50%;
  207. background-color: #a1d8ba;
  208. font-size: 28rpx;
  209. font-weight: bold;
  210. align-items: center;
  211. justify-content: center;
  212. color: #fff;
  213. box-shadow: 0px 0px 8px 0px rgba(0, 0, 0, 0.3) !important;
  214. }
  215. .button-hover {
  216. background-color: #97cbb0;
  217. }
  218. }
  219. </style>