
vue3聊天网页版|Vue3.x+ElementPlus仿QQ|微信聊天界面
项目简介
一周前有给大家分享一个vue3版手机端聊天实战项目。今天给大家带来的是基于vue3.x+饿了么vue3组件库开发的pc桌面端仿制微信+QQ界面聊天|朋友圈实例。
vue3-webchat 聊天实例支持发送图文消息、预览视频/图片、网址查看、拖拽发送图片、红包/朋友圈
等功能。
QQ皮肤效果
微信皮肤效果
使用技术
- 编辑器:VScode
- MVVM框架:Vue3.0.5
- 状态管理:Vuex4.x
- 页面路由:Vue-Router@4
- UI组件库:element-plus (饿了么桌面端vue3组件库)
- 弹窗组件:v3layer(基于vue3自定义弹窗组件)
- 美化滚动条:v3scroll(基于vue3自定义滚动条组件)
- 字体图标:阿里iconfont图标
项目结构
vue3.x全局模态框组件
v3layer基于vue3开发的仿layer.js自定义弹出层组件。应用于整个项目弹窗功能。
之前有过一篇详细介绍,感兴趣的可以去看看。
vue3自定义组件系列:vue3.0全局弹窗组件|对话框组件
vue3.x全局滚动条组件
v3scroll基于vue3开发的仿el-scrollbar自定义美化滚动条组件。在各个模块页面均有使用。
vue3自定义组件系列:vue3.0自定义pc端模拟滚动条组件
vue3入口页配置
在main.js中引入一些公共组件/样式、路由地址及vuex配置。
/**
* Vue3.0入口配置
*/
import { createApp } from 'vue'
import App from './App.vue'
// 引入vuex和地址路由
import store from './store'
import router from './router'
// 引入公共组件
import Plugins from './plugins'
/* 引入公共样式 */
import '@assets/fonts/iconfont.css'
import '@assets/css/reset.css'
import '@assets/css/layout.css'
const app = createApp(App)
app.use(store)
app.use(router)
app.use(Plugins)
app.mount('#app')
vue3实现60s倒计时+表单验证
/**
* @Desc vue3表单验证
* @Time andy by 2021-01
* @About Q:282310962 wx:xy190310
*/
<script>
import { reactive, toRefs, inject, getCurrentInstance } from 'vue'
export default {
components: {},
setup() {
const { ctx } = getCurrentInstance()
const v3layer = inject('v3layer')
const utils = inject('utils')
const formObj = reactive({})
const data = reactive({
vcodeText: '获取验证码',
disabled: false,
time: 0,
})
const VTips = (content) => {
v3layer({
content: content, layerStyle: 'background:#ff5151;color:#fff;', time: 2
})
}
const handleSubmit = () => {
if(!formObj.tel){
VTips('手机号不能为空!')
}else if(!utils.checkTel(formObj.tel)){
VTips('手机号格式不正确!')
}else if(!formObj.pwd){
VTips('密码不能为空!')
}else if(!formObj.vcode){
VTips('验证码不能为空!')
}else{
ctx.$store.commit('SET_TOKEN', utils.setToken());
ctx.$store.commit('SET_USER', formObj.tel);
// ...
}
}
// 60s倒计时
const handleVcode = () => {
if(!formObj.tel) {
VTips('手机号不能为空!')
}else if(!utils.checkTel(formObj.tel)) {
VTips('手机号格式不正确!')
}else {
data.time = 60
data.disabled = true
countDown()
}
}
const countDown = () => {
if(data.time > 0) {
data.vcodeText = '获取验证码('+ data.time +')'
data.time--
setTimeout(countDown, 1000)
}else{
data.vcodeText = '获取验证码'
data.time = 0
data.disabled = false
}
}
return {
formObj,
...toRefs(data),
handleSubmit,
handleVcode
}
}
}
</script>
毛玻璃效果
大家看到项目中的背景是被模糊虚化的,使用了svg filter来实现。
<!-- //模糊化效果 -->
<div class="vui__bgblur">
<svg width="100%" height="100%" class="blur-svg" viewBox="0 0 1920 875" preserveAspectRatio="none">
<filter id="blur_mkvvpnf"><feGaussianBlur in="SourceGraphic" stdDeviation="50"></feGaussianBlur></filter>
<image :xlink:href="store.state.skin" x="0" y="0" width="100%" height="100%" externalResourcesRequired="true" xmlns:xlink="http://www.w3.org/1999/xlink" style="filter:url(#blur_mkvvpnf)" preserveAspectRatio="none"></image>
</svg>
<div class="blur-cover"></div>
</div>
图片/视频预览
图片预览使用element-plus中的image组件就能轻易实现。
<el-image class="img__pic"
:src="item.imgsrc"
:preview-src-list="[item.imgsrc]"
hide-on-click-modal
/>
视频弹窗预览是使用v3layer组件实现。
<!-- 视频播放器 -->
<v3-layer v-model="isShowVideoPlayer"
title="<i class='iconfont icon-bofang'></i> 视频预览"
layerStyle="background:#f9f9f9"
opacity=".2"
:area="['550px', '450px']"
xclose
resize
:maximize="true"
>
<video class="vplayer" ref="playerRef" autoplay preload="auto" controls
:src="videoList.videosrc"
:poster="videoList.imgsrc"
x5-video-player-fullscreen="true"
webkit-playsinline="true"
x-webkit-airplay="true"
playsinline="true"
x5-playsinline
/>
</v3-layer>
网址链接预览
通过v3layer iframe弹窗来实现预览网址链接。
const handleMsgClicked = (e) => {
let target = e.target
// 链接
if(target.tagName === 'A') {
e.preventDefault()
// console.log('触发点击链接事件!')
v3layer({
type: 'iframe',
title: '<i class="iconfont icon-link"></i> 网址预览',
content: target.href,
opacity: .2,
area: ['860px', '600px'],
xclose: true,
resize: true,
maximize: true
})
}
// 图片
if (target.tagName === 'IMG' && target.classList.contains('img-view')) {
// ...
}
}
发红包效果
发红包弹窗也是使用v3layer来实现的。通过引入外部页面,自定义插槽引入即可。
import SendRedPacket from './redPacket.vue'
<!-- ……发红包模板 -->
<v3-layer v-model="isShowSendRedPacketLayer"
layerStyle="background:#fff8f4"
opacity=".2"
:area="['400px', '480px']"
xclose
xcolor="#ffdccb"
drag='.ntDrag__head'
>
<SendRedPacket />
</v3-layer>
好了,以上就是基于vue3开发网页端聊天实例的一些分享,希望对大家有些帮助哈!
链接:https://juejin.cn/post/6920777347620667405
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
项目简介
一周前有给大家分享一个vue3版手机端聊天实战项目。今天给大家带来的是基于vue3.x+饿了么vue3组件库开发的pc桌面端仿制微信+QQ界面聊天|朋友圈实例。
vue3-webchat 聊天实例支持发送图文消息、预览视频/图片、网址查看、拖拽发送图片、红包/朋友圈
等功能。
QQ皮肤效果
微信皮肤效果
使用技术
- 编辑器:VScode
- MVVM框架:Vue3.0.5
- 状态管理:Vuex4.x
- 页面路由:Vue-Router@4
- UI组件库:element-plus (饿了么桌面端vue3组件库)
- 弹窗组件:v3layer(基于vue3自定义弹窗组件)
- 美化滚动条:v3scroll(基于vue3自定义滚动条组件)
- 字体图标:阿里iconfont图标
项目结构
vue3.x全局模态框组件
v3layer基于vue3开发的仿layer.js自定义弹出层组件。应用于整个项目弹窗功能。
之前有过一篇详细介绍,感兴趣的可以去看看。
vue3自定义组件系列:vue3.0全局弹窗组件|对话框组件
vue3.x全局滚动条组件
v3scroll基于vue3开发的仿el-scrollbar自定义美化滚动条组件。在各个模块页面均有使用。
vue3自定义组件系列:vue3.0自定义pc端模拟滚动条组件
vue3入口页配置
在main.js中引入一些公共组件/样式、路由地址及vuex配置。
/**
* Vue3.0入口配置
*/
import { createApp } from 'vue'
import App from './App.vue'
// 引入vuex和地址路由
import store from './store'
import router from './router'
// 引入公共组件
import Plugins from './plugins'
/* 引入公共样式 */
import '@assets/fonts/iconfont.css'
import '@assets/css/reset.css'
import '@assets/css/layout.css'
const app = createApp(App)
app.use(store)
app.use(router)
app.use(Plugins)
app.mount('#app')
vue3实现60s倒计时+表单验证
/**
* @Desc vue3表单验证
* @Time andy by 2021-01
* @About Q:282310962 wx:xy190310
*/
<script>
import { reactive, toRefs, inject, getCurrentInstance } from 'vue'
export default {
components: {},
setup() {
const { ctx } = getCurrentInstance()
const v3layer = inject('v3layer')
const utils = inject('utils')
const formObj = reactive({})
const data = reactive({
vcodeText: '获取验证码',
disabled: false,
time: 0,
})
const VTips = (content) => {
v3layer({
content: content, layerStyle: 'background:#ff5151;color:#fff;', time: 2
})
}
const handleSubmit = () => {
if(!formObj.tel){
VTips('手机号不能为空!')
}else if(!utils.checkTel(formObj.tel)){
VTips('手机号格式不正确!')
}else if(!formObj.pwd){
VTips('密码不能为空!')
}else if(!formObj.vcode){
VTips('验证码不能为空!')
}else{
ctx.$store.commit('SET_TOKEN', utils.setToken());
ctx.$store.commit('SET_USER', formObj.tel);
// ...
}
}
// 60s倒计时
const handleVcode = () => {
if(!formObj.tel) {
VTips('手机号不能为空!')
}else if(!utils.checkTel(formObj.tel)) {
VTips('手机号格式不正确!')
}else {
data.time = 60
data.disabled = true
countDown()
}
}
const countDown = () => {
if(data.time > 0) {
data.vcodeText = '获取验证码('+ data.time +')'
data.time--
setTimeout(countDown, 1000)
}else{
data.vcodeText = '获取验证码'
data.time = 0
data.disabled = false
}
}
return {
formObj,
...toRefs(data),
handleSubmit,
handleVcode
}
}
}
</script>
毛玻璃效果
大家看到项目中的背景是被模糊虚化的,使用了svg filter来实现。
<!-- //模糊化效果 -->
<div class="vui__bgblur">
<svg width="100%" height="100%" class="blur-svg" viewBox="0 0 1920 875" preserveAspectRatio="none">
<filter id="blur_mkvvpnf"><feGaussianBlur in="SourceGraphic" stdDeviation="50"></feGaussianBlur></filter>
<image :xlink:href="store.state.skin" x="0" y="0" width="100%" height="100%" externalResourcesRequired="true" xmlns:xlink="http://www.w3.org/1999/xlink" style="filter:url(#blur_mkvvpnf)" preserveAspectRatio="none"></image>
</svg>
<div class="blur-cover"></div>
</div>
图片/视频预览
图片预览使用element-plus中的image组件就能轻易实现。
<el-image class="img__pic"
:src="item.imgsrc"
:preview-src-list="[item.imgsrc]"
hide-on-click-modal
/>
视频弹窗预览是使用v3layer组件实现。
<!-- 视频播放器 -->
<v3-layer v-model="isShowVideoPlayer"
title="<i class='iconfont icon-bofang'></i> 视频预览"
layerStyle="background:#f9f9f9"
opacity=".2"
:area="['550px', '450px']"
xclose
resize
:maximize="true"
>
<video class="vplayer" ref="playerRef" autoplay preload="auto" controls
:src="videoList.videosrc"
:poster="videoList.imgsrc"
x5-video-player-fullscreen="true"
webkit-playsinline="true"
x-webkit-airplay="true"
playsinline="true"
x5-playsinline
/>
</v3-layer>
网址链接预览
通过v3layer iframe弹窗来实现预览网址链接。
const handleMsgClicked = (e) => {
let target = e.target
// 链接
if(target.tagName === 'A') {
e.preventDefault()
// console.log('触发点击链接事件!')
v3layer({
type: 'iframe',
title: '<i class="iconfont icon-link"></i> 网址预览',
content: target.href,
opacity: .2,
area: ['860px', '600px'],
xclose: true,
resize: true,
maximize: true
})
}
// 图片
if (target.tagName === 'IMG' && target.classList.contains('img-view')) {
// ...
}
}
发红包效果
发红包弹窗也是使用v3layer来实现的。通过引入外部页面,自定义插槽引入即可。
import SendRedPacket from './redPacket.vue'
<!-- ……发红包模板 -->
<v3-layer v-model="isShowSendRedPacketLayer"
layerStyle="background:#fff8f4"
opacity=".2"
:area="['400px', '480px']"
xclose
xcolor="#ffdccb"
drag='.ntDrag__head'
>
<SendRedPacket />
</v3-layer>
好了,以上就是基于vue3开发网页端聊天实例的一些分享,希望对大家有些帮助哈!
链接:https://juejin.cn/post/6920777347620667405
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

个人发卡网源码|个人发卡网系统带搭建平台方法
个人发卡网源码系统是一个即时服务软件系统(SaaS)的解决方案,它使工程团队能够在云中实现和优化CI和CD,并帮助小型和成长中的团队开发从简单的web应用程序到现代微服务架构的一切,以实现快速、安全和频繁的代码交付。
个人发卡网源码系统演示及下载搭建方法:点击获取

个人发卡网源码系统特点:
1、自动发卡一键掌控
您是希望立即为您设置所有内容,还是要自定义您的环境和工作流?CloudBees CodeShip允许开发人员选择最适合他们的路径,以最大限度地提高生产力,并让团队随着时间的推移而发展。
2、在几分钟内完全工作
使用CloudBees CodeShip的交钥匙环境和简单的UI,您可以在不到五分钟的时间内完成构建和部署。从那里,您可以发展到更复杂的工作流,并随着项目的增长而配置为代码。
3、与所有事物集成
从部署到通知到代码覆盖,再到安全扫描和内部scm,CloudBees CodeShip允许您与任何工具、服务或云集成,以实现组织的完美工作流。
4、保证速度和可靠性
您需要您的构建运行速度快,易于优化和调试,并且始终可用。我们构建了具有弹性和高性能的基础设施,并构建了CloudBees代码,使闪电般快速的构建速度易于实现。
5、由于专用的单租户AWS实例,性能和安全性都得到了保证
选择我们为您提供的AWS实例的大小、CPU和内存。由于您的代码只运行在一个实例上,而您没有与其他人共享实例,因此我们可以保证高安全性,并确保您不会受到其他团队运行的CPU过多构建的影响。
个人发卡网源码系统一种新的支付形式,C开发人员可以编写它,让您可以做两件事:
一是检索汇编对象,它表示正在编译的所有用户代码。这个对象可以被检查,您可以编写与正在编译的代码的语法和语义模型一起工作的代码,就像今天的分析器一样。
二是生成可添加到汇编对象。换句话说,您可以在编译代码时提供额外的源代码作为编译的输入。
将这两个因素结合起来,使源生成器变得如此有用。您可以使用编译器在编译期间构建的所有丰富的元数据检查用户代码,然后将C代码重新发送到基于所分析数据的同一编译中!如果您熟悉Roslyn分析器,那么可以将源代码生成器看作可以发出C源代码的分析器。
个人发卡网源码系统是一个.NET标准2.0程序集,它与任何分析仪. 它在可以加载和运行.NET标准组件的环境中可用。
现在您已经知道了什么是源生成器,让我们来看看它们可以改进的一些场景。
使用个人发卡网源码系统可以做的事情远不止是这样简单:
自动实现带有附加属性的类的接口,例如INotifyProperty已更改
根据从中检查的数据生成设置文件SourceGeneratorContext
将类中的值序列化为JSON字符串等。
另外,我们还有一个GitHub上提供的一组示例你可以自己试试。
如前所述,我们正致力于在实际应用中更好地编写和使用个人发卡网源码系统,例如添加模板、允许无缝的智能感知和导航、调试以及提高生成源文件时visualstudio的响应能力和性能。
个人发卡网源码系统是一个即时服务软件系统(SaaS)的解决方案,它使工程团队能够在云中实现和优化CI和CD,并帮助小型和成长中的团队开发从简单的web应用程序到现代微服务架构的一切,以实现快速、安全和频繁的代码交付。
个人发卡网源码系统演示及下载搭建方法:点击获取
个人发卡网源码系统特点:
1、自动发卡一键掌控
您是希望立即为您设置所有内容,还是要自定义您的环境和工作流?CloudBees CodeShip允许开发人员选择最适合他们的路径,以最大限度地提高生产力,并让团队随着时间的推移而发展。
2、在几分钟内完全工作
使用CloudBees CodeShip的交钥匙环境和简单的UI,您可以在不到五分钟的时间内完成构建和部署。从那里,您可以发展到更复杂的工作流,并随着项目的增长而配置为代码。
3、与所有事物集成
从部署到通知到代码覆盖,再到安全扫描和内部scm,CloudBees CodeShip允许您与任何工具、服务或云集成,以实现组织的完美工作流。
4、保证速度和可靠性
您需要您的构建运行速度快,易于优化和调试,并且始终可用。我们构建了具有弹性和高性能的基础设施,并构建了CloudBees代码,使闪电般快速的构建速度易于实现。
5、由于专用的单租户AWS实例,性能和安全性都得到了保证
选择我们为您提供的AWS实例的大小、CPU和内存。由于您的代码只运行在一个实例上,而您没有与其他人共享实例,因此我们可以保证高安全性,并确保您不会受到其他团队运行的CPU过多构建的影响。
个人发卡网源码系统一种新的支付形式,C开发人员可以编写它,让您可以做两件事:
一是检索汇编对象,它表示正在编译的所有用户代码。这个对象可以被检查,您可以编写与正在编译的代码的语法和语义模型一起工作的代码,就像今天的分析器一样。
二是生成可添加到汇编对象。换句话说,您可以在编译代码时提供额外的源代码作为编译的输入。
将这两个因素结合起来,使源生成器变得如此有用。您可以使用编译器在编译期间构建的所有丰富的元数据检查用户代码,然后将C代码重新发送到基于所分析数据的同一编译中!如果您熟悉Roslyn分析器,那么可以将源代码生成器看作可以发出C源代码的分析器。
个人发卡网源码系统是一个.NET标准2.0程序集,它与任何分析仪. 它在可以加载和运行.NET标准组件的环境中可用。
现在您已经知道了什么是源生成器,让我们来看看它们可以改进的一些场景。
使用个人发卡网源码系统可以做的事情远不止是这样简单:
自动实现带有附加属性的类的接口,例如INotifyProperty已更改
根据从中检查的数据生成设置文件SourceGeneratorContext
将类中的值序列化为JSON字符串等。
另外,我们还有一个GitHub上提供的一组示例你可以自己试试。
如前所述,我们正致力于在实际应用中更好地编写和使用个人发卡网源码系统,例如添加模板、允许无缝的智能感知和导航、调试以及提高生成源文件时visualstudio的响应能力和性能。
收起阅读 »
安卓 app 视频闪退问题
第一个问题: 视频图片列表页分页加载,只要有一个视频预加载报错,安卓端app就会闪退,ios正常
第二个问题:onPageScroll 用户滚动时播放当前的视频,视频过多安卓端app就会闪退,ios正常
onLoad(options) {
//创建视频上下文
this.videoContent = uni.createVideoContext
},
onPageScroll(e){
const that = this
if(that.tabId=="dynamic" && app.globalData.platformObj.platform=='ios'){
if(that.playId){
that.videoContent(that.playId).pause(); //暂停上一次播放的视频
that.playId = ''
}
clearTimeout(that.debounce)
that.debounce = setTimeout(()=>{
that.dynListData.forEach(item=>{
if(item.type==2){
let scrTop = parseInt(e.scrollTop),top = parseInt(item.top) + parseInt(item.height);
if(scrTop<top && scrTop+300>top){
console.log('播放用户当前滑动的视频')
let currentId = 'video' + item.id;// 获取当前视频id
that.playId = currentId
that.videoContent(currentId).play(); //播放当前视频
// return
}
}
})
}, 500)
}
}
第一个问题: 视频图片列表页分页加载,只要有一个视频预加载报错,安卓端app就会闪退,ios正常
第二个问题:onPageScroll 用户滚动时播放当前的视频,视频过多安卓端app就会闪退,ios正常
onLoad(options) {
//创建视频上下文
this.videoContent = uni.createVideoContext
},
onPageScroll(e){
const that = this
if(that.tabId=="dynamic" && app.globalData.platformObj.platform=='ios'){
if(that.playId){
that.videoContent(that.playId).pause(); //暂停上一次播放的视频
that.playId = ''
}
clearTimeout(that.debounce)
that.debounce = setTimeout(()=>{
that.dynListData.forEach(item=>{
if(item.type==2){
let scrTop = parseInt(e.scrollTop),top = parseInt(item.top) + parseInt(item.height);
if(scrTop<top && scrTop+300>top){
console.log('播放用户当前滑动的视频')
let currentId = 'video' + item.id;// 获取当前视频id
that.playId = currentId
that.videoContent(currentId).play(); //播放当前视频
// return
}
}
})
}, 500)
}
}

uniCloud: 如何切换云服务商?
1. 创建新项目并启用uniCloud
创建uniapp项目时, 如果勾选了启用uniCloud,会创建一个uniCloud云开发环境。
目前有3个云服务商, 分别是 阿里云 、腾讯云、支付宝小程序云(HBuilderX 3.97+), 在创建项目可以选择某个云服务商。
1.1 创建项目
1.2 关联云服务空间
新建项目后, 需要关联相应的云服务空间。
选中uniCloud目录,右键菜单【关联云服务空间或项目】,在弹出的窗口上,选择服务空间。。
注意: 阿里云云开发环境只能显示 已经创建的阿里云云服务空间, 腾讯云云开发环境只能显示 已经创建的腾讯云云服务空间。
2. 已有的项目,创建/切换云开发环境
HBuilderX项目管理器,选中项目,右键菜单【创建uniCloud云开发环境】,点击腾讯云或阿里云。
当然,也可以通过直接修改文件夹名称
的方式来切换云服务厂商。如下项目:已绑定阿里云服务空间,uniCloud目录为uniCloud-aliyun
, 直接修改目录名为uniCloud-tcb
3. uniCloud同时绑定多个云服务商
Note: 如果同时使用阿里云和腾讯云的两个云服务商, 参考 uniCloud同时绑定多个云服务商
4. 被授权空间(协作者)说明
注意事项:在被授权的应用上,才能看到被授权的服务空间。
5. 切换云厂商时如需迁移数据库请参考:在云厂商之间迁移数据
1. 创建新项目并启用uniCloud
创建uniapp项目时, 如果勾选了启用uniCloud,会创建一个uniCloud云开发环境。
目前有3个云服务商, 分别是 阿里云 、腾讯云、支付宝小程序云(HBuilderX 3.97+), 在创建项目可以选择某个云服务商。
1.1 创建项目
1.2 关联云服务空间
新建项目后, 需要关联相应的云服务空间。
选中uniCloud目录,右键菜单【关联云服务空间或项目】,在弹出的窗口上,选择服务空间。。
注意: 阿里云云开发环境只能显示 已经创建的阿里云云服务空间, 腾讯云云开发环境只能显示 已经创建的腾讯云云服务空间。
2. 已有的项目,创建/切换云开发环境
HBuilderX项目管理器,选中项目,右键菜单【创建uniCloud云开发环境】,点击腾讯云或阿里云。
当然,也可以通过直接修改文件夹名称
的方式来切换云服务厂商。如下项目:已绑定阿里云服务空间,uniCloud目录为uniCloud-aliyun
, 直接修改目录名为uniCloud-tcb
3. uniCloud同时绑定多个云服务商
Note: 如果同时使用阿里云和腾讯云的两个云服务商, 参考 uniCloud同时绑定多个云服务商
4. 被授权空间(协作者)说明
注意事项:在被授权的应用上,才能看到被授权的服务空间。
5. 切换云厂商时如需迁移数据库请参考:在云厂商之间迁移数据
收起阅读 »
app热更新升级页面不是最新的,解决办法
问题:
app热更新后页面不是最新的,还是之前的, 关闭重新打开app后页面显示正常
如还有不明白免费解答
微信 13236336468
qq号 282675853
解决办法:
1.升级成功后 设置热更新标识
//设置wgt升级标志,变量名随意
uni.setStorageSync("wgtrestart",1);
//重新启动
plus.runtime.restart();
2.创建空页面, 作用跳转使用
pages/home/empty
onload 里面跳转到主页面
3.主页面
onload 里面检测 wgtrestart值为真,
关闭所有页面再跳转到 pages/home/empty
自动跳转到主页面页面已正常,所有改动立即生效
var wgtrestart =uni.getStorageSync('wgtrestart')
uni.removeStorageSync('wgtrestart')
if(wgtrestart){
//ts.$showToast('wgtrestart')
//关闭所有页面
uni.reLaunch({
url: '/pages/home/empty', //设置首页面无效
})
}
4.缺点升级重启瞬间需要短暂跳转一个临时页面
问题:
app热更新后页面不是最新的,还是之前的, 关闭重新打开app后页面显示正常
如还有不明白免费解答
微信 13236336468
qq号 282675853
解决办法:
1.升级成功后 设置热更新标识
//设置wgt升级标志,变量名随意
uni.setStorageSync("wgtrestart",1);
//重新启动
plus.runtime.restart();
2.创建空页面, 作用跳转使用
pages/home/empty
onload 里面跳转到主页面
3.主页面
onload 里面检测 wgtrestart值为真,
关闭所有页面再跳转到 pages/home/empty
自动跳转到主页面页面已正常,所有改动立即生效
var wgtrestart =uni.getStorageSync('wgtrestart')
uni.removeStorageSync('wgtrestart')
if(wgtrestart){
//ts.$showToast('wgtrestart')
//关闭所有页面
uni.reLaunch({
url: '/pages/home/empty', //设置首页面无效
})
}
4.缺点升级重启瞬间需要短暂跳转一个临时页面
收起阅读 »
uni.chooseLocation地图显示不出来
H5
升级到新版本后打包上传到后台,结果有人反馈选择地址界面显示不出来,找了很久发现是HBuilderX版本得问题。
当前版本:HBuilderX 3.0.4.20201231,本地测试选择定位地图不显示。
同事版本:HBuilderX 2.9.8 ,正常显示。
切回历史版本就可以解决此问题

美团饿了么外卖CPS小程序 外卖分销小程序
外卖分销小程序,自定义用户级别,自定义分佣比例!
今年最赚钱的小程序!
我们都知道,目前两家巨头饿了么和美团点外卖都可以获得返现,其中饿了么是返利6%,美团是返利3-5%,具体要根据活动来。
也就是说按正常一个人用户点餐,你可以获得每笔外卖的CPS返利佣金,而且外卖的用户粘性极高,已经成了很多淘客的首选。
从核心功能方面来说,主要还是实现自动跟单返利,获得CPS交易佣金、自定义用户等级和分佣比例,自定义用户的升级条件,引导用户完成自购和分享。这样的公众号和小程序渠道,在微信生态下是非常好的裂变,可以迅速获得用户群做社群运营。
喜欢的找我 q 691618012
看下小程序页面:
外卖分销小程序,自定义用户级别,自定义分佣比例!
今年最赚钱的小程序!
我们都知道,目前两家巨头饿了么和美团点外卖都可以获得返现,其中饿了么是返利6%,美团是返利3-5%,具体要根据活动来。
也就是说按正常一个人用户点餐,你可以获得每笔外卖的CPS返利佣金,而且外卖的用户粘性极高,已经成了很多淘客的首选。
从核心功能方面来说,主要还是实现自动跟单返利,获得CPS交易佣金、自定义用户等级和分佣比例,自定义用户的升级条件,引导用户完成自购和分享。这样的公众号和小程序渠道,在微信生态下是非常好的裂变,可以迅速获得用户群做社群运营。
喜欢的找我 q 691618012
看下小程序页面:

千万不要买QQ号为:392716797的源码,这个人就是个骗子
上传者:作者: 392716797@qq.com
湖南邵阳人肖敏 QQ昵称:永不言败☞澎湃小伙
在本社区上传有 : 微信支付(原生小程序),抽签小程序(原生小程序),小红书(原生小程序),美团外卖(原生小程序),外卖优惠券(原生小程序),消费优惠券汇总(原生小程序),美团微信登录。
该作者抓取别人小程序源码放在上面,要么是挂羊头卖狗肉,发一个垃圾源码给你,要么是中途让你各种加钱,反正各种坑
上传者:作者: 392716797@qq.com
湖南邵阳人肖敏 QQ昵称:永不言败☞澎湃小伙
在本社区上传有 : 微信支付(原生小程序),抽签小程序(原生小程序),小红书(原生小程序),美团外卖(原生小程序),外卖优惠券(原生小程序),消费优惠券汇总(原生小程序),美团微信登录。
该作者抓取别人小程序源码放在上面,要么是挂羊头卖狗肉,发一个垃圾源码给你,要么是中途让你各种加钱,反正各种坑
收起阅读 »
uniapp跳转第三方应用后, 粘贴板设置的内容丢失
// 第一步
uni.setClipboardData({
data: this.info[key]['value'],
})
// 第二步
plus.runtime.openURL(this.info[key].value, (res) => {
console.log(res)
uni.showToast({
title: '打开失败',
icon: 'none'
})
})
代码如上图,
第一步复制成功, 在第三方应用内粘贴, 粘贴不了内容
如果只执行第一步, 然后手动打开应用,去粘贴. 则有内容
// 第一步
uni.setClipboardData({
data: this.info[key]['value'],
})
// 第二步
plus.runtime.openURL(this.info[key].value, (res) => {
console.log(res)
uni.showToast({
title: '打开失败',
icon: 'none'
})
})
代码如上图,
第一步复制成功, 在第三方应用内粘贴, 粘贴不了内容
如果只执行第一步, 然后手动打开应用,去粘贴. 则有内容

uniapp map组件iOS APP nvue@updated @regionchange事件的触发机制
MAP组件文档上确实对于@updated @regionchange在APP及APP-NVUE的支持情况没有写(也就是应该不支持),但实际其实是支持的,并且在安卓端支持得蛮好的,这里就不详细讨论安卓的部分了。
iOS那边就比较怪异了,目前测下来,这俩事件也确实都是可以触发的。
btw这边先提一句:安卓和iOS两边regionchange事件的参数是有略微差别的,安卓那边来获取拖拽起始和结束是这样:
onRegionChange(e) {
swich(e.type) {
case 'begin':
//处理起始事件
case 'end':
//处理结束事件
}
}
而iOS这边是这样:
onRegionChange(e) {
swich(e.detail.type) {
case 'begin':
//处理起始事件
case 'end':
//处理结束事件
}
}
扯回主要想讲的怪异行为,也就是这俩事件的触发条件在iOS端还挺特殊的
- 必须等@updated事件触发过之后,@regionchange事件才可以被触发,不然在地图上拖动完全不会触发@regionchange事件;也就是:一旦成功触发过@updated事件,@regionchange事件就可以完全正常监听了
- 然而奇怪的就是@updated事件并不是次次都能在刚进入页面加载完地图后就自动触发
2.1. 目前的尝试1:在地图显示出来之后快速拖动地图使地图移动较远距离(慢慢拖动就完全没用,应该是快速移动到一片地图完全没有预载好的区块导致重新渲染)可以触发@updated
2.2. 目前的尝试2:在地图显示出来之后缩放地图(大概是scale值发生了变化,慢慢缩放也可以,通过代码修改scale值也可以)也可以触发@updated
2.3. 目前的尝试3:在地图显示出来之后通过代码改变地图中心到很远的地方并不能触发与2.1相同的结果(通过setTimeout延迟触发也不行,通过mapContext.moveToLocation和直接改变map组件的latitude和longitude都不行)
总结:要在iOS的nvue中完美使用map组件的@regionchange需要先成功触发@updated,可以参考以下代码:
<map :id="mapId" :latitude="latitude" :longitude="longitude" :scale="mapScale"
@regionchange="onMapRegionChange" @updated="onMapFinish" />
data: function() {
return {
// 深圳的经纬度
latitude: 22.547,
longitude: 114.085947,
mapId: 'whatever',
mapScale: 17,
}
},
methods: {
onMapRegionChange: function(e) {
let type = '';
const { platform } = uni.getSystemInfoSync();
switch (platform) {
case 'android':
type = e.type;
break;
case 'ios':
type = e.detail.type;
break;
}
if (type === 'begin') {
// 处理拖拽开始时的逻辑
}
else if (type === 'end') {
// 处理拖拽结束时的逻辑
}
},
onMapFinish: function() {
console.log('现在可以开始监听@regionchange了');
},
},
onLoad: function() {
uni.showLoading();
uni.getLocation({
type: 'gcj02',
success: async (data) => {
uni.hideLoading();
console.log('getLocation', data);
this.mapScale = 18;
this.latitude = data.latitude;
this.longitude = data.longitude;
},
fail: (e) => {
uni.hideLoading();
console.log('getLocation fail', e);
this.mapScale = 18;
},
});
}
P.S. 仅代表HBuilderX 3.0.5,iOS 14以上,其他情况也许会略有不同
MAP组件文档上确实对于@updated @regionchange在APP及APP-NVUE的支持情况没有写(也就是应该不支持),但实际其实是支持的,并且在安卓端支持得蛮好的,这里就不详细讨论安卓的部分了。
iOS那边就比较怪异了,目前测下来,这俩事件也确实都是可以触发的。
btw这边先提一句:安卓和iOS两边regionchange事件的参数是有略微差别的,安卓那边来获取拖拽起始和结束是这样:
onRegionChange(e) {
swich(e.type) {
case 'begin':
//处理起始事件
case 'end':
//处理结束事件
}
}
而iOS这边是这样:
onRegionChange(e) {
swich(e.detail.type) {
case 'begin':
//处理起始事件
case 'end':
//处理结束事件
}
}
扯回主要想讲的怪异行为,也就是这俩事件的触发条件在iOS端还挺特殊的
- 必须等@updated事件触发过之后,@regionchange事件才可以被触发,不然在地图上拖动完全不会触发@regionchange事件;也就是:一旦成功触发过@updated事件,@regionchange事件就可以完全正常监听了
- 然而奇怪的就是@updated事件并不是次次都能在刚进入页面加载完地图后就自动触发
2.1. 目前的尝试1:在地图显示出来之后快速拖动地图使地图移动较远距离(慢慢拖动就完全没用,应该是快速移动到一片地图完全没有预载好的区块导致重新渲染)可以触发@updated
2.2. 目前的尝试2:在地图显示出来之后缩放地图(大概是scale值发生了变化,慢慢缩放也可以,通过代码修改scale值也可以)也可以触发@updated
2.3. 目前的尝试3:在地图显示出来之后通过代码改变地图中心到很远的地方并不能触发与2.1相同的结果(通过setTimeout延迟触发也不行,通过mapContext.moveToLocation和直接改变map组件的latitude和longitude都不行)
总结:要在iOS的nvue中完美使用map组件的@regionchange需要先成功触发@updated,可以参考以下代码:
<map :id="mapId" :latitude="latitude" :longitude="longitude" :scale="mapScale"
@regionchange="onMapRegionChange" @updated="onMapFinish" />
data: function() {
return {
// 深圳的经纬度
latitude: 22.547,
longitude: 114.085947,
mapId: 'whatever',
mapScale: 17,
}
},
methods: {
onMapRegionChange: function(e) {
let type = '';
const { platform } = uni.getSystemInfoSync();
switch (platform) {
case 'android':
type = e.type;
break;
case 'ios':
type = e.detail.type;
break;
}
if (type === 'begin') {
// 处理拖拽开始时的逻辑
}
else if (type === 'end') {
// 处理拖拽结束时的逻辑
}
},
onMapFinish: function() {
console.log('现在可以开始监听@regionchange了');
},
},
onLoad: function() {
uni.showLoading();
uni.getLocation({
type: 'gcj02',
success: async (data) => {
uni.hideLoading();
console.log('getLocation', data);
this.mapScale = 18;
this.latitude = data.latitude;
this.longitude = data.longitude;
},
fail: (e) => {
uni.hideLoading();
console.log('getLocation fail', e);
this.mapScale = 18;
},
});
}
P.S. 仅代表HBuilderX 3.0.5,iOS 14以上,其他情况也许会略有不同
收起阅读 »
uniapp对接网易七鱼客服
网易七鱼客服发布免费插件链接 https://ext.dcloud.net.cn/plugin?id=3818
对接过程中有问题可私信!
网易七鱼客服发布免费插件链接 https://ext.dcloud.net.cn/plugin?id=3818
对接过程中有问题可私信!

在 uniapp 中使用 tailwindcss
崮生的 uni-app 最佳实践
tailwindcss
! 值得注意的是微信小程序并不支持一些 CSS 选择器还有他的 wxss 不支持 \
所以如果直接使用 tailwindcss 会报错类似于图中这样的错 :
- 幸运的是 tailwindcss 支持自定义
separator
- 但是在类名中包含
.
的又需要\.
这样的形式去声明类名而且貌似没有办法自定义这个, 所以在这种情况下我复制了'tailwindcss/defaultConfig'
中的配置将\
全部改成了_
这种语法 wxss 也不支持.... 这里不是 CSS 类名修改可以避免的,就只能去
corePlugins
禁用相关的插件- 禁用了
space
divideWidth
divideStyle
divideOpacity
- 禁用了
- CSS 的类名是允许以数字开头的,但需要进行转义,而
screens
配置中有一个2xl
这个 key 会在类名的最前面出现,于是 tailwind 转义为\32xl
这里就又有了\
所以这里也需要 改一下 - 本 demo 对 tailwind 进行了如上定制,所以在使用的时候需要注意这些点
- 建议使用这里 tailwindcss 类名提示 链接中的插件
效果
相关 commit 记录
- 引入 tailwindcss 并在 微信开发者工具中正常跑起来的改动
b3c7085
- refactor(tailwind): 更好的配置文件
- fix(tailwind): 加回响应式配置
崮生的 uni-app 最佳实践
tailwindcss
! 值得注意的是微信小程序并不支持一些 CSS 选择器还有他的 wxss 不支持 \
所以如果直接使用 tailwindcss 会报错类似于图中这样的错 :
- 幸运的是 tailwindcss 支持自定义
separator
- 但是在类名中包含
.
的又需要\.
这样的形式去声明类名而且貌似没有办法自定义这个, 所以在这种情况下我复制了'tailwindcss/defaultConfig'
中的配置将\
全部改成了_
这种语法 wxss 也不支持.... 这里不是 CSS 类名修改可以避免的,就只能去
corePlugins
禁用相关的插件- 禁用了
space
divideWidth
divideStyle
divideOpacity
- 禁用了
- CSS 的类名是允许以数字开头的,但需要进行转义,而
screens
配置中有一个2xl
这个 key 会在类名的最前面出现,于是 tailwind 转义为\32xl
这里就又有了\
所以这里也需要 改一下 - 本 demo 对 tailwind 进行了如上定制,所以在使用的时候需要注意这些点
- 建议使用这里 tailwindcss 类名提示 链接中的插件
效果
相关 commit 记录
- 引入 tailwindcss 并在 微信开发者工具中正常跑起来的改动
b3c7085
- refactor(tailwind): 更好的配置文件
- fix(tailwind): 加回响应式配置
收起阅读 »