
scroll-view没有效果
小纪录
1.问题:
在使用scroll-view的时候没有效果拖拽不动
2.解决方式:
scroll-view是需要加高度或者宽度的,加在外层的view或内层的view是没有用的。
3.示例代码:
<view>
<scroll-view scroll-y="true" :scroll-top="0" style="height: 500upx;">
<view></view>
</scroll-view>
</view>
小纪录
1.问题:
在使用scroll-view的时候没有效果拖拽不动
2.解决方式:
scroll-view是需要加高度或者宽度的,加在外层的view或内层的view是没有用的。
3.示例代码:
<view>
<scroll-view scroll-y="true" :scroll-top="0" style="height: 500upx;">
<view></view>
</scroll-view>
</view>

我给自己的uniapp添加了多端多扩展名管理代码的能力
因为我们计划支持多端开发,每个平台的小程序都会上线,而很多接口的参数需要自己处理,有时候兼容性问题更是让人头大,不知不觉项目内的条件编译高达数百处,维护起来极为困难,因此,我在阅读了《京喜小程序最佳实践》后发现多平台多端文件是个不错的功能,于是自己加进来了,效果是我引入文件```javascript
import xxx from '@/platform/xxx/index'
然后通过写的webpack插件,比如我运行的支付宝小程序,运行时会解析为```javascript
@/platform/xxx/index.mp-alipay
这样就可以尽情书写js了,而单个Vue文件内不会参杂过多的js部分条件编译
因为我们计划支持多端开发,每个平台的小程序都会上线,而很多接口的参数需要自己处理,有时候兼容性问题更是让人头大,不知不觉项目内的条件编译高达数百处,维护起来极为困难,因此,我在阅读了《京喜小程序最佳实践》后发现多平台多端文件是个不错的功能,于是自己加进来了,效果是我引入文件```javascript
import xxx from '@/platform/xxx/index'
然后通过写的webpack插件,比如我运行的支付宝小程序,运行时会解析为```javascript
@/platform/xxx/index.mp-alipay
这样就可以尽情书写js了,而单个Vue文件内不会参杂过多的js部分条件编译
收起阅读 »
解决uni.request不支持发送FormData格式数据的办法,兼容所有端
- uni-app非H5端不支持FormData,因此uni.request无法发送multipart/form-data格式数据
- 而uni.uploadFile可以发送FormData格式数据,因此转为uni.uploadFile实现:
uni.uploadFile({
url: "您的接口地址",
filePath: '123', // 随便填,不为空即可
name: '123', // 随便填,不为空即可
header: header, // 可以加access_token等
formData: data, // 接口参数,json格式,底层自动转为FormData的格式数据
complete: (res)=>{
console.error(res);
}
})
此方法兼容所有端
- uni-app非H5端不支持FormData,因此uni.request无法发送multipart/form-data格式数据
- 而uni.uploadFile可以发送FormData格式数据,因此转为uni.uploadFile实现:
uni.uploadFile({
url: "您的接口地址",
filePath: '123', // 随便填,不为空即可
name: '123', // 随便填,不为空即可
header: header, // 可以加access_token等
formData: data, // 接口参数,json格式,底层自动转为FormData的格式数据
complete: (res)=>{
console.error(res);
}
})
此方法兼容所有端
收起阅读 »
在使用uview中的ScrollList横向滚动列表时,不显示指示器,而且数据显示不完全
遇到问题:
在使用uview中的ScrollLis横向关滚动列表时出现了以下问题

循环的view显示不全,而且指示器也不见了,改换uniapp自带的scroll-view也无效
找到原因:
经过一段时间摸索,终于找到了原因:
在使用uview的布局时,我是按照24等分来分的,这就导致了view冲出了屏幕,导致显示不全,而且无指示器
解决办法:
在使用view时将布局按照12等分来分割,又可以愉快的继续开发了。
遇到问题:
在使用uview中的ScrollLis横向关滚动列表时出现了以下问题
循环的view显示不全,而且指示器也不见了,改换uniapp自带的scroll-view也无效
找到原因:
经过一段时间摸索,终于找到了原因:
在使用uview的布局时,我是按照24等分来分的,这就导致了view冲出了屏幕,导致显示不全,而且无指示器
解决办法:
在使用view时将布局按照12等分来分割,又可以愉快的继续开发了。

uni-app 选择和上传非图像、视频文件 —— APP上传
如果你根据文档发现uni.uploadFile(上传非图像、视频文件)后,发现在APP上上传失败了,也没有报错。后端收到请求,只有请求头,无法获取数据。
那么试试将 filePath 和 name 改为使用 files 。
如果你使用 files 报错 [Vue warn]: Error in v-on handler: "TypeError: Cannot read property 'indexOf' of undefined"。
请注意:files 中的对象的 uri 不是 url,注意最后一个字母不是 l ,是 i 。
如果你根据文档发现uni.uploadFile(上传非图像、视频文件)后,发现在APP上上传失败了,也没有报错。后端收到请求,只有请求头,无法获取数据。
那么试试将 filePath 和 name 改为使用 files 。
如果你使用 files 报错 [Vue warn]: Error in v-on handler: "TypeError: Cannot read property 'indexOf' of undefined"。
请注意:files 中的对象的 uri 不是 url,注意最后一个字母不是 l ,是 i 。

骚操作,nvue/weex获取文字行数,实现展开收起
HTML部分
一行text组件,一行textarea组件,共用一个class 这个class里很简单,只有字体大小和颜色
<text class="content" :style="`lines:${lines};text-overflow: ellipsis;`">{{overview}}</text>
<textarea class="content" :value="overview" style="height: 0rpx;" disabled @linechange = "linechange" ></textarea>
<view class="showmore" @click="showMoreing" v-if="showMore">
<text class="topic-content" style="color: #303133;" >展开</text>
</view>
<view class="closemore" v-if="!showMore&& lineCount>3">
<text class="topic-content" style="color: #303133;" >收起</text>
</view>
给textarea高度设为0 实现了display:none的效果 组件不显示,但是@linechange事件 却接收到了行数
linechange(event){
console.log(event)
const lineCount = event.detail.lineCount //行数
this.lineCount = lineCount
if(lineCount>3){ //如果大于3行,显示展开阅读
this.showMore = true
}
},
showMoreing(){
this.lines = 1000
this.showMore =false
},
closeMoreing(){
this.lines = 3
this.showMore =true
}
点击展开按钮,把lines改为1000 或者是 this.lineCount 然后把按钮隐藏。
点击收齐按钮,把lines改为3行,显示收起按钮
HTML部分
一行text组件,一行textarea组件,共用一个class 这个class里很简单,只有字体大小和颜色
<text class="content" :style="`lines:${lines};text-overflow: ellipsis;`">{{overview}}</text>
<textarea class="content" :value="overview" style="height: 0rpx;" disabled @linechange = "linechange" ></textarea>
<view class="showmore" @click="showMoreing" v-if="showMore">
<text class="topic-content" style="color: #303133;" >展开</text>
</view>
<view class="closemore" v-if="!showMore&& lineCount>3">
<text class="topic-content" style="color: #303133;" >收起</text>
</view>
给textarea高度设为0 实现了display:none的效果 组件不显示,但是@linechange事件 却接收到了行数
linechange(event){
console.log(event)
const lineCount = event.detail.lineCount //行数
this.lineCount = lineCount
if(lineCount>3){ //如果大于3行,显示展开阅读
this.showMore = true
}
},
showMoreing(){
this.lines = 1000
this.showMore =false
},
closeMoreing(){
this.lines = 3
this.showMore =true
}
点击展开按钮,把lines改为1000 或者是 this.lineCount 然后把按钮隐藏。
点击收齐按钮,把lines改为3行,显示收起按钮

云转码源码|php云转码系统源码-m3u8切片程序-html5播放器
虽然基于云的转码传统上是小型初创企业的领域,并专注于低价值媒体,但过去两年,专业级、高可靠性的应用程序激增。这是由于运营商一方面需要应对爆炸式增长的内容量和不断增长的期望,另一方面供应商能够提供不断下降的成本以及改进的自动化和可靠性。云转码源码是一种高度可扩展、易用且经济高效的方法,可供开发者和企业将视频和音频文件从源格式转换(或“转换”)为可在智能手机、平板电脑和PC等设备上播放的版本。
云转码源码及演示:c.yunzes.top/zm
云转码源码特征:
多区域基础设施
云转码源码可在全球范围内提供服务,以使文件传输更快且更具成本效益。
没有供应商锁定
您可以简单地将您的转码文件放入我们的云存储或使用任何 S3 兼容的云
简易 API 和 SDK
使用干净美观的 API 和简单的 SDK 对您的视频进行转码。将视频集成到您的应用程序从未如此简单快捷。
GPU转码
我们的 GPU 转码器支持超快转码。您可以简单地从设置中启用它。
实时通知
获得有关正在运行的转码作业更新的实时通知。如果作业成功,则将信息报告回您的服务器,失败。
即用即付定价
只需支付用于转码视频的资源和时间。您按每分钟的视频输出计费。 如果您在设备之间切换以观看您喜爱的 OTT 系列、视频频道或电影,那么您并不孤单。事实上,报告显示他们平均每天至少在两台设备上进行流媒体播放。在手机上暂停视频,然后在电视上从同一位置恢复视频似乎很典型。但从提供商的角度来看,无论设备如何,保持一致的体验都至关重要。
易于上手
云转码源码不需要您在设置、管理或维护视频处理基础设施方面付出任何努力。它可以通过一个完整的文档和对开发人员友好的 Web API 轻松与您的后端系统集成。只需创建编码作业、指定源视频文件的位置和所需的处理设置即可开始。
利用云
作为基于云的产品,云转码源码具有高度可扩展性和运营效率,能够并行编码数百个视频。它会根据您的需求自动扩展资源并保证最大的可用性。它会定期更新以引入新的功能和技术。
具有成本效益
云转码源码是一种 SaaS 产品,您只需为所消费的内容付费。这种基于使用的方法非常适合任何企业规模。该服务与您一起发展,无需大量前期成本。此外,我们没有规定任何最低转码量或每月承诺。
多 DRM 保护
云转码源码与 DRM 原生集成,以支持多种 DRM 技术。它通过为每个视频质量级别和音轨启用单独的加密密钥来提供最佳保护。
端到端工作流程
云转码源码是原生集成到转码中的众多产品之一。该平台提供一整套用于构建视频业务的工具,以及用于构建视频平台、内容管理和保护的端到端解决方案。
视频处理工作流程(插入图片)
跨设备优化以获得最佳观看体验取决于多个变量,主要变量是编码格式,因为兼容性因设备和用例而异。编码解决方案在让视频为多屏流媒体做好准备方面发挥着重要作用。它通过将视频转码和打包成自适应流格式来实现这一点,以确保跨设备和平台的体验的兼容性和一致性。由于其带来的简单性、效率和灵活性,基于云的视频编码方法的采用正在兴起。此外,视频行业是一个不断发展的空间,新格式和技术不时被引入。
多个编解码器
编码服务使用称为编解码器的压缩技术压缩您的视频以进行流式传输。这些编解码器使用一种称为有损压缩的技术,该技术丢弃任何不必要的数据以创建更小的文件大小。每个编解码器都包含两个元素,一个用于压缩视频以进行传输的编码器和一个用于重建视频以进行播放的解码器。但是,在视频压缩过程中需要取得平衡,因为太多会导致视频质量下降,而较低的压缩会带来可怕的缓冲。这种困境导致了多个编解码器服务于不同的用例。最流行的视频编解码器包括:
H.264 (AVC)
H.265 (HEVC)
H.266 (VVC)
AV1
VP9
H.264 是最流行的视频编解码器,几乎与市场上的任何设备或平台兼容。但是,H264 最适合低延迟流式传输,并且在 4K 或高动态范围 (HDR) 内容上表现不佳。H.265 通过提高压缩效率作为高分辨率视频和实时流媒体的解决方案而出现。尽管如此,由于许可费用的不确定性,H.265 并没有像其前身那样被广泛采用。不过,它确实在大多数智能电视上都有强大的影响力。H.266 于 2020 年推出,也被称为多功能视频编码 (VVC),因为它承诺提供各种类型的视频质量。然而,H.266 尚未在业界采用。AV1 由开放媒体联盟 (AOM)推出是开源的,被许多人认为是目前可用的最好的免费视频编解码器。AV1 尚未得到广泛支持,并且已知需要更长的编码时间,这意味着编码成本增加。VP9 是谷歌开发的另一款开源编解码器,性能可与 H.265 媲美。它非常适合 4K 流媒体,并且在许多浏览器和设备上广泛兼容。
视频的音频流使用其自己的压缩编解码器,其中 AAC(高级音频编码)是最流行的。您的视频编码后,将被打包到一个视频容器中,该容器包含视频编解码器、音频编解码器以及相关的元数据,如字幕、隐藏式字幕、缩略图等。视频容器决定了视频流与设备的兼容性。自适应流媒体案例中最常用的容器格式(我们接下来会介绍)基于 ISO 基本媒体文件格式 (ISOBMFF),也称为分段 mp4。
自适应比特率流
观众可以访问不同的带宽功能,并且必须针对每种情况优化视频流。这就是自适应比特率 (ABR) 流媒体的用武之地。通过 ABR 方法,您可以在不中断视频流的情况下提供互联网连接允许的最佳视频质量。这是通过将您的视频文件编码为不同比特率、分辨率和压缩率的多个再现来实现的。因此,您的视频流可以根据设备和可用带宽在不同的视频质量之间切换。由于观众准备好忍受视频质量下降以获得一致的流,因此 ABR 是一项至关重要的编码技术。两种广泛使用的 ABR 流格式是 Apple 的 HLS(HTTP Live Streaming)和开源格式 MPEG-DASH(Dynamic Adaptive Streaming over HTTP)。流媒体格式的碎片化意味着针对更多受众的提供商必须对同一个视频文件进行编码并将其存储在多个副本中。CMAF(或通用媒体应用格式)规范的出现通过定义一种用于编码、打包和存储视频内容的单一方法来解决这一挑战。
数字版权管理
保护您的视频内容免遭未经授权的观看和分发是视频供应链中的另一个关键步骤。这是通过使用数字版权管理 (DRM) 服务来实现的。使用 DRM 技术时,编码服务使用 DRM 服务提供的加密密钥对视频进行加密。在播放点,DRM 服务将向媒体播放器颁发许可证以解密视频。
基于云的编码解决方案
云转码源码是一种高度可扩展的服务,用于准备视频内容以覆盖更广泛的受众。它通过将视频内容编码和打包成广泛使用的编解码器和自适应流格式(HLS 和 MPEG-DASH)以及 CMAF 规范来实现这一点。它是一种完全托管的云服务,旨在通过按使用付费的方法实现高效率。云转码源码让您摆脱管理自己的视频处理基础设施的后顾之忧,让您专注于创建引人入胜的视频流体验。
虽然基于云的转码传统上是小型初创企业的领域,并专注于低价值媒体,但过去两年,专业级、高可靠性的应用程序激增。这是由于运营商一方面需要应对爆炸式增长的内容量和不断增长的期望,另一方面供应商能够提供不断下降的成本以及改进的自动化和可靠性。云转码源码是一种高度可扩展、易用且经济高效的方法,可供开发者和企业将视频和音频文件从源格式转换(或“转换”)为可在智能手机、平板电脑和PC等设备上播放的版本。
云转码源码及演示:c.yunzes.top/zm
云转码源码特征:
多区域基础设施
云转码源码可在全球范围内提供服务,以使文件传输更快且更具成本效益。
没有供应商锁定
您可以简单地将您的转码文件放入我们的云存储或使用任何 S3 兼容的云
简易 API 和 SDK
使用干净美观的 API 和简单的 SDK 对您的视频进行转码。将视频集成到您的应用程序从未如此简单快捷。
GPU转码
我们的 GPU 转码器支持超快转码。您可以简单地从设置中启用它。
实时通知
获得有关正在运行的转码作业更新的实时通知。如果作业成功,则将信息报告回您的服务器,失败。
即用即付定价
只需支付用于转码视频的资源和时间。您按每分钟的视频输出计费。 如果您在设备之间切换以观看您喜爱的 OTT 系列、视频频道或电影,那么您并不孤单。事实上,报告显示他们平均每天至少在两台设备上进行流媒体播放。在手机上暂停视频,然后在电视上从同一位置恢复视频似乎很典型。但从提供商的角度来看,无论设备如何,保持一致的体验都至关重要。
易于上手
云转码源码不需要您在设置、管理或维护视频处理基础设施方面付出任何努力。它可以通过一个完整的文档和对开发人员友好的 Web API 轻松与您的后端系统集成。只需创建编码作业、指定源视频文件的位置和所需的处理设置即可开始。
利用云
作为基于云的产品,云转码源码具有高度可扩展性和运营效率,能够并行编码数百个视频。它会根据您的需求自动扩展资源并保证最大的可用性。它会定期更新以引入新的功能和技术。
具有成本效益
云转码源码是一种 SaaS 产品,您只需为所消费的内容付费。这种基于使用的方法非常适合任何企业规模。该服务与您一起发展,无需大量前期成本。此外,我们没有规定任何最低转码量或每月承诺。
多 DRM 保护
云转码源码与 DRM 原生集成,以支持多种 DRM 技术。它通过为每个视频质量级别和音轨启用单独的加密密钥来提供最佳保护。
端到端工作流程
云转码源码是原生集成到转码中的众多产品之一。该平台提供一整套用于构建视频业务的工具,以及用于构建视频平台、内容管理和保护的端到端解决方案。
视频处理工作流程(插入图片)
跨设备优化以获得最佳观看体验取决于多个变量,主要变量是编码格式,因为兼容性因设备和用例而异。编码解决方案在让视频为多屏流媒体做好准备方面发挥着重要作用。它通过将视频转码和打包成自适应流格式来实现这一点,以确保跨设备和平台的体验的兼容性和一致性。由于其带来的简单性、效率和灵活性,基于云的视频编码方法的采用正在兴起。此外,视频行业是一个不断发展的空间,新格式和技术不时被引入。
多个编解码器
编码服务使用称为编解码器的压缩技术压缩您的视频以进行流式传输。这些编解码器使用一种称为有损压缩的技术,该技术丢弃任何不必要的数据以创建更小的文件大小。每个编解码器都包含两个元素,一个用于压缩视频以进行传输的编码器和一个用于重建视频以进行播放的解码器。但是,在视频压缩过程中需要取得平衡,因为太多会导致视频质量下降,而较低的压缩会带来可怕的缓冲。这种困境导致了多个编解码器服务于不同的用例。最流行的视频编解码器包括:
H.264 (AVC)
H.265 (HEVC)
H.266 (VVC)
AV1
VP9
H.264 是最流行的视频编解码器,几乎与市场上的任何设备或平台兼容。但是,H264 最适合低延迟流式传输,并且在 4K 或高动态范围 (HDR) 内容上表现不佳。H.265 通过提高压缩效率作为高分辨率视频和实时流媒体的解决方案而出现。尽管如此,由于许可费用的不确定性,H.265 并没有像其前身那样被广泛采用。不过,它确实在大多数智能电视上都有强大的影响力。H.266 于 2020 年推出,也被称为多功能视频编码 (VVC),因为它承诺提供各种类型的视频质量。然而,H.266 尚未在业界采用。AV1 由开放媒体联盟 (AOM)推出是开源的,被许多人认为是目前可用的最好的免费视频编解码器。AV1 尚未得到广泛支持,并且已知需要更长的编码时间,这意味着编码成本增加。VP9 是谷歌开发的另一款开源编解码器,性能可与 H.265 媲美。它非常适合 4K 流媒体,并且在许多浏览器和设备上广泛兼容。
视频的音频流使用其自己的压缩编解码器,其中 AAC(高级音频编码)是最流行的。您的视频编码后,将被打包到一个视频容器中,该容器包含视频编解码器、音频编解码器以及相关的元数据,如字幕、隐藏式字幕、缩略图等。视频容器决定了视频流与设备的兼容性。自适应流媒体案例中最常用的容器格式(我们接下来会介绍)基于 ISO 基本媒体文件格式 (ISOBMFF),也称为分段 mp4。
自适应比特率流
观众可以访问不同的带宽功能,并且必须针对每种情况优化视频流。这就是自适应比特率 (ABR) 流媒体的用武之地。通过 ABR 方法,您可以在不中断视频流的情况下提供互联网连接允许的最佳视频质量。这是通过将您的视频文件编码为不同比特率、分辨率和压缩率的多个再现来实现的。因此,您的视频流可以根据设备和可用带宽在不同的视频质量之间切换。由于观众准备好忍受视频质量下降以获得一致的流,因此 ABR 是一项至关重要的编码技术。两种广泛使用的 ABR 流格式是 Apple 的 HLS(HTTP Live Streaming)和开源格式 MPEG-DASH(Dynamic Adaptive Streaming over HTTP)。流媒体格式的碎片化意味着针对更多受众的提供商必须对同一个视频文件进行编码并将其存储在多个副本中。CMAF(或通用媒体应用格式)规范的出现通过定义一种用于编码、打包和存储视频内容的单一方法来解决这一挑战。
数字版权管理
保护您的视频内容免遭未经授权的观看和分发是视频供应链中的另一个关键步骤。这是通过使用数字版权管理 (DRM) 服务来实现的。使用 DRM 技术时,编码服务使用 DRM 服务提供的加密密钥对视频进行加密。在播放点,DRM 服务将向媒体播放器颁发许可证以解密视频。
基于云的编码解决方案
云转码源码是一种高度可扩展的服务,用于准备视频内容以覆盖更广泛的受众。它通过将视频内容编码和打包成广泛使用的编解码器和自适应流格式(HLS 和 MPEG-DASH)以及 CMAF 规范来实现这一点。它是一种完全托管的云服务,旨在通过按使用付费的方法实现高效率。云转码源码让您摆脱管理自己的视频处理基础设施的后顾之忧,让您专注于创建引人入胜的视频流体验。

关于在h5中进行视频下载(安卓、苹果都可以)
\<a href="https://xxxxx.mp4?attname="\>点击下载\</a\>
目前亲测有效,
加上attname属性可以进行有效下载,
注意:
1.加上attname属性不一定都可以下载。
- 微信是不支持下载视频的,前端实现的下载视频的方法在微信不可行,同时会提示你在浏览器进行下载。
\<a href="https://xxxxx.mp4?attname="\>点击下载\</a\>
目前亲测有效,
加上attname属性可以进行有效下载,
注意:
1.加上attname属性不一定都可以下载。
- 微信是不支持下载视频的,前端实现的下载视频的方法在微信不可行,同时会提示你在浏览器进行下载。

Hbuilder创建的uniapp工程,使用tailwindcss最优雅的方式
简介
使用Hbuilder创建的uniapp工程,目前很难找到可以顺利使用tailwindcss的方案
本文仅针对 Hbuilder 创建的 uniapp 工程,对于 vue-cli 方式创建的uniapp工程,网上有文章提供了方法,但也可以使用本文的方法实现
本文的方法目前看来是最优雅的契合uniapp的,当然这得益于tailwindcss提供了强大的解决方案 —— Tailwind CLI
先说如何使用
总共5步
- 安装tailwindcss
npm install tailwindcss -D
注意最新的tailwindcss已经升级到 3.x 版本,这里安装的就是 3.x ,文档:https://tailwindcss.com/
而中文版的tailwindcss文档目前是 2.x 版本,有所差异,建议使用最新的
- 创建输入css文件
在根目录创建 tailwind-input.css,并写上如下内容
@tailwind base; /* 如果是小程序的话,这一行注释掉,因为tailwind base模块提供的一些样式选择器是基于*,这在小程序中会报错 */
@tailwind components;
@tailwind utilities;
- 创建tailwind配置文件
在根目录创建 tailwind.config.js 配置文件,可以使用npx tailwind init
指令,也可以自己创建,写上如下内容
/** @type {import('tailwindcss').Config} */
module.exports = {
separator: '__', // 如果是小程序项目需要设置这一项,将 : 选择器替换成 __,之后 hover:bg-red-500 将改为 hover__bg-red-500
corePlugins: {
// 预设样式
preflight: false, // 一般uniapp都有预设样式,所以不需要tailwindcss的预设
// 以下功能小程序不支持
space: false, // > 子节点选择器
divideWidth: false,
divideColor: false,
divideStyle: false,
divideOpacity: false,
},
// 指定要处理的文件
content: [
'./pages/**/*.{vue,js}',
'./main.js',
'./App.vue',
'./index.html'
],
theme: {
// 字号,使用 App.vue 中的 --x-font-size 样式变量配置
fontSize(config){
const list = ['2xs','xs','sm','base','md','lg','xl','2xl','3xl'];
let result = {}
list.forEach(it=>{
result[it] = `var(--x-font-size-${it})`
})
return result
},
extend: {
// 间距,tailwindcss中默认间距是rem单位,可以统一设置为uniapp的rpx单位。
// 类似的设置根据项目需求自己调整一下就好了,没必要去安装别人的预设,其实主要是小程序不兼容的css比较多,H5和App基本都直接兼容tailwindcss默认的预设
spacing(config) {
let result = { 0: '0' }
// 允许的数值大一些也无所谓,最后打包tailwindcss会摇树优化,未使用的样式并不会打包
for (let i = 1; i <= 300; i ) {
result[i] = `${i}rpx`
}
return result
},
// 增加颜色板,现在主流UI组件库大都是采用css变量实现定制主题,所以这里引用了全局的css变量,这个css变量的定义位置可以在 App.vue 中 page{} 选择器下
// 其实tailwindcss只是一个css工具,不必局限于它内部提供的东西,灵活运用css变量这些特性完全可以整合出自己的生产力工具
colors:{
'primary': 'var(--x-color-primary)',
'tips' : 'var(--x-color-tips)'
},
},
},
plugins: [],
}
- 启动 tailwind cli 输出结果css
# 在根目录
npx tailwindcss -i ./tailwind-input.css -o ./static/tailwind.css --watch
这行指令意思是,启动 tailwind cli,以 ./tailwind-input.css 为输入文件,以 ./tailwind.config.js (默认)为配置文件,开始扫描配置中 content 字段指定的【项目文件】,并输出结果css文件到 ./static/tailwind.css 中,并且监听这些【项目文件】的变化,实时更新输出结果文件
- 在项目中引入 tailwind cli 的输出结果
在 main.js 或 App.vue 中引入都行,例如在main.js中
import "@/static/tailwind.css"
大功告成!
总结一下
实际上tailwindcss有几种使用方式,传统的用法是利用 postcss ,把tailwindcss当作postcss的一个插件使用。
而uniapp的情况比较特殊,实际上使用HbuilderX创建的uniapp工程也是内置了postcss的(似乎是7.x版本),这点uniapp文档提及较少,只找到一处(https://uniapp.dcloud.net.cn/tutorial/adapt.html#_3-内容缩放拉伸的处理 )说明。
实际上因为HbuilderX创建的uniapp内部做了高度封装,所以想自己接入它的postcss过程,反而路走偏了,光是postcss v7.x 和 v8.x 的差异,都足以大到必须安装不同版本的tailwindcss才能解决
所以直接使用tailwindcss的cli方式,它自身可以在不依赖postcss和项目的情况下,自己处理好css转换的事。
归根结底,其实 tailwind cli 的工作很简单
- 从一个入口css(tailwind-input.css)开始(读取其中的 @tailwind utilities; 指令)
- 经过配置文件(tailwind.config.js),知道要处理哪些目标【项目文件】,以及要启用哪些功能
- 看看【项目文件】中使用了哪些功能类(其实它的摇树优化就是单纯的字符串匹配)
- 输出一个结果css(static/tailwind.css)
它要做的事,本身就是这么简单
高效自动化
经过上述操作,项目还是有一点点麻烦,即每次用Hbuilder启动工程开发之前,需要手动执行 npx tailwindcss -i xxxx
。
既然是程序,它完全应该更自动化一点。只需两步
npx tailwindcss -i xxxx
这个命令可以放进package.json中作为scripts执行
// 根目录的 package.json 文件
// 什么?你的项目没有这个文件? ... 那在根目录执行 npm init 命令就有了
{
// ...
"scripts": {
"tailwind-dev": "tailwindcss -i ./tailwind-input.css -o ./static/tailwind.css --watch",
"tailwind-build": "tailwindcss -i ./tailwind-input.css -o ./static/tailwind.css",
},
// ...
}
这样一来下次项目启动开发前,可以直接 npm run tailwind-dev
启动开发,npm run tailwind-build
启动生产环境打包
- 在Hbuilder启动项目开发和打包项目的过程中,让它自己执行这个npm命令
这一步稍微有点复杂,因为Hbuilder在编辑器内部集成了vue-cli或vite环境,并不能直接去控制它的启动开发过程或打包过程。
但有一点啊,uniapp一定是基于vue的,那么vue一定需要vue-cli(vue2)或vite(vue3)来打包。vue-cli 和 vite,都有配置文件,可以自由配置(参考:https://uniapp.dcloud.net.cn/collocation/vite-config.html# )。
这里以vue3的 vite.config.js
举例,vue2的 vue.config.js
是同理的
// vite.config.js
import { defineConfig } from 'vite';
import uni from '@dcloudio/vite-plugin-uni';
/** ==== 处理 tailwind cli 的自动启动和打包 ==== */
const child_process = require('child_process')
let tailwindMode = process.env.NODE_ENV
// 主进程输出
console.log(`[tailwindcss] 开始${tailwindMode == 'production' ? '生产环境打包' : '开发模式监听'}`);
child_process.exec(
// 这里指令对应 package.json 中的 npm scripts
tailwindMode == 'production'
? 'npm run tailwind-build'
: 'npm run tailwind-dev',
{
cwd: __dirname, // 切换目录到当前项目,必须
},
(error, stdout, stderr) => {
// tailwind --watch 是一个持久进程,不会立即执行回调
// process.stdout.write('tailwind success')
if (error) {
console.error('[tailwindcss] 异常,请检查');
console.error(error);
console.error(stdout);
console.error(stderr);
}
if(tailwindMode == 'production'){
console.log('[tailwindcss] 生产环境打包完成');
}
})
export default defineConfig({
plugins: [uni()],
});
对,大概就是这样。现在试一下用Hbuilder启动开发,然后在页面中使用tailwindcss的样式,你会发现 static/tailwind.css 这个文件被实时更新了。
写在后面的话
能让程序干的活就应该让程序干
我开源了一个uniapp的小程序工程启动模板
( https://gitee.com/lilimin/uniapp-weapp-starter-template )
实现了
- tailwindcss 整合
- vant-weapp 整合(个人觉得vant组件都同时支持受控和非受控模式,相比一些uniapp生态的UI组件库,这个设计模式用着还是比较舒服的)
,这个项目主要是自己用,未必会长期维护,有兴趣可以点个赞~
简介
使用Hbuilder创建的uniapp工程,目前很难找到可以顺利使用tailwindcss的方案
本文仅针对 Hbuilder 创建的 uniapp 工程,对于 vue-cli 方式创建的uniapp工程,网上有文章提供了方法,但也可以使用本文的方法实现
本文的方法目前看来是最优雅的契合uniapp的,当然这得益于tailwindcss提供了强大的解决方案 —— Tailwind CLI
先说如何使用
总共5步
- 安装tailwindcss
npm install tailwindcss -D
注意最新的tailwindcss已经升级到 3.x 版本,这里安装的就是 3.x ,文档:https://tailwindcss.com/
而中文版的tailwindcss文档目前是 2.x 版本,有所差异,建议使用最新的
- 创建输入css文件
在根目录创建 tailwind-input.css,并写上如下内容
@tailwind base; /* 如果是小程序的话,这一行注释掉,因为tailwind base模块提供的一些样式选择器是基于*,这在小程序中会报错 */
@tailwind components;
@tailwind utilities;
- 创建tailwind配置文件
在根目录创建 tailwind.config.js 配置文件,可以使用npx tailwind init
指令,也可以自己创建,写上如下内容
/** @type {import('tailwindcss').Config} */
module.exports = {
separator: '__', // 如果是小程序项目需要设置这一项,将 : 选择器替换成 __,之后 hover:bg-red-500 将改为 hover__bg-red-500
corePlugins: {
// 预设样式
preflight: false, // 一般uniapp都有预设样式,所以不需要tailwindcss的预设
// 以下功能小程序不支持
space: false, // > 子节点选择器
divideWidth: false,
divideColor: false,
divideStyle: false,
divideOpacity: false,
},
// 指定要处理的文件
content: [
'./pages/**/*.{vue,js}',
'./main.js',
'./App.vue',
'./index.html'
],
theme: {
// 字号,使用 App.vue 中的 --x-font-size 样式变量配置
fontSize(config){
const list = ['2xs','xs','sm','base','md','lg','xl','2xl','3xl'];
let result = {}
list.forEach(it=>{
result[it] = `var(--x-font-size-${it})`
})
return result
},
extend: {
// 间距,tailwindcss中默认间距是rem单位,可以统一设置为uniapp的rpx单位。
// 类似的设置根据项目需求自己调整一下就好了,没必要去安装别人的预设,其实主要是小程序不兼容的css比较多,H5和App基本都直接兼容tailwindcss默认的预设
spacing(config) {
let result = { 0: '0' }
// 允许的数值大一些也无所谓,最后打包tailwindcss会摇树优化,未使用的样式并不会打包
for (let i = 1; i <= 300; i ) {
result[i] = `${i}rpx`
}
return result
},
// 增加颜色板,现在主流UI组件库大都是采用css变量实现定制主题,所以这里引用了全局的css变量,这个css变量的定义位置可以在 App.vue 中 page{} 选择器下
// 其实tailwindcss只是一个css工具,不必局限于它内部提供的东西,灵活运用css变量这些特性完全可以整合出自己的生产力工具
colors:{
'primary': 'var(--x-color-primary)',
'tips' : 'var(--x-color-tips)'
},
},
},
plugins: [],
}
- 启动 tailwind cli 输出结果css
# 在根目录
npx tailwindcss -i ./tailwind-input.css -o ./static/tailwind.css --watch
这行指令意思是,启动 tailwind cli,以 ./tailwind-input.css 为输入文件,以 ./tailwind.config.js (默认)为配置文件,开始扫描配置中 content 字段指定的【项目文件】,并输出结果css文件到 ./static/tailwind.css 中,并且监听这些【项目文件】的变化,实时更新输出结果文件
- 在项目中引入 tailwind cli 的输出结果
在 main.js 或 App.vue 中引入都行,例如在main.js中
import "@/static/tailwind.css"
大功告成!
总结一下
实际上tailwindcss有几种使用方式,传统的用法是利用 postcss ,把tailwindcss当作postcss的一个插件使用。
而uniapp的情况比较特殊,实际上使用HbuilderX创建的uniapp工程也是内置了postcss的(似乎是7.x版本),这点uniapp文档提及较少,只找到一处(https://uniapp.dcloud.net.cn/tutorial/adapt.html#_3-内容缩放拉伸的处理 )说明。
实际上因为HbuilderX创建的uniapp内部做了高度封装,所以想自己接入它的postcss过程,反而路走偏了,光是postcss v7.x 和 v8.x 的差异,都足以大到必须安装不同版本的tailwindcss才能解决
所以直接使用tailwindcss的cli方式,它自身可以在不依赖postcss和项目的情况下,自己处理好css转换的事。
归根结底,其实 tailwind cli 的工作很简单
- 从一个入口css(tailwind-input.css)开始(读取其中的 @tailwind utilities; 指令)
- 经过配置文件(tailwind.config.js),知道要处理哪些目标【项目文件】,以及要启用哪些功能
- 看看【项目文件】中使用了哪些功能类(其实它的摇树优化就是单纯的字符串匹配)
- 输出一个结果css(static/tailwind.css)
它要做的事,本身就是这么简单
高效自动化
经过上述操作,项目还是有一点点麻烦,即每次用Hbuilder启动工程开发之前,需要手动执行 npx tailwindcss -i xxxx
。
既然是程序,它完全应该更自动化一点。只需两步
npx tailwindcss -i xxxx
这个命令可以放进package.json中作为scripts执行
// 根目录的 package.json 文件
// 什么?你的项目没有这个文件? ... 那在根目录执行 npm init 命令就有了
{
// ...
"scripts": {
"tailwind-dev": "tailwindcss -i ./tailwind-input.css -o ./static/tailwind.css --watch",
"tailwind-build": "tailwindcss -i ./tailwind-input.css -o ./static/tailwind.css",
},
// ...
}
这样一来下次项目启动开发前,可以直接 npm run tailwind-dev
启动开发,npm run tailwind-build
启动生产环境打包
- 在Hbuilder启动项目开发和打包项目的过程中,让它自己执行这个npm命令
这一步稍微有点复杂,因为Hbuilder在编辑器内部集成了vue-cli或vite环境,并不能直接去控制它的启动开发过程或打包过程。
但有一点啊,uniapp一定是基于vue的,那么vue一定需要vue-cli(vue2)或vite(vue3)来打包。vue-cli 和 vite,都有配置文件,可以自由配置(参考:https://uniapp.dcloud.net.cn/collocation/vite-config.html# )。
这里以vue3的 vite.config.js
举例,vue2的 vue.config.js
是同理的
// vite.config.js
import { defineConfig } from 'vite';
import uni from '@dcloudio/vite-plugin-uni';
/** ==== 处理 tailwind cli 的自动启动和打包 ==== */
const child_process = require('child_process')
let tailwindMode = process.env.NODE_ENV
// 主进程输出
console.log(`[tailwindcss] 开始${tailwindMode == 'production' ? '生产环境打包' : '开发模式监听'}`);
child_process.exec(
// 这里指令对应 package.json 中的 npm scripts
tailwindMode == 'production'
? 'npm run tailwind-build'
: 'npm run tailwind-dev',
{
cwd: __dirname, // 切换目录到当前项目,必须
},
(error, stdout, stderr) => {
// tailwind --watch 是一个持久进程,不会立即执行回调
// process.stdout.write('tailwind success')
if (error) {
console.error('[tailwindcss] 异常,请检查');
console.error(error);
console.error(stdout);
console.error(stderr);
}
if(tailwindMode == 'production'){
console.log('[tailwindcss] 生产环境打包完成');
}
})
export default defineConfig({
plugins: [uni()],
});
对,大概就是这样。现在试一下用Hbuilder启动开发,然后在页面中使用tailwindcss的样式,你会发现 static/tailwind.css 这个文件被实时更新了。
写在后面的话
能让程序干的活就应该让程序干
我开源了一个uniapp的小程序工程启动模板
( https://gitee.com/lilimin/uniapp-weapp-starter-template )
实现了
- tailwindcss 整合
- vant-weapp 整合(个人觉得vant组件都同时支持受控和非受控模式,相比一些uniapp生态的UI组件库,这个设计模式用着还是比较舒服的)
,这个项目主要是自己用,未必会长期维护,有兴趣可以点个赞~
收起阅读 »
uni统计 - 安卓平台 deviceId 获取方式变更升级指南
起因
因 HBuilderX 3.4.9
版本起,uni统计
调整了App-Android平台 deviceId 获取方式,导致 uni统计
App-Android平台部分统计数据不准确。
影响范围
仅影响使用HBuilderX
3.4.9
- 3.6.4
版本打包的App-Android的统计数据。
解决方案
如使用了HBuilderX
3.4.9
- 3.6.4
版本且开通了uni统计
的应用,需要使用HBuilderX3.6.7
及以上版本重新打包发布应用。此外如使用uni统计2.0
还需升级 uni-admin
至2.1.1
及以上版本,否则会导致日活、留存等数据出现偏差。
升级步骤
uni统计1.0
如应用使用uni统计1.0
,请使用HBuilderX3.6.7
及以上版本重新打包发布Android app。
uni统计2.0
服务端升级
- 右键选中
uni-admin
根目录下的package.json文件,选择“从插件市场更新”选项,更新uni-admin
至最新版 - 重新上传
uni-stat
公共模块到关联服务空间
注意: 如果升级前有对uni-admin
项目进行过调整,需自行比较并合并代码。如果只想升级uni统计2.0相关的功能,则可只合并uni-stat
公共模块并上传到关联服务空间。
客户端升级
使用HBuilderX3.6.7
及以上版本重新打包发布Android app。
起因
因 HBuilderX 3.4.9
版本起,uni统计
调整了App-Android平台 deviceId 获取方式,导致 uni统计
App-Android平台部分统计数据不准确。
影响范围
仅影响使用HBuilderX
3.4.9
- 3.6.4
版本打包的App-Android的统计数据。
解决方案
如使用了HBuilderX
3.4.9
- 3.6.4
版本且开通了uni统计
的应用,需要使用HBuilderX3.6.7
及以上版本重新打包发布应用。此外如使用uni统计2.0
还需升级 uni-admin
至2.1.1
及以上版本,否则会导致日活、留存等数据出现偏差。
升级步骤
uni统计1.0
如应用使用uni统计1.0
,请使用HBuilderX3.6.7
及以上版本重新打包发布Android app。
uni统计2.0
服务端升级
- 右键选中
uni-admin
根目录下的package.json文件,选择“从插件市场更新”选项,更新uni-admin
至最新版 - 重新上传
uni-stat
公共模块到关联服务空间
注意: 如果升级前有对uni-admin
项目进行过调整,需自行比较并合并代码。如果只想升级uni统计2.0相关的功能,则可只合并uni-stat
公共模块并上传到关联服务空间。
客户端升级
使用HBuilderX3.6.7
及以上版本重新打包发布Android app。

乘风破浪、厚积薄发国产服务器软件: LinWin Http Server
国产服务器一直存在着被国外 nginx、apache、tomcat 等垄断的局面,然而这使得在推进操作系统的国产化上是一个不小的阻碍。在国产操作系统成为趋势的背景下,也迫切的需要一款自主的国产服务器软件来供给给国产的服务器操作系统。这就是本文章的主角: LinWin Http Server服务器。
LinWin Http Server开发的小插曲
这一路上 LinWin Http Server异常坎坎坷坷,开发之旅并不顺利,早在2021年初便开始了这个项目,最开始使用的是Python开发,同样是基于Linux,却是单线程,在开发路上最后经过多次的模块重写,最后失败了。这也给作者了一个教训,在开发的时候一定要规划详细、仔细而且要谨慎。而在2022年中,作者重拾起了这个已经尘封的项目。
这次不想之前的莽撞,而是多了份自信、成熟与思考。经过 3个月的开发,超过10万次的服务器测试,这个项目也算是有了雏形、稳定了,LinWin Http Server力求给用户最稳定的服务器体验。
什么是 LinWin Http Server
LinWin Http Server是由 优信团队、萤火科技团队、LinWinCloud几个团队共同开发的一款基于Java的开源HTTP服务器软件。支持反向代理、HTTP服务、对Web的服务,是沟通互联网的重要工具之一。LinWin Http Server使用多线程技术来为用户提供HTTP服务,对配置一般的服务器来说非常友好。
为什么要开发 LinWin Http Server
作者亲眼看到了,很多国内企业、团队都使用的是国外的产品,而在我们的国产服务器上,非常缺乏国产的服务器软件。这也是 LInWin Http Server开发的动力。打破垄断,厚积薄发,努力为中国国产服务器和操作系统作为一个更好的服务器软件。
LinWin Http Server的支持平台
Linux平台
Linux平台是LinWinHttp Server主要支持的平台,因为大多数的服务器运行上面
开放麒麟、优麒麟、银河麒麟、UOS、deepin国产Linux系统,支持国产,LinWin Http对国产支持最好
LinWin Http Server的安全性
保证服务器的安全是LInWIn Http的第一准则,一切功能的前提下是服务器安全。LinWIn Http Server内置了非常多的安全模块,安全省心省力
SQL注入防护
SQL注入慢慢成为了现在危害很多网站的漏洞之一,而LInWIn Http默认开启了这个防护选项,拦截非法的sql语句。
XSS注入防护
XSS防护模块会把非法的脚本、标签识别出来,接着阻断用户继续的访问。
资源防护
很多开发者在使用服务器的时候会忘记把日志文件、重要的用户和密码等文件放在服务目录,这些都是不被允许的,而LinWin Http在默认的配置中完全保护了这些可能的资源不该访问的情况。
部署网站的便捷性
您可以直接把所有的文件丢在 /usr/www/html 内,剩下的全都交给服务器,而且安全方便,提供专门的安装脚本,拒绝各种麻烦的预先配置。(网站默认的服务端口在10141)
反向代理服务器
是的你没听错,他和 nginx一样支持反向代理,对静态网站的代理支持最好,您可以根据需要来设置代理的服务器。
结语
LinWin Http Server一路坎坎坷坷,致力为中国和世界贡献一份属于自己的源代码、属于自己的探索之路,一份精彩的传奇之路。他还年轻,有敢想敢为的梦想、有青春少年的冲劲、有敢为甘当的精神。乘风破浪、厚积薄发,这是属于数字的时代,在这数字的海洋中,LInWin Http的明天将会更加好。
欢迎关注作者: LinWinCloud
源代码: https://github.com/LinWin-Cloud/linwin-http-server
国产服务器一直存在着被国外 nginx、apache、tomcat 等垄断的局面,然而这使得在推进操作系统的国产化上是一个不小的阻碍。在国产操作系统成为趋势的背景下,也迫切的需要一款自主的国产服务器软件来供给给国产的服务器操作系统。这就是本文章的主角: LinWin Http Server服务器。
LinWin Http Server开发的小插曲
这一路上 LinWin Http Server异常坎坎坷坷,开发之旅并不顺利,早在2021年初便开始了这个项目,最开始使用的是Python开发,同样是基于Linux,却是单线程,在开发路上最后经过多次的模块重写,最后失败了。这也给作者了一个教训,在开发的时候一定要规划详细、仔细而且要谨慎。而在2022年中,作者重拾起了这个已经尘封的项目。
这次不想之前的莽撞,而是多了份自信、成熟与思考。经过 3个月的开发,超过10万次的服务器测试,这个项目也算是有了雏形、稳定了,LinWin Http Server力求给用户最稳定的服务器体验。
什么是 LinWin Http Server
LinWin Http Server是由 优信团队、萤火科技团队、LinWinCloud几个团队共同开发的一款基于Java的开源HTTP服务器软件。支持反向代理、HTTP服务、对Web的服务,是沟通互联网的重要工具之一。LinWin Http Server使用多线程技术来为用户提供HTTP服务,对配置一般的服务器来说非常友好。
为什么要开发 LinWin Http Server
作者亲眼看到了,很多国内企业、团队都使用的是国外的产品,而在我们的国产服务器上,非常缺乏国产的服务器软件。这也是 LInWin Http Server开发的动力。打破垄断,厚积薄发,努力为中国国产服务器和操作系统作为一个更好的服务器软件。
LinWin Http Server的支持平台
Linux平台
Linux平台是LinWinHttp Server主要支持的平台,因为大多数的服务器运行上面
开放麒麟、优麒麟、银河麒麟、UOS、deepin国产Linux系统,支持国产,LinWin Http对国产支持最好
LinWin Http Server的安全性
保证服务器的安全是LInWIn Http的第一准则,一切功能的前提下是服务器安全。LinWIn Http Server内置了非常多的安全模块,安全省心省力
SQL注入防护
SQL注入慢慢成为了现在危害很多网站的漏洞之一,而LInWIn Http默认开启了这个防护选项,拦截非法的sql语句。
XSS注入防护
XSS防护模块会把非法的脚本、标签识别出来,接着阻断用户继续的访问。
资源防护
很多开发者在使用服务器的时候会忘记把日志文件、重要的用户和密码等文件放在服务目录,这些都是不被允许的,而LinWin Http在默认的配置中完全保护了这些可能的资源不该访问的情况。
部署网站的便捷性
您可以直接把所有的文件丢在 /usr/www/html 内,剩下的全都交给服务器,而且安全方便,提供专门的安装脚本,拒绝各种麻烦的预先配置。(网站默认的服务端口在10141)
反向代理服务器
是的你没听错,他和 nginx一样支持反向代理,对静态网站的代理支持最好,您可以根据需要来设置代理的服务器。
结语
LinWin Http Server一路坎坎坷坷,致力为中国和世界贡献一份属于自己的源代码、属于自己的探索之路,一份精彩的传奇之路。他还年轻,有敢想敢为的梦想、有青春少年的冲劲、有敢为甘当的精神。乘风破浪、厚积薄发,这是属于数字的时代,在这数字的海洋中,LInWin Http的明天将会更加好。
欢迎关注作者: LinWinCloud
源代码: https://github.com/LinWin-Cloud/linwin-http-server
收起阅读 »
使用unicoloud遇到的一大巨坑,后来者千万要小心!!!
当你的where里有一项的值为undefined的时候,比如你前端表单里忘了写这一项
比如:
.where({
_id:uid
status:'正常'
})
如果这个时候uid传过来的是undefined,数据库忽略掉_id这一项,会把所有的status='正常'的数据全都给你
仅查询的话问题不大,但当你update的时候......
比如:
.where({
_id:uid
status:'正常'
})
.update({
vip:true
})
那么恭喜你。。。整个库里的人全变成了VIP。。。。。
当你的where里有一项的值为undefined的时候,比如你前端表单里忘了写这一项
比如:
.where({
_id:uid
status:'正常'
})
如果这个时候uid传过来的是undefined,数据库忽略掉_id这一项,会把所有的status='正常'的数据全都给你
仅查询的话问题不大,但当你update的时候......
比如:
.where({
_id:uid
status:'正常'
})
.update({
vip:true
})
那么恭喜你。。。整个库里的人全变成了VIP。。。。。