uni-app 121转发功能实现

Posted 2019ab

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了uni-app 121转发功能实现相关的知识,希望对你有一定的参考价值。

/pages/chat/chat-list/chat-list.vue

<template>
	<view class="page">
		<!-- 导航栏 -->
		<free-nav-bar title="选择" showBack :showRight="true">
			<free-main-button :name="muliSelect ? '发送 ('+selectCount+')' : '多选'" slot="right" @click="handlenNav"></free-main-button>
		</free-nav-bar>
		<!-- 搜索框 -->
		<view class="p-3 bg-light position-fixed left-0 right-0" :style="'top:'+top+'px;'" style="z-index: 2;">
			<input type="text" value="" v-model="keyword" placeholder="搜索" class="bg-white rounded" placeholder-class="text-center" style="height: 80rpx;"/>
		</view>
		<view style="height:140rpx;"></view>
		
		<free-list-item v-for="(item,index) in allList" :key="index" :title="item.name" :cover="item.avatar || '/static/images/userpic.png'" showRight :showRightIcon="false" @click="selectItem(item)">
			<view v-if="muliSelect" slot="right" class="border rounded-circle flex align-center" style="width: 40rpx;height: 40rpx;" >
				<view v-if="item.checked" class="main-bg-color rounded-circle" style="width: 39rpx;height: 39rpx;">	
				</view>
			</view>
		</free-list-item>
		
		<view style="height:100rpx;" class="flex align-center justify-center" v-if="keyword !== '' && searchList.length === 0">
			<text class="font text-light-muted">暂无搜索结果</text>
		</view>
		<free-confirm ref="confirm" title="发送给:">
			<scroll-view scroll-x="true" class="flex" :show-scrollbar='false'>
				<view class="mr-1" v-for="i in 10" :key="i">
					<free-avatar src="/static/images/mail/friend.png" size="60"></free-avatar>
				</view>
			</scroll-view>
			<view class="my-3 bg-light rounded p-2">
				<text class="font text-light-muted">[个人名片] 昵称</text>
			</view>
			<input type="text" value="" class="border-bottom font-md" style="height: 60rpx;" placeholder="给朋友留言"  />
		</free-confirm>
	</view>
</template>

<script>
	import freeNavBar from '@/components/free-ui/free-nav-bar.vue';
	import freeMainButton from '@/components/free-ui/free-main-button.vue';
	import freeListItem from '@/components/free-ui/free-list-item.vue';
	import freeConfirm from '@/components/free-ui/free-confirm.vue';
	import freeAvatar from '@/components/free-ui/free-avatar.vue';
	import  mapState  from 'vuex';
	export default 
		components:
			freeNavBar,
			freeMainButton,
			freeListItem,
			freeConfirm,
			freeAvatar
		,
		data() 
			return 
				keyword:'',
				muliSelect:false,
				top:0,
				list:[]
			
		,
		computed:
			...mapState(
				chatList:state=>state.user.chatList,
				chat:state=>state.user.chat,
			),
			// 最终列表
			allList()
				return this.keyword === '' ? this.list : this.searchList;
			,
			// 搜索结果列表
			searchList()
				if(this.keyword === '')
					return [];
				
				return this.list.filter(item=>
					return item.username.indexOf(this.keyword) !== -1;
				)
			,
			// 选中列表
			selectList()
				return this.list.filter(item=>item.checked)
			,
			// 选中数量
			selectCount()
				return this.selectList.length;
			
		,
		methods: 
			// 点击导航栏
			handlenNav()
				if(!this.muliSelect)
					return this.muliSelect = true;
				
				// 发送
				console.log('发送')
			,
			// 选中、取消选中
			selectItem(item)
				// 选中、取消选中
				if(this.muliSelect)
					// 选中
					if(!item.checked && (this.selectCount === 9))
						// 限制选中数量
						return uni.showToast(
								title:'最多选中9个',
								icon:'none'
						)
					
					// 取消选中
					return item.checked = !item.checked;
				
				// 发送
				this.$refs.confirm.show((close)=>
					console.log('点击了确定');
					close();
				);
			
		,
		onLoad() 
			let res = uni.getSystemInfoSync();
			this.top = res.statusBarHeight + uni.upx2px(90);
			this.list = this.chatList.map(item=>
				return 
					...item,
					checked:false
				
			)
		
	
</script>

<style>

</style>

components/free-ui/free-popup.vue

<template>
	<div style="z-index:9999;overflow:hidden;" v-if="status">
		<!-- 蒙版 -->
		<view v-if="mask" class="position-fixed top-0 left-0 right-0 bottom-0 z-index" :style="getMaskColor" @click="hide"></view>
		<!-- 弹出框内容 -->
		<div ref="popup" class="position-fixed free-animated z-index" :class="getBodyClass" :style="getBodyStyle">
			<slot></slot>
		</div>
	</div>
</template>

<script>
	// #ifdef APP-PLUS-NVUE
	const animation = weex.requireModule('animation')
	// #endif
	export default 
		props: 
			// 是否开启蒙版颜色
			maskColor: 
				type: Boolean,
				default: false
			,
			// 是否开启蒙版
			mask:
				type:Boolean,
				default:true
			,
			// 是否居中
			center:
				type:Boolean,
				default:false
			,
			// 是否处于底部
			bottom:
				type:Boolean,
				default:false
			,
			// 弹出层内容宽度
			bodyWidth:
				type:Number,
				default:0
			,
			// 弹出层内容高度
			bodyHeight:
				type:Number,
				default:0
			,
			bodyBgColor:
				type:String,
				default:"bg-white"
			,
			transformOrigin:
				type:String,
				default:"left top"
			,
			// tabbar高度
			tabbarHeight:
				type:Number,
				default:0
			
		,
		data() 
			return 
				status: false,
				x:-1,
				y:1,
				maxX:0,
				maxY:0
			
		,
		mounted() 
			try 
			    const res = uni.getSystemInfoSync();
				this.maxX = res.windowWidth - uni.upx2px(this.bodyWidth)
				this.maxY = res.windowHeight - uni.upx2px(this.bodyHeight) - uni.upx2px(this.tabbarHeight)
			 catch (e) 
			    // error
			
		,
		computed: 
			getMaskColor() 
				let i = this.maskColor ? 0.5 : 0
				return `background-color: rgba(0,0,0,$i);` 
			,
			getBodyClass()
				if(this.center)
					return 'left-0 right-0 bottom-0 top-0 flex align-center justify-center'
				
				let bottom = this.bottom ? 'left-0 right-0 bottom-0' : 'rounded border'
				return `$this.bodyBgColor $bottom`
			,
			getBodyStyle()
				let left = this.x > -1 ? `left:$this.xpx;` : ''
				let top = this.y > -1 ? `top:$this.ypx;` : ''
				return left + top
			
		,
		methods:
			show(x = -1 ,y = -1)
				if (this.status) 
					return;
				
				this.x = (x > this.maxX) ? this.maxX : x
				this.y = (y > this.maxY) ? this.maxY : y
				this.status = true
				// #ifdef APP-PLUS-NVUE
				this.$nextTick(()=>
					animation.transition(this.$refs.popup, 
					    styles: 
					        transform: 'scale(1,1)',
							transformOrigin:this.transformOrigin,
							opacity:1
					    ,
					    duration: 100, //ms
					    timingFunction: 'ease',
					    , function () 
					       console.log('动画执行结束');
					    )
				)
				// #endif
				
			,
			hide()
				this.$emit('hide')
				// #ifdef APP-PLUS-NVUE
				animation.transition(this.$refs.popup, 
				styles: 
					transform: 'scale(0,0)',
					transformOrigin:this.transformOrigin,
					opacity:0
				,
				duration: 100, //ms
				timingFunction: 'ease',
				, ()=> 
					this.status = false
				   console.log('动画执行结束');
				)
				// #endif
				// #ifndef APP-PLUS-NVUE
				this.status = false
				// #endif
			
		
	
</script>

<style scoped>
	.free-animated
		/* #ifdef APP-PLUS-NVUE */
		transform: scale(0,0);
		opacity: 0;
		/* #endif */
	
	.z-index
		/* #ifndef APP-NVUE */
		z-index: 9999;
		/* #endif */
	
</style>

pages/chat/chat/chat.vue

<template>
	<view>

		<!-- 导航栏 -->
		<free-nav-bar :title="detail.name" :noreadnum="totalNoreadnum" showBack>
			<free-icon-button slot="right" 
			:icon="'\\ue6fd'"
			@click="openChatSet"></free-icon-button>
		</free-nav-bar>
		
		<!-- 聊天内容区域 -->
		<scroll-view scroll-y class="bg-light position-fixed left-0 right-0 px-3" style="bottom: 105rpx;box-sizing: border-box;" :style="chatBodyBottom" :show-scrollbar="false" :scroll-into-view="scrollIntoView" :scroll-with-animation="true"
		@click="clickPage">
			
			<!-- 聊天信息列表组件 -->
			<view v-for="(item,index) in list" :key="index" 
			:id="'chatItem_'+index">
				<free-chat-item :item="item" :index="index" ref="chatItem"
				:pretime=" index > 0 ? list[index-1].create_time : 0"
				@long="long" @preview="previewImage" 
				:shownickname="currentChatItem.shownickname"
				></free-chat-item>
			</view>
			
		</scroll-view>
		
		<!-- #ifdef APP-PLUS-NVUE -->
		<div v-if="mode === 'action' || mode === 'emoticon'"
		class="position-fixed top-0 right-0 left-0"
		:style="'bottom:'+maskBottom+'px;'"
		@click="clickPage"></div>
		<!-- #endif -->
		
		<!-- 底部输入框 -->
		<view class="position-fixed left-0 right-0 border-top flex align-center" style="background-color: #F7F7F6;height: 105rpx;" 
		:style="'bottom:'+KeyboardHeight+'px;'">
			<free-icon-button v-if="mode === 'audio'"  @click="changeVoiceOrText"><text class="iconfont font-lg">&#xe607;</text></free-icon-button>
			<free-icon-button v-else @click="changeVoiceOrText"><text class="iconfont font-lg">&#xe606;</text></free-icon-button>
			<view class="flex-1">
				<view v-if="mode === 'audio'" class="rounded flex align-center justify-center" style="height: 80rpx;" :class="isRecording?'bg-hover-light':'bg-white'" @touchstart="voiceTouchStart" @touchend="voiceTouchEnd" @touchcancel="voiceTouchCancel" @touchmove="voiceTouchMove">
					<text class="font">isRecording ? '松开 结束':'按住 说话'</text>
				</view>
				
				<textarea v-else fixed

以上是关于uni-app 121转发功能实现的主要内容,如果未能解决你的问题,请参考以下文章

uni-app 122转发功能实现

uni-app 124转发功能实现

uni-app 179转发名片功能

uni-app 实现拨打电话功能(android)

uni-app 实现拨打电话功能(android)

小程序各种功能代码片段整理---持续更新