赞
踩
前言
最近在开发一款微信小程序,用的Vue3+Ts+uni-app,目前已完成基本的文章发布、文章列表、文章详情、个人中心、首页展示、文章评论点赞等功能,不定期分享开发中的一些东西,希望能帮助到大家!
需求
类似于头条、知乎交流社区类的软件文章页面,可对该进行评论、点赞收藏,可发布表情评论和图片评论。
效果图如下
实现思路
文章最底部固定静态评论框展示以及右侧点赞收藏按钮,静态的评论框点击打开评论输入框,输入框使用textarea,自动聚焦,聚焦式自动弹出键盘,并且键盘自动把输入框顶上去,避免遮挡输入框!
最开始我想用uni-app中的popup组件,但是在popou中嵌入textarea时无法自动聚焦,就很尴尬,索性自己写一个。背景固定一个mask蒙层,评论框固定在页面最底部,层级比蒙层高。表情包按钮和图片按钮放在底部,表情按钮触发时隐藏键盘,并弹出表情选择列表,点击蒙层以及发布评论成功时则关闭评论输入框。
大致是这么一个实现的思路。
代码实现:如下
- // 组件:底部固定静态评论显示框,赞藏方法不在这儿展示,根据自己需求修改
- <template>
- <view class="bottom-comment">
- <!-- 左边静态输入框 -->
- <view class="disableinput" @click.stop="emit('articleCommentInputFocus', 1)">
- 良言一句三冬暖,恶语伤人六月寒。
- </view>
- <!-- 文章总评论 -->
- <view class="bottom-item">
- <text class="item-icon icon-a-44tubiao-112"></text>
- <text class="item-text">{{ 20 }}</text>
- </view>
- <!-- 文章总点赞 -->
- <view class="bottom-item">
- <text class="item-icon"></text>
- <text class="item-text">{{ 30 }}</text>
- </view>
- <!-- 文章总收藏 -->
- <view class="bottom-item">
- <text class="item-icon"></text>
- <text class="item-text">{{ 10 }}</text>
- </view>
- </view>
- </template>
-
- <script setup lang="ts">
-
- const emit = defineEmits([
- 'articleCommentInputFocus'
- ])
- </script>
-
- <style lang="scss">
- .bottom-comment {
- position: fixed;
- left: 0;
- bottom: 0;
- z-index: 80;
- width: 100vw;
- min-height: 8vh;
- background-color: #fff;
- box-shadow: 0 0 8rpx 4rpx #f7f7f7;
- display: flex;
- align-items: center;
- justify-content: space-between;
- padding: 0 28rpx;
-
- .disableinput {
- width: 54%;
- height: 70rpx;
- background-color: #f6f6f6;
- border-radius: 35rpx;
- margin-right: 30rpx;
- font-size: 20rpx;
- color: #767676;
- padding-left: 16rpx;
- display: flex;
- align-items: center;
- }
-
- .bottom-item {
- flex: 1;
- display: flex;
- margin-right: 10rpx;
- align-items: center;
-
- .item-icon {
- font-size: 38rpx;
- padding-right: 10rpx;
- }
-
- .isUp {
- color: $uni-color-primary;
- }
-
- .item-text {
- font-size: 30rpx;
- }
- }
- }
- </style>
- <template>
- <!-- 蒙层 -->
- <view clas="c-mask" v-if="showInputPop" class="c-mask" @click.stop="emit('closeInputPop')"
- @touchmove.stop.prevent="emit('disableScroll')">
- </view>
- <view class="popup-comment" v-if="showInputPop">
- <view class="comment-input-wrap">
- <view class="comment-textarea-box" @touchmove.stop.prevent="emit('disableScroll')">
- <textarea v-model="commentParams.content" class="comment-textarea" :maxlength="600" :focus="replyFocus"
- :placeholder="customPlaceholder" :show-confirm-bar="false" @focus="commentInputFocus" @blur="commentInputBlur"
- :adjust-position="true" :cursor-spacing="400" :cursor="cursorIndex" @input="inputFocusChange" :fixed="true" />
- <view class="limit">{{ commentParams.content?.length || 0 }} / 600</view>
- </view>
- <view class="image-list">
- <view class="image-item" v-for="(item, index) in commentImages" :key="index">
- <image class="image" :src="item" mode="aspectFill" @click.stop="previewCommentImage(item)"></image>
- <uni-icons class="icon-close" @click.stop="deleteOneCommentImage(index)" type="clear" size="20"
- color="#red"></uni-icons>
- </view>
- </view>
- <view class="relase-btn">
- <!-- 表情 和 图片 -->
- <view class="emoji-image">
- <!-- 选择上传图片 -->
- <view class="as-image icon-a-44tubiao-81" hover-class="checkActive" :hover-stay-time="100"
- @click="selectMediaImage"></view>
- <!-- 表情 -->
- <view class="emoji icon-biaoqing-xue" hover-class="checkActive" :hover-stay-time="100" @click="openEmoji"
- v-if="!showEmoji"></view>
- <!-- 键盘 -->
- <view v-else class="keyboard icon-a-44tubiao-155" hover-class="checkActive" :hover-stay-time="100"
- @click="openKeyboard">
- </view>
- </view>
- <!-- 发布 -->
- <view class="relase" @click.stop="commentCommit" hover-class="button-hover" :hover-stay-time="100">发布</view>
- </view>
- <list class="emoji-data" :show-scrollbar="false" v-if="showEmoji">
- <view v-for="(item, index) in emojiDataList" :key="index" class="emoji-item" hover-class="checkActive"
- :hover-stay-time="100" @click.stop="tuchCurrentEmoji(item)">
- <text class="emoj_conn">{{ item }}</text>
- </view>
- </list>
- </view>
- </view>
- </template>
-
- <script setup lang="ts">
- import { ref, nextTick } from 'vue'
- import { uploadImages } from '@/utils/public'
-
- const props = defineProps({
- showInputPop: {
- type: Boolean,
- default: false,
- },
- })
-
- const emit = defineEmits([
- 'closeInputPop',
- 'disableScroll',
- 'update:showInputPop',
- ])
-
- // 新增评论入参
- const commentParams = ref({ content: '' } as any)
-
- // 评论上传的图片
- const commentImages = ref<string[]>([])
-
- // 点击回复控制textarea的聚焦
- const replyFocus = ref(false)
- // 默认的提示内容
- const customPlaceholder = ref<string>('输入评论')
- // 是否显示表情包
- const showEmoji = ref(false)
- // 表情包列表
- const emojiDataList = ref([
- '声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/683533推荐阅读
相关标签
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。