
uni原生插件注册
不用创建json文件的另外一种注册方式
public class App extends Application {
@Override
public void onCreate() {
super.onCreate();
try {
UniSDKEngine.registerModule("TestModule", TestModule.class);
} catch (UniException e) {
e.printStackTrace();
}
}
}
不用创建json文件的另外一种注册方式
public class App extends Application {
@Override
public void onCreate() {
super.onCreate();
try {
UniSDKEngine.registerModule("TestModule", TestModule.class);
} catch (UniException e) {
e.printStackTrace();
}
}
}

拓扑新动画效果,可拖拽,可滚轮缩放。
展示效果网址 http://jstopo.top
!
init(){
this.domRef = this.$refs.canvas;
this.w = this.domRef.width = this.domRef.clientWidth,
this.h = this.domRef.height = this.domRef.clientHeight;
this.ctx = this.domRef.getContext("2d");
this.ctx.textAlign = "center";
this.ctx.textBaseline = "top";
this.ctx.font = "18px 黑体";
this.dotMove();
},
展示效果网址 http://jstopo.top
!
init(){
this.domRef = this.$refs.canvas;
this.w = this.domRef.width = this.domRef.clientWidth,
this.h = this.domRef.height = this.domRef.clientHeight;
this.ctx = this.domRef.getContext("2d");
this.ctx.textAlign = "center";
this.ctx.textBaseline = "top";
this.ctx.font = "18px 黑体";
this.dotMove();
},
收起阅读 »

app-nvue webview加载本地网页,真机上路径错误
app-nvue webview加载本地网页,url不能携带参数(如:/hybrid/html/index.html?id=1 改为 /hybrid/html/index.html)。
数据传递使用webview通信。
webview官网:https://uniapp.dcloud.net.cn/component/web-view.html
<template>
<view>
<web-view ref="webview" class="webview" @onPostMessage="handlePostMessage"></web-view>
<button class="button" @click="evalJs">evalJs(改变webview背景颜色)</button>
</view>
</template>
<script>
export default {
data: {
},
methods: {
// webview向外部发送消息
handlePostMessage: function(data) {
console.log("接收到消息:" JSON.stringify(data.detail));
},
// 调用 webview 内部逻辑和方法(方法挂载到window对象上)
evalJs: function() {
this.$refs.webview.evalJs(`方法名(${paramStr})`);
}
}
}
</script>
app-nvue webview加载本地网页,url不能携带参数(如:/hybrid/html/index.html?id=1 改为 /hybrid/html/index.html)。
数据传递使用webview通信。
webview官网:https://uniapp.dcloud.net.cn/component/web-view.html
<template>
<view>
<web-view ref="webview" class="webview" @onPostMessage="handlePostMessage"></web-view>
<button class="button" @click="evalJs">evalJs(改变webview背景颜色)</button>
</view>
</template>
<script>
export default {
data: {
},
methods: {
// webview向外部发送消息
handlePostMessage: function(data) {
console.log("接收到消息:" JSON.stringify(data.detail));
},
// 调用 webview 内部逻辑和方法(方法挂载到window对象上)
evalJs: function() {
this.$refs.webview.evalJs(`方法名(${paramStr})`);
}
}
}
</script>
收起阅读 »

如何解决打包后wap2app顶部标题栏与APP首页内容重叠,真机调试中显示正常
Step1.修改manifest.json文件
将plus>statusbar>immersed的值修改为"false"或"none"。
即:
"plus" : {
......
"statusbar" : {
"immersed" : "none"
},
......
}
Step2.(可选)修改导航栏颜色样式
完成Step1后导航栏默认显示为灰色背景,黑色字体。
如需修改样式,请修改client_index.html文件。
在body标签中加入
<script type="text/javascript">
if(window.plus)
{
plusReady()
}
else
{
document.addEventListener('plusready',plusReady,false)
}
function plusReady()
{
plus.navigator.setStatusBarBackground('#FFFFFF');
plus.navigator.setStatusBarStyle('dark');
}
</script>
Step1.修改manifest.json文件
将plus>statusbar>immersed的值修改为"false"或"none"。
即:
"plus" : {
......
"statusbar" : {
"immersed" : "none"
},
......
}
Step2.(可选)修改导航栏颜色样式
完成Step1后导航栏默认显示为灰色背景,黑色字体。
如需修改样式,请修改client_index.html文件。
在body标签中加入
<script type="text/javascript">
if(window.plus)
{
plusReady()
}
else
{
document.addEventListener('plusready',plusReady,false)
}
function plusReady()
{
plus.navigator.setStatusBarBackground('#FFFFFF');
plus.navigator.setStatusBarStyle('dark');
}
</script>
收起阅读 »

python后端直接通过http的方式操作数据库, 不通过web控制台或者云函数
只贴下python的insert数据库的操作, 其他语言类似
免费版的url = 'https://api.bspapp.com/client'
收费版的是url = 'https://api.next.bspapp.com/client'自己替换下
import requests
import json
import time
import hmac
import hashlib
def insert():
# accessToken是后面header需要的参数
accessToken = get_access_token()
url = 'https://api.bspapp.com/client'
payload = {
'method': 'serverless.function.runtime.invoke',
'params': json.dumps(
{
"functionTarget": "DCloud-clientDB",
"functionArgs": {
"command": {
"$db": [
{
"$method": "collection",
"$param": ["表名"]
}, {
"$method": "add", #如果是update这里add就换成update. 写法类似于mongodb的
"$param": [{"字段名1": "字段值1"}]
}
]
}
}
}
),
# spaceId自己在web控制台找, timestamp是时间戳
'spaceId': spaceId,
'timestamp': int(round(time.time() * 1000)),
'token': accessToken,
}
headers = {
'content-type': 'application/json',
'x-basement-token': accessToken,
'x-serverless-sign': get_sign(payload),
}
payload = json.dumps(payload)
# 发送post请求
response = requests.post(url, data=payload, headers=headers)
result = json.loads(response.text)
return result
#获取access_token的方法, access_token一段时间会过期
def get_access_token():
url = 'https://api.bspapp.com/client'
payload = {
'method': 'serverless.auth.user.anonymousAuthorize',
'params': '{}',
'spaceId': spaceId,
'timestamp': int(round(time.time() * 1000)),
}
headers = {
'Content-Type': 'application/json',
'x-serverless-sign': get_sign(payload)
}
payload = json.dumps(payload)
response = requests.post(url, data=payload, headers=headers)
result = json.loads(response.text)
access_token = result['data']['accessToken']
return access_token
# 签名参数
def get_sign(param):
#按照键名的升序排序
param = ksort(param)
#键与值 等号拼接的数组, 结果如["键1=值1", "键2=值2", "键3=值3"...]
signList = []
for k, v in param:
if v != '':
signList.append(k + '=' + str(v))
# 每个参数对拼接&并连在一起的字符串, 结果如 "键1=值1&键2=值2&键3=值3"...
signPars = '&'.join(signList)
#md5 hmac加密, clientSecret自己的web控制台里找, hmac, hashlib是python自带的库..其他语言也应该有类似的
sign = hmac.new(clientSecret.encode('utf-8'), signPars.encode('utf-8'), digestmod=hashlib.md5).hexdigest()
return sign
#按照键名的升序排序, php里直接有ksort() 可以使用
def ksort(d):
return [(k, d[k]) for k in sorted(d.keys())]
下面是一些写法举例
查询,比如查_id: 17的那条数据
"command": {
"$db": [
{
"$method": "collection",
"$param": ["表名"]
}, {
"$method": "where",
"$param": [{"_id": 17}]
}, {
"$method": "get",
"$param": []
}
]
}
删除, 比如删除_id: 17的那条数据
"command": {
"$db": [
{
"$method": "collection",
"$param": ["表名"]
}, {
"$method": "where",
"$param": [{"_id": 17}]
}, {
"$method": "remove",
"$param": []
}
]
},
改, 修改_id:17的那条数据
"command": {
"$db": [
{
"$method": "collection",
"$param": ["表名"]
}, {
"$method": "where",
"$param": [{"_id": 17]
}, {
"$method": "update",
"$param": [{"字段1":"字段值1"}]
}
]
}
只贴下python的insert数据库的操作, 其他语言类似
免费版的url = 'https://api.bspapp.com/client'
收费版的是url = 'https://api.next.bspapp.com/client'自己替换下
import requests
import json
import time
import hmac
import hashlib
def insert():
# accessToken是后面header需要的参数
accessToken = get_access_token()
url = 'https://api.bspapp.com/client'
payload = {
'method': 'serverless.function.runtime.invoke',
'params': json.dumps(
{
"functionTarget": "DCloud-clientDB",
"functionArgs": {
"command": {
"$db": [
{
"$method": "collection",
"$param": ["表名"]
}, {
"$method": "add", #如果是update这里add就换成update. 写法类似于mongodb的
"$param": [{"字段名1": "字段值1"}]
}
]
}
}
}
),
# spaceId自己在web控制台找, timestamp是时间戳
'spaceId': spaceId,
'timestamp': int(round(time.time() * 1000)),
'token': accessToken,
}
headers = {
'content-type': 'application/json',
'x-basement-token': accessToken,
'x-serverless-sign': get_sign(payload),
}
payload = json.dumps(payload)
# 发送post请求
response = requests.post(url, data=payload, headers=headers)
result = json.loads(response.text)
return result
#获取access_token的方法, access_token一段时间会过期
def get_access_token():
url = 'https://api.bspapp.com/client'
payload = {
'method': 'serverless.auth.user.anonymousAuthorize',
'params': '{}',
'spaceId': spaceId,
'timestamp': int(round(time.time() * 1000)),
}
headers = {
'Content-Type': 'application/json',
'x-serverless-sign': get_sign(payload)
}
payload = json.dumps(payload)
response = requests.post(url, data=payload, headers=headers)
result = json.loads(response.text)
access_token = result['data']['accessToken']
return access_token
# 签名参数
def get_sign(param):
#按照键名的升序排序
param = ksort(param)
#键与值 等号拼接的数组, 结果如["键1=值1", "键2=值2", "键3=值3"...]
signList = []
for k, v in param:
if v != '':
signList.append(k + '=' + str(v))
# 每个参数对拼接&并连在一起的字符串, 结果如 "键1=值1&键2=值2&键3=值3"...
signPars = '&'.join(signList)
#md5 hmac加密, clientSecret自己的web控制台里找, hmac, hashlib是python自带的库..其他语言也应该有类似的
sign = hmac.new(clientSecret.encode('utf-8'), signPars.encode('utf-8'), digestmod=hashlib.md5).hexdigest()
return sign
#按照键名的升序排序, php里直接有ksort() 可以使用
def ksort(d):
return [(k, d[k]) for k in sorted(d.keys())]
下面是一些写法举例
查询,比如查_id: 17的那条数据
"command": {
"$db": [
{
"$method": "collection",
"$param": ["表名"]
}, {
"$method": "where",
"$param": [{"_id": 17}]
}, {
"$method": "get",
"$param": []
}
]
}
删除, 比如删除_id: 17的那条数据
"command": {
"$db": [
{
"$method": "collection",
"$param": ["表名"]
}, {
"$method": "where",
"$param": [{"_id": 17}]
}, {
"$method": "remove",
"$param": []
}
]
},
改, 修改_id:17的那条数据
"command": {
"$db": [
{
"$method": "collection",
"$param": ["表名"]
}, {
"$method": "where",
"$param": [{"_id": 17]
}, {
"$method": "update",
"$param": [{"字段1":"字段值1"}]
}
]
}
收起阅读 »

【分享】微信内部浏览器跳转公众号引导用户关注
制作一个链接,点击该链接跳转到公众号关注页面。
1、从公众平台登进入公众号
2、点击开发>>开发者工具
3、F12 >>Elements
4、ctrl+f 搜索 uin_base64或在控制台window.wx.commonData.uin_base64
5、将下面链接的__biz=后面的值更换成uin_base64的值,然后用微信打开该链接即可。
https://mp.weixin.qq.com/mp/profile_ext?action=home&__biz=64位uin加密值&scene=110#wechat_redirect
示例:
https://mp.weixin.qq.com/mp/profile_ext?action=home&__biz=MzIzODU4NzkyOQ==&scene=110#wechat_redirect
制作一个链接,点击该链接跳转到公众号关注页面。
1、从公众平台登进入公众号
2、点击开发>>开发者工具
3、F12 >>Elements
4、ctrl+f 搜索 uin_base64或在控制台window.wx.commonData.uin_base64
5、将下面链接的__biz=后面的值更换成uin_base64的值,然后用微信打开该链接即可。
https://mp.weixin.qq.com/mp/profile_ext?action=home&__biz=64位uin加密值&scene=110#wechat_redirect
示例:
https://mp.weixin.qq.com/mp/profile_ext?action=home&__biz=MzIzODU4NzkyOQ==&scene=110#wechat_redirect

uniapp 打包时提示:未添加 OAuth 模块
问题:打包时总是提示 “未添加 OAuth 模块”
关闭 manifest.json 模块配置中的 Oauth:在 manifest.json->App 模块配置中勾选 “OAuth(登录鉴权)”,但要将下方所有登录都取消勾选,
把 App.vue 中的一键登录 uni.preLogin 整个注释掉
login.vue 登录页中,注释掉第三方登录
问题:打包时总是提示 “未添加 OAuth 模块”
关闭 manifest.json 模块配置中的 Oauth:在 manifest.json->App 模块配置中勾选 “OAuth(登录鉴权)”,但要将下方所有登录都取消勾选,
把 App.vue 中的一键登录 uni.preLogin 整个注释掉
login.vue 登录页中,注释掉第三方登录
收起阅读 »
在开发unicloud+微信支付分账时遇到的奇葩问题和解决方案,原因未知渴望解答
背景与需求
我负责开发运维的一款家政服务类小程序,支持微信在线支付,并在支付完成后,通过微信分账功能,将渠道环节的费用直接分账到渠道个人微信,例如,推荐人的分成直接到账。
理想与现实
理想
通过微信支付回调接口,触发分账,计算各个渠道的分账比例和金额,提交给微信,由微信完成分账。分账结果返回后,在平台做财务记录,完成分账。
现实
实际遇到的问题比想象的多出了很多,例如:
1,用户支付完成后立即发起分账申请,会失败,报错是验签失败(这根本和验签无关,是支付流程结束后等一段才能申请分账)
2,直接通过unicloud云函数A调用分账,不返回任何数据,云函数直接结束。(而如果通过另一个云函数B调用云函数A,则能正常返回数据)
3,如果在本地直接运行云函数B,调用云函数A,在支付完成后的大约1分钟后,可正常返回。但如果直接运行云函数A,则分账被执行,但不返回任何结果。
4,如果在云函数B中稍微代码多一点的位置调用云函数A,则会返回验签失败错误。如果在云函数B的靠前位置调用,则返回成功。
5,如果将云函数部署到云端,并通过设置外链方式触发云函数,则返回验签失败错误。但如果在本地hbuilderx里右键,本地运行,则正常。
6,如果在本地hbuilderx里右键云函数B,选择上传并运行,则返回验签失败错误。
7,在分账成功后,有时候不会立即返回分账成功的消息,分账状态是PROCESSING,因此需要过大约几分钟,调用查询分账的接口获取状态。但是,该接口必须在云函数A中直接执行,如果用其他函数调用,则返回验签失败错误。
8,如果设置云函数B为定时触发,在B中调用A,则正常。但如果选择访问链接方式触发云函数B,则大部分情况下是失败,偶尔成功。
9,发现对同一笔订单进行重复的分账,反而比get分账状态接口更好用。如果对同一笔订单再次申请分账,则会准确返回分账状态。
10,发现云函数B触发时的context不太一样,我将context强制定义成本地右键云函数本地运行方式才可正常返回分账结果。抓取方式是,云函数B中,event后面加,context,然后打印,再讲打印的结果,强行赋值给context,这样从任何地方访问,都会被认为是本地执行。
解决方案
1,建立云函数A,里面是分账代码。
2,建立云函数B,调用和执行云函数A,触发分账。
3,再次调用云函数B,再次对同一笔订单执行相同操作分账,可返回分账状态。
4,云函数B的触发方式很多,但只有两种(本地hbuilderx云函数右键本地运行和自动定时触发)不会报验签错误,而其中只有一种可部署到生产环境下,即定时触发。
5,阿里云限制云函数触发周期最短1小时,因此我建立了共6个云函数B,实现到了10分钟触发一次,云函数名额有限,只能临时采取这种方式了。
思考
我认为这种腾讯支付API不稳定的状态可能与发起提交的数据中的headers之类数据相关,要不然为什么相同的代码,本地运行可以,传到云函数运行就不行,或者定时触发可以,外链方式触发就不行,这些地方太诡异了。
打个广告
个人团队可承接微信小程序开发任务,定制各种疑难技术问题解决方案,V361757或私信即可。
背景与需求
我负责开发运维的一款家政服务类小程序,支持微信在线支付,并在支付完成后,通过微信分账功能,将渠道环节的费用直接分账到渠道个人微信,例如,推荐人的分成直接到账。
理想与现实
理想
通过微信支付回调接口,触发分账,计算各个渠道的分账比例和金额,提交给微信,由微信完成分账。分账结果返回后,在平台做财务记录,完成分账。
现实
实际遇到的问题比想象的多出了很多,例如:
1,用户支付完成后立即发起分账申请,会失败,报错是验签失败(这根本和验签无关,是支付流程结束后等一段才能申请分账)
2,直接通过unicloud云函数A调用分账,不返回任何数据,云函数直接结束。(而如果通过另一个云函数B调用云函数A,则能正常返回数据)
3,如果在本地直接运行云函数B,调用云函数A,在支付完成后的大约1分钟后,可正常返回。但如果直接运行云函数A,则分账被执行,但不返回任何结果。
4,如果在云函数B中稍微代码多一点的位置调用云函数A,则会返回验签失败错误。如果在云函数B的靠前位置调用,则返回成功。
5,如果将云函数部署到云端,并通过设置外链方式触发云函数,则返回验签失败错误。但如果在本地hbuilderx里右键,本地运行,则正常。
6,如果在本地hbuilderx里右键云函数B,选择上传并运行,则返回验签失败错误。
7,在分账成功后,有时候不会立即返回分账成功的消息,分账状态是PROCESSING,因此需要过大约几分钟,调用查询分账的接口获取状态。但是,该接口必须在云函数A中直接执行,如果用其他函数调用,则返回验签失败错误。
8,如果设置云函数B为定时触发,在B中调用A,则正常。但如果选择访问链接方式触发云函数B,则大部分情况下是失败,偶尔成功。
9,发现对同一笔订单进行重复的分账,反而比get分账状态接口更好用。如果对同一笔订单再次申请分账,则会准确返回分账状态。
10,发现云函数B触发时的context不太一样,我将context强制定义成本地右键云函数本地运行方式才可正常返回分账结果。抓取方式是,云函数B中,event后面加,context,然后打印,再讲打印的结果,强行赋值给context,这样从任何地方访问,都会被认为是本地执行。
解决方案
1,建立云函数A,里面是分账代码。
2,建立云函数B,调用和执行云函数A,触发分账。
3,再次调用云函数B,再次对同一笔订单执行相同操作分账,可返回分账状态。
4,云函数B的触发方式很多,但只有两种(本地hbuilderx云函数右键本地运行和自动定时触发)不会报验签错误,而其中只有一种可部署到生产环境下,即定时触发。
5,阿里云限制云函数触发周期最短1小时,因此我建立了共6个云函数B,实现到了10分钟触发一次,云函数名额有限,只能临时采取这种方式了。
思考
我认为这种腾讯支付API不稳定的状态可能与发起提交的数据中的headers之类数据相关,要不然为什么相同的代码,本地运行可以,传到云函数运行就不行,或者定时触发可以,外链方式触发就不行,这些地方太诡异了。
打个广告
个人团队可承接微信小程序开发任务,定制各种疑难技术问题解决方案,V361757或私信即可。
收起阅读 »
判断元素是否在于数组中
inArray (str, array) {
let isInArray = -1;
for (let i = 0; i < array.length; i++) {
let array_ = array[i];
if (isEqual(array_,str)) {
isInArray = i;
break;
};
};
return isInArray;
}
isEqual() // 判断是否等于
.find() 是查找是否包含
inArray (str, array) {
let isInArray = -1;
for (let i = 0; i < array.length; i++) {
let array_ = array[i];
if (isEqual(array_,str)) {
isInArray = i;
break;
};
};
return isInArray;
}
isEqual() // 判断是否等于
.find() 是查找是否包含
收起阅读 »
在 HBuilderX 中使用 tailwindcss
在 HBuilderX 中使用 tailwindcss
- 在 HBuilderX 中使用 tailwindcss
之前我写了一个 weapp-tailwindcss-webpack-plugin
来兼容 uni-app
,taro
等等各个框架,不过那时候提供的 demo
都是 cli
版本的。最近社区里有同学问我, HBuilderX
要如何使用?
今天就给大家带来 HBuilderX
中 vue2
和 vue3
各自的 tailwindcss
的使用方法。
快速使用模板
如果你只想直接使用,而不在意 从 0 到 1 的搭建过程的话,你可以直接使用这 2
个模板。
uni-app-vue2-tailwind-hbuilder-template
uni-app-vue3-tailwind-hbuilder-template
下载下来后,先本地 npm i
/yarn
安装一下依赖,然后就可以直接导入 HBuilderX
使用了。
从 0 到 1 的搭建过程
vue2 版本
vue2
版本的uni-app
内置的webpack
版本为4
,postcss
版本为7
, 所以还是只能使用@tailwindcss/postcss7-compat
版本。
package.json
新建一个vue2 uni-app
项目,然后我们 npm init -y
在项目根目录创建一个 package.json
,并安装依赖:
{
"devDependencies": {
"autoprefixer": "9",
"postcss": "7",
"postcss-rem-to-responsive-pixel": "^5.1.3",
"tailwindcss": "npm:@tailwindcss/postcss7-compat",
"weapp-tailwindcss-webpack-plugin": "^1.6.8",
"webpack": "npm:webpack@webpack-4"
}
}
vue.config.js
然后添加 vue.config.js
文件,注册 weapp-tailwindcss-webpack-plugin
:
// 为了 tailwindcss jit 开发时的热更新
if (process.env.NODE_ENV === "development") {
process.env.TAILWIND_MODE = "watch";
}
const {
UniAppWeappTailwindcssWebpackPluginV4,
} = require("weapp-tailwindcss-webpack-plugin");
/**
* @type {import('@vue/cli-service').ProjectOptions}
*/
const config = {
//....
configureWebpack: {
plugins: [new UniAppWeappTailwindcssWebpackPluginV4()],
},
//....
};
module.exports = config;
postcss.config.js
然后再添加 postcss.config.js
const path = require("path");
module.exports = {
plugins: [
require("autoprefixer")({
remove: process.env.UNI_PLATFORM !== "h5",
}),
require("tailwindcss")({
config: path.resolve(__dirname, "./tailwind.config.js"),
}),
// rem 转 rpx
require("postcss-rem-to-responsive-pixel/postcss7")({
rootValue: 32,
propList: ["*"],
transformUnit: "rpx",
}),
],
};
这里特别注意,在声明所有路径时,必须声明为绝对路径!!!
因为 hbuilderx
有这样一个读取配置的策略:如果目标目录是相对路径,就会读取 '\HBuilderX\plugins\uniapp-cli\'
目录下的文件,这直接导致配置找不到,导致项目无法启动。
tailwind.config.js
接着我们添加 tailwind.config.js
const path = require("path");
const resolve = (p) => {
return path.resolve(__dirname, p);
};
/** @type {import('@types/tailwindcss/tailwind-config').TailwindConfig} */
module.exports = {
mode: "jit",
purge: {
content: [
resolve("./index.html"),
resolve("./pages/**/*.{vue,js,ts,jsx,tsx,wxml}"),
],
},
darkMode: false, // or 'media' or 'class'
theme: {
extend: {},
},
variants: {},
plugins: [],
corePlugins: {
preflight: false,
},
};
同样,content
也必须为绝对路径。
在 App.vue
中引入 tailwindcss
最后只需在 App.vue
引入即可:
<style lang="scss">
/*每个页面公共css */
@import "tailwindcss/base";
@import "tailwindcss/utilities";
</style>
现在,你就可以在 hbuilder
的vue2
项目中愉快的使用 tailwindcss
了!
vue3 版本
uni-app
的vue3/vite
版本,使用了rollup base
的插件。
暂时不要升级到vite 3.x
版本,目前uni-app
并没有兼容这个版本,详见 Release Notes, 安装2.x
版本的最新即可。(3.x
会报process is not defined
的错误)
package.json
我们 npm init -y
在项目根目录创建一个 package.json
,并安装依赖:
{
"devDependencies": {
"autoprefixer": "^10.4.8",
"postcss": "^8.4.14",
"postcss-rem-to-responsive-pixel": "^5.1.3",
"tailwindcss": "^3.1.7",
"weapp-tailwindcss-webpack-plugin": "^1.6.10"
}
}
vite.config.js
然后添加 vite.config.js
文件,注册 weapp-tailwindcss-webpack-plugin
:
import path from "path";
import { defineConfig } from "vite";
import uni from "@dcloudio/vite-plugin-uni";
import vwt from "weapp-tailwindcss-webpack-plugin/vite";
import postcssWeappTailwindcssRename from "weapp-tailwindcss-webpack-plugin/postcss";
const isH5 = process.env.UNI_PLATFORM === "h5";
// vite 插件配置,注意一定要把 uni 注册在 vwt 前
const vitePlugins = [uni()];
const resolve = (p) => {
return path.resolve(__dirname, p);
};
const postcssPlugins = [
require("autoprefixer")(),
require("tailwindcss")({
config: resolve("./tailwind.config.js"),
}),
];
if (!isH5) {
vitePlugins.push(vwt());
postcssPlugins.push(postcssWeappTailwindcssRename({}));
}
// https://vitejs.dev/config/
export default defineConfig({
plugins: vitePlugins,
css: {
postcss: {
// 内联写法
plugins: postcssPlugins,
},
},
});
tailwind.config.js
添加 tailwind.config.js
:
const path = require("path");
const resolve = (p) => {
return path.resolve(__dirname, p);
};
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ["./index.html", "./**/*.vue"].map(resolve),
theme: {
extend: {},
},
plugins: [],
corePlugins: {
preflight: false,
},
};
下面这点在上面的 vue2
中也提到了,我再重复一遍
这里特别注意,在声明所有路径时,必须声明为绝对路径!!!
因为 hbuilderx
有这样一个读取配置的策略:如果目标目录是相对路径,就会读取 '\HBuilderX\plugins\uniapp-cli\'
目录下的文件,这直接导致配置找不到,导致项目无法启动。
在 App.vue
中引入 tailwindcss
<style lang="scss">
/*每个页面公共css */
@import "tailwindcss/base";
@import "tailwindcss/utilities";
</style>
现在,你就可以在 hbuilderx
的 vue3
项目中愉快的使用 tailwindcss
了!
其他配置
.gitignore
unpackage
node_modules
.hbuilderx
HbuilderX 智能提示工具
DCloud-HBuilderX团队提供了对应的插件,可以去
https://ext.dcloud.net.cn/plugin?id=8560 进行下载,即可产生智能提示。
关联项目
插件核心
weapp-tailwindcss-webpack-plugin 提供核心转义功能
CLI 工具
weapp-ide-cli: 一个微信开发者工具命令行,快速方便的直接启动 ide 进行登录,开发,预览,上传代码等等功能。
模板 template
uni-app-vite-vue3-tailwind-vscode-template
uni-app-vue3-tailwind-vscode-template
uni-app-vue2-tailwind-vscode-template
weapp-native-mina-tailwindcss-template
uni-app-vue2-tailwind-hbuilder-template
uni-app-vue3-tailwind-hbuilder-template
预设 tailwindcss preset
tailwindcss-miniprogram-preset
Bugs & Issues
在 HBuilderX 中使用 tailwindcss
- 在 HBuilderX 中使用 tailwindcss
之前我写了一个 weapp-tailwindcss-webpack-plugin
来兼容 uni-app
,taro
等等各个框架,不过那时候提供的 demo
都是 cli
版本的。最近社区里有同学问我, HBuilderX
要如何使用?
今天就给大家带来 HBuilderX
中 vue2
和 vue3
各自的 tailwindcss
的使用方法。
快速使用模板
如果你只想直接使用,而不在意 从 0 到 1 的搭建过程的话,你可以直接使用这 2
个模板。
uni-app-vue2-tailwind-hbuilder-template
uni-app-vue3-tailwind-hbuilder-template
下载下来后,先本地 npm i
/yarn
安装一下依赖,然后就可以直接导入 HBuilderX
使用了。
从 0 到 1 的搭建过程
vue2 版本
vue2
版本的uni-app
内置的webpack
版本为4
,postcss
版本为7
, 所以还是只能使用@tailwindcss/postcss7-compat
版本。
package.json
新建一个vue2 uni-app
项目,然后我们 npm init -y
在项目根目录创建一个 package.json
,并安装依赖:
{
"devDependencies": {
"autoprefixer": "9",
"postcss": "7",
"postcss-rem-to-responsive-pixel": "^5.1.3",
"tailwindcss": "npm:@tailwindcss/postcss7-compat",
"weapp-tailwindcss-webpack-plugin": "^1.6.8",
"webpack": "npm:webpack@webpack-4"
}
}
vue.config.js
然后添加 vue.config.js
文件,注册 weapp-tailwindcss-webpack-plugin
:
// 为了 tailwindcss jit 开发时的热更新
if (process.env.NODE_ENV === "development") {
process.env.TAILWIND_MODE = "watch";
}
const {
UniAppWeappTailwindcssWebpackPluginV4,
} = require("weapp-tailwindcss-webpack-plugin");
/**
* @type {import('@vue/cli-service').ProjectOptions}
*/
const config = {
//....
configureWebpack: {
plugins: [new UniAppWeappTailwindcssWebpackPluginV4()],
},
//....
};
module.exports = config;
postcss.config.js
然后再添加 postcss.config.js
const path = require("path");
module.exports = {
plugins: [
require("autoprefixer")({
remove: process.env.UNI_PLATFORM !== "h5",
}),
require("tailwindcss")({
config: path.resolve(__dirname, "./tailwind.config.js"),
}),
// rem 转 rpx
require("postcss-rem-to-responsive-pixel/postcss7")({
rootValue: 32,
propList: ["*"],
transformUnit: "rpx",
}),
],
};
这里特别注意,在声明所有路径时,必须声明为绝对路径!!!
因为 hbuilderx
有这样一个读取配置的策略:如果目标目录是相对路径,就会读取 '\HBuilderX\plugins\uniapp-cli\'
目录下的文件,这直接导致配置找不到,导致项目无法启动。
tailwind.config.js
接着我们添加 tailwind.config.js
const path = require("path");
const resolve = (p) => {
return path.resolve(__dirname, p);
};
/** @type {import('@types/tailwindcss/tailwind-config').TailwindConfig} */
module.exports = {
mode: "jit",
purge: {
content: [
resolve("./index.html"),
resolve("./pages/**/*.{vue,js,ts,jsx,tsx,wxml}"),
],
},
darkMode: false, // or 'media' or 'class'
theme: {
extend: {},
},
variants: {},
plugins: [],
corePlugins: {
preflight: false,
},
};
同样,content
也必须为绝对路径。
在 App.vue
中引入 tailwindcss
最后只需在 App.vue
引入即可:
<style lang="scss">
/*每个页面公共css */
@import "tailwindcss/base";
@import "tailwindcss/utilities";
</style>
现在,你就可以在 hbuilder
的vue2
项目中愉快的使用 tailwindcss
了!
vue3 版本
uni-app
的vue3/vite
版本,使用了rollup base
的插件。
暂时不要升级到vite 3.x
版本,目前uni-app
并没有兼容这个版本,详见 Release Notes, 安装2.x
版本的最新即可。(3.x
会报process is not defined
的错误)
package.json
我们 npm init -y
在项目根目录创建一个 package.json
,并安装依赖:
{
"devDependencies": {
"autoprefixer": "^10.4.8",
"postcss": "^8.4.14",
"postcss-rem-to-responsive-pixel": "^5.1.3",
"tailwindcss": "^3.1.7",
"weapp-tailwindcss-webpack-plugin": "^1.6.10"
}
}
vite.config.js
然后添加 vite.config.js
文件,注册 weapp-tailwindcss-webpack-plugin
:
import path from "path";
import { defineConfig } from "vite";
import uni from "@dcloudio/vite-plugin-uni";
import vwt from "weapp-tailwindcss-webpack-plugin/vite";
import postcssWeappTailwindcssRename from "weapp-tailwindcss-webpack-plugin/postcss";
const isH5 = process.env.UNI_PLATFORM === "h5";
// vite 插件配置,注意一定要把 uni 注册在 vwt 前
const vitePlugins = [uni()];
const resolve = (p) => {
return path.resolve(__dirname, p);
};
const postcssPlugins = [
require("autoprefixer")(),
require("tailwindcss")({
config: resolve("./tailwind.config.js"),
}),
];
if (!isH5) {
vitePlugins.push(vwt());
postcssPlugins.push(postcssWeappTailwindcssRename({}));
}
// https://vitejs.dev/config/
export default defineConfig({
plugins: vitePlugins,
css: {
postcss: {
// 内联写法
plugins: postcssPlugins,
},
},
});
tailwind.config.js
添加 tailwind.config.js
:
const path = require("path");
const resolve = (p) => {
return path.resolve(__dirname, p);
};
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ["./index.html", "./**/*.vue"].map(resolve),
theme: {
extend: {},
},
plugins: [],
corePlugins: {
preflight: false,
},
};
下面这点在上面的 vue2
中也提到了,我再重复一遍
这里特别注意,在声明所有路径时,必须声明为绝对路径!!!
因为 hbuilderx
有这样一个读取配置的策略:如果目标目录是相对路径,就会读取 '\HBuilderX\plugins\uniapp-cli\'
目录下的文件,这直接导致配置找不到,导致项目无法启动。
在 App.vue
中引入 tailwindcss
<style lang="scss">
/*每个页面公共css */
@import "tailwindcss/base";
@import "tailwindcss/utilities";
</style>
现在,你就可以在 hbuilderx
的 vue3
项目中愉快的使用 tailwindcss
了!
其他配置
.gitignore
unpackage
node_modules
.hbuilderx
HbuilderX 智能提示工具
DCloud-HBuilderX团队提供了对应的插件,可以去
https://ext.dcloud.net.cn/plugin?id=8560 进行下载,即可产生智能提示。
关联项目
插件核心
weapp-tailwindcss-webpack-plugin 提供核心转义功能
CLI 工具
weapp-ide-cli: 一个微信开发者工具命令行,快速方便的直接启动 ide 进行登录,开发,预览,上传代码等等功能。
模板 template
uni-app-vite-vue3-tailwind-vscode-template
uni-app-vue3-tailwind-vscode-template
uni-app-vue2-tailwind-vscode-template
weapp-native-mina-tailwindcss-template
uni-app-vue2-tailwind-hbuilder-template
uni-app-vue3-tailwind-hbuilder-template
预设 tailwindcss preset
tailwindcss-miniprogram-preset