小程序 vant 项目记录总结 使用 scss 分享 订阅消息 wxs 分包 echarts图表 canvas getCurrentPages页面栈
小程序 + vant
vant
下载
npm init -ynpm i @vant/weapp -S --production
修改 app.json
将 app.json 中的 “style”: “v2” 去除
修改 project.config.json
{..."setting": {..."packNpmManually": true,"packNpmRelationList": [{"packageJsonPath": "./package.json","miniprogramNpmDistDir": "./"}]}
}
构建 npm 包
打开微信开发者工具,点击 工具 -> 构建 npm,并勾选 使用 npm 模块 选项,构建完成后,即可引入组件。
van-dialog
before-close 回调函数使用
不需要 confirm,cancel 事件
<van-dialog use-slot show="{{ show }}" before-close="{{ beforeClose }}"></van-dialog>
Page({onLoad() {this.setData({beforeClose: (action) => this.confirmScore(action),});},confirmScore(action) {return new Promise((resolve, reject) => {if (action === "cancel") return resolve(true);if (action === "confirm") {if (...) return resolve(false);return resolve(true);}});},
})
小程序
使用 typescript、less、sass
编译插件配置,目前支持编译插件有 typescript、less、sass
project.config.json
{"setting": {"useCompilerPlugins": ["typescript","sass"]}
}
表示项目支持直接使用 typescript 和 sass
.wxss 文件命名 .scss
setData 多种赋值写法
const index = 0;data: {list: [{page: 1,limit: 10,data: [],finished: false,},],obj: {name:'ls',},name: 'ls'
},
this.setData({name: 'xr',obj: {},'obj.name': 'xr','list[0].finished': true,`list[${index}].data`: [],[`list[${index}].data`]: []
})
getCurrentPages 页面栈使用
const pages = getCurrentPages();
const prePage = pages[pages.length - 2];// 获取上一页数据
console.log("prePage", prePage?.data.detail);
// 调用上一页方法
prePage?.save();
// 修改上一页数据
prePage.setData({"detail.name": "xr",
});
request 请求封装
封装 request
utils/http.js
import getBaseUrl from "./config";
import log from "./log";class CustomRequestInstance {static instance = null;static getInstance() {if (!this.instance) {this.instance = new CustomRequestInstance();}return this.instance;}request({ url = "", method = "get", data = {}, headers = {} }) {return new Promise((resolve, reject) => {wx.request({url: getBaseUrl() + url,header: {"content-type": "application/json",Authorization: `Bearer ${wx.getStorageSync("token")}`,...headers,},method: method.toUpperCase(),data: {...data,},success: function (res) {},fail: function (err) {log.error(`request-${url}-${err}`);reject(err);},});});}
}export default CustomRequestInstance;
封装 api
services/common.js
import Services from "../utils/http";const http = Services.getInstance();class CommonServices {// 获取城市async getCity() {const res = await http.request({ url: "/city" });return res;}
}export default new CommonServices();
使用
import CommonServices from "../../../services/common";const res = await CommonServices.getCity();
upload 封装
import getUrl from "./config";/*** uploadFile 封装* @param {*} Object { name = "file", filePath, ...rest }** @see [https://developers.weixin.qq.com/miniprogram/dev/api/media/video/wx.chooseMedia.html](https://developers.weixin.qq.com/miniprogram/dev/api/media/video/wx.chooseMedia.html)*/
export function customUpload({ name = "file", filePath, ...rest }) {return new Promise((resolve, reject) => {wx.uploadFile({url: `${getUrl()}/upload/image`,filePath,name,header: {Authorization: `Bearer ${wx.getStorageSync("token")}`,},...rest,success(res) {resolve(JSON.parse(res.data));},fail(error) {reject(error);},});});
}
组件
components/test/test.json
{"component": true,"usingComponents": {"van-icon": "@vant/weapp/icon/index"}
}
components/test/test.wxml
<view wx:if="{{show}}" class="mask"><van-icon class="remove" name="cross" catchtap="handleClose" />
</view>
components/test/test.js
Component({options: {// 在组件定义时的选项中启用多slot支持multipleSlots: true,// 使用全局 app.wxssaddGlobalClass: true,},/*** 组件的属性列表*/properties: {show: {type: Boolean,value: false,},},/*** 组件的初始数据*/data: {},// 监听observers: {show: function (newVal) {console.log("newVal", newVal);},},// // 生命周期函数,可以为函数,或一个在methods段中定义的方法名lifetimes: {// 可以使用 setDataattached: function () {console.log("attached");},moved: function () {console.log("moved");},detached: function () {console.log("detached");},},// // 组件所在页面的生命周期函数pageLifetimes: {// 页面进入show: function () {console.log("show");},// 页面离开hide: function () {console.log("hide");},resize: function () {console.log("resize");},},/*** 组件的方法列表*/methods: {handleClose() {this.triggerEvent("close", { flag: false });},},
});
- 实现默认插槽
Component({properties: {useDefaultSlot: {type: Boolean,value: false,},},
});
components/test/test.js
<view><view wx:if="{{ !useDefaultSlot }}">默认值</view><slot wx:else></slot><slot name="after"></slot>
</view>
{"usingComponents": {"x-text": "/components/test/test"}
}
<x-text useDefaultSlot><view>默认插槽</view><view slot="after">after 插槽</view>
</x-text>
- 向外提供样式类
<view class="custom-class"></view>
Component({externalClasses: ["custom-class"],
});
<x-text custom-class="text-14px"></x-text>
- 获取组件实例
可在父组件里调用 this.selectComponent ,获取子组件的实例对象。
父组件
Page({getChildComponent: function () {const child = this.selectComponent(".my-component");},
});
wxs 使用
在当前 wxml 中
<view wx:if="{{util.isHas(idList, userId)}}"></view><wxs module="util">
function isHas(arr, val) {return arr.indexOf(val) >= 0
}
module.exports.isHas = isHas
</wxs>
单独封装方法
utils/utils.wxs
module.exports = {formatNums: function (val) {if (val >= 1000) {val = (val / 1000) + 'K'}return val},
}<wxs module="tools" src="/utils/utils.wxs"></wxs>{{tools.formatNums(item.type)}}
获取元素信息 wx.createSelectorQuery()
如果在组件中,使用 this.createSelectorQuery()
const query = wx.createSelectorQuery();
query.select(".content").boundingClientRect();
query.exec((res) => {});
获取列表数据/加载更多/下拉刷新
data: {list: [{page: 1,limit: 10,data: [],finished: false,},],
},onReachBottom() {this.getData();
},
async onPullDownRefresh() {await this.getData(true);wx.stopPullDownRefresh();
},
async getData(refresh = false) {try {const index = 0;let { page, limit, data, finished } = this.data.list[index];if (refresh) {page = 1;finished = false;}if (finished) return;const res = await SkillServices.getFairList(page, limit);let list = [];if (res?.data?.length < limit) finished = true;else finished = false;if (refresh) list = res?.data;else list = [...data, ...res.data];this.setData({[`list[${index}].data`]: list,[`list[${index}].page`]: page + 1,[`list[${index}].finished`]: finished,});} catch (error) {console.log(error);}
},
实现文本隐藏展示查看更多功能
text-ellipsis.wxml
<view class="relative" wx:if="{{desc}}"><text class="{{showMore?'x-ellipsis--l3':''}} " style="line-height: {{lineHight}}px" ><text catchtap="handleLink">{{desc}}</text><text class="absolute primary more" bindtap="handleReadMore" wx:if="{{showMore}}">查看全部</text><text class="absolute primary more" bindtap="handleHideMore" wx:if="{{isExceed && !showMore}}">收起</text></text>
</view>
<block wx:else><slot></slot>
</block>
text-ellipsis.js
// pages/mine/visit/components/text-ellipsis/text-ellipsis.js
Component({options: {addGlobalClass: true,},properties: {lineHight: {type: Number,value: 22,},desc: {type: null,value: "",},},data: {showMore: false,isExceed: false, // 是否超过三行},observers: {desc(newValue) {// 如果当前被截断则直接返回if (this.data.showMore) return;if (newValue) this.init();},},methods: {handleLink() {this.triggerEvent("link");},handleHideMore() {this.setData({ showMore: true });},handleReadMore() {this.setData({ showMore: false });},init() {const { lineHight } = this.data;let showMore = false;let isExceed = false;var query = this.createSelectorQuery();query.select(".content").boundingClientRect();query.exec((res) => {var height = res[0]?.height;if (!height) return;var line = height / lineHight;if (line > 3) {showMore = true;isExceed = true;} else {showMore = false;isExceed = false;}this.setData({ showMore, isExceed });});},},
});
.more {bottom: 0;right: 0;background: #fff;padding-left: 10rpx;
}
.relative {position: relative;
}
.absolute {position: absolute;
}
.primary {color: var(--primary);
}
引入组件
{"usingComponents": {"x-text-ellipsis": "/components/text-ellipsis/text-ellipsis"}
}
<x-text-ellipsis desc="{{userInfo.desc}}"><view class="text-sm text-aaa">暂未填写简介</view>
</x-text-ellipsis>
订阅消息封装
export const requestSubscribeMessage = (tmplIds = ["MLCQvuq6kWY-jbH8Cxn-veoPZ6gJ8QTWiBpMV96mjs0"]) => {wx.requestSubscribeMessage({tmplIds,success(res) {console.log("requestSubscribeMessage res", res);// MLCQvuq6kWY-jbH8Cxn-veoPZ6gJ8QTWiBpMV96mjs0: "reject" 取消// MLCQvuq6kWY-jbH8Cxn-veoPZ6gJ8QTWiBpMV96mjs0: "accept" 同意tmplIds.forEach((tmplId) => {if (res[tmplId] === "accept") console.log(tmplId, "同意了");else if (res[tmplId] === "reject") console.log(tmplId, "拒绝了");});},fail(err) {console.log("requestSubscribeMessage err", err);},});
};
分享
onShareAppMessage(){return {title: '**',path: '/pages**',imageUrl: '/static/share.png'}
}
分包
others/pages/mine/mine.wxml
app.json
..."subPackages": [{"root": "others","pages": ["pages/mine/mine"]}],
防抖、节流
css
动画
/* pages/idea/form/form.wxss */@keyframes opacity-show {0% {opacity: 0;}to {opacity: 1;}
}
@keyframes opacity-hide {0% {opacity: 1;}to {opacity: 0;}
}@keyframes scale-show {0% {transform: scale(0);}to {transform: scale(1);}
}
@keyframes scale-hide {0% {transform: scale(1);}to {transform: scale(0);}
}
<view style="animation: opacity-show 2s ease,scale-show 2s ease;"></view>
.x-ellipsis {overflow: hidden;white-space: nowrap;text-overflow: ellipsis;
}
.x-ellipsis--l2,
.x-ellipsis--l3 {-webkit-box-orient: vertical;display: -webkit-box;overflow: hidden;text-overflow: ellipsis;
}
.x-ellipsis--l2 {-webkit-line-clamp: 2;
}
.x-ellipsis--l3 {-webkit-line-clamp: 3;
}.arrow::after {content: "";width: 15rpx;height: 15rpx;border-top: 3rpx solid ##ccc;border-right: 3rpx solid ##ccc;transform: rotate(45deg);
}/* 数字、字母过长不换行 */
.break-all {word-break: break-all;
}scroll-view::-webkit-scrollbar {width: 0;height: 0;color: transparent;
}
修改 vant css 变量
page {--van-picker-confirm-action-color: #08bebe;
}
修改 input placeholder 样式
<input value="{{ keyword }}" placeholder-class="placeholder-class" placeholder="请输入" bindinput="handleInput" />
.placeholder-class {color: #bbbbbb;
}
textarea 设置行高后,光标与 placeholder 不对齐
解决方案:使用 text 替换 placeholder
iPhone 13 pro 遇到的问题:
text 不要放在 textarea 标签内
定位后,给 text 一个事件,自动获取焦点
<view class="relative"><textareaclass="absolute left-0 top-0"focus="{{focus}}"bindblur="onBlur"model:value="{{value}}"disable-default-paddingmaxlength="{{-1}}"/><text class="text-aaa text-14px leading-28px absolute left-0 top-0" bindtap="onFocus" wx:if="{{!value}}">提示:请输入内容请输入内容请输入内容请输入内容请输入内容</text>
</view>
Page({data: {focus: false,value: "",},onFocus() {this.setData({ focus: true });},onBlur() {this.setData({ focus: false });},
});
Ios 底部安全距离
page {--ios-safe-bottom-low: constant(safe-area-inset-bottom); /* 兼容 iOS<11.2 */--ios-safe-bottom-higt: env(safe-area-inset-bottom); /* 兼容iOS>= 11.2 */
}
.safe-area-inset-bottom {padding-bottom: var(--ios-safe-bottom-low);padding-bottom: var(--ios-safe-bottom-higt);
}
setFormValue(value, num = undefined) {value = value.trim();if (num) value = value.slice(0, num);else value = value.slice(0);return value;
},
echarts-for-weixin
动态设置数据如下
echarts-for-weixin
xx.json
{"usingComponents": {"ec-canvas": "../../ec-canvas/ec-canvas"}
}
xx.wxml
<view class="container"><ec-canvas id="mychart-dom-bar" canvas-id="mychart-bar" ec="{{ ec }}"></ec-canvas></view>
xx.wxss
ec-canvas {width: 100%;height: 100%;}
xx.js
import * as echarts from '../../ec-canvas/echarts';let chart = null;
let option;
function initChart(canvas, width, height, dpr) {chart = echarts.init(canvas, null, {width: width,height: height,devicePixelRatio: dpr // 像素});canvas.setChart(chart);option = {xAxis: {type: "category",data: ["今日已完成", "本周已完成", "本月已完成", "本季度已完成"],},yAxis: {type: "value",},series: [{data: [10, 20, 150, 8],type: "bar",},],};chart.setOption(option);return chart;
}Page({data: {ec: {onInit: initChart}},onLoad() {setTimeout(() => {option.series[0].data = [10, 20, 150, 8, 70]chart.setOption(option);}, 2000);},
});
相关文章:
小程序 vant 项目记录总结 使用 scss 分享 订阅消息 wxs 分包 echarts图表 canvas getCurrentPages页面栈
小程序 vant vant 下载 npm init -ynpm i vant/weapp -S --production修改 app.json 将 app.json 中的 “style”: “v2” 去除 修改 project.config.json {..."setting": {..."packNpmManually": true,"packNpmRelationList": [{"p…...

关于Power Query中一些忽略的细节
Power Query中一些忽略的细节 重新认识Power Query查询的引用----提高数据加载效率透视逆透视----一对“好朋友”神奇的拼接----实现很多意想不到的操作 重新认识Power Query 关于它的定义,这里不再赘述,主要说一些新的理解。 Power Query 可以理解就是一…...
QML与C++交互
目录 1 QML获取C的变量值 2 QML获取C创建的自定义对象 3 QML发送信号绑定C端的槽 4 C端发送信号绑定qml端槽 5 C调用QML端函数 1 QML获取C的变量值 QQmlApplicationEngine engine; 全局对象 上下文属性 QQmlApplicationEngine engine; QQmlContext *context1 engine.…...

Microsoft ISA服务器配置及日志分析
Microsoft ISA 分析器工具,可分析 Microsoft ISA 服务器(或 Forefront 威胁管理网关服务器)的日志并生成安全和流量报告。支持来自 Microsoft ISA 服务器组件的以下日志: 数据包过滤器ISA 服务器防火墙服务ISA 服务器网络代理服务…...

Openlayers 实战 - 地图视野(View)- 图层 -(layer)- 资源(source)显示等级设置。
Openlayers 实战 - 地图视野(View)- 图层 -(layer)- 资源(source)显示等级设置。 问题原因核心代码完整代码:在线示例 在以往的项目维护中,出现一个问题,使用最新高清底图…...

Linux:shell脚本 正则表达式与AWK
一、正则表达式 由一类特殊字符及文本字符所编写的模式,其中有些字符(元字符)不表示字符字面意义,而表示控制或通配的功能,类似于增强版的通配符功能,但与通配符不同,通配符功能是用来处理文件…...

Android UI自动化测试框架—SoloPi简介
1、UI自动化测试简介 软件测试简介 软件测试是伴随着软件开发一同诞生的,随着软件规模大型化,结构复杂化,软件测试也从最初的简单“调试”,发展到当今的自动化测试。 自动化测试是什么呢?自动化测试是把以人为…...
Android Studio Giraffe 正式版下载地址
Android Studio 是 Android 的官方 IDE。它专为 Android 而打造,可以加快您的开发速度,帮助您为每款 Android 设备构建最高品质的应用。 比以往更快地编码和迭代 Android Studio 基于 IntelliJ IDEA 而构建,可以提供较短的编码和运行工作流…...

【C语言】调试技巧
目录 一、什么是bug? 二、调试 1.一般调试的步骤 2.Debug 和 Release 三、调试环境准备 四、调试时要查看的信息 1.查看临时变量的值 2.查看内存信息 3.查看调用堆栈 4.查看反汇编信息 5.查看寄存器 五、练习 六、常见的coding技巧 七、const的作用 八、编程常见…...

MySQL SUBSTRING_INDEX() 函数的详细介绍
MySQL SUBSTRING_INDEX() 从给定字符串中返回指定数量的分隔符出现之前的子字符串。 当指定数字为正数时从最终分隔符的左侧返回子字符串,当指定数字为负数时从最终分隔符的右侧返回子字符串。 如果指定的次数大于分隔符的出现次数,则返回的子字符串将…...

开源数据库Mysql_DBA运维实战 (DML/DQL语句)
DML/DQL DML INSERT 实现数据的 插入 实例: DELETE 实现数据的 删除 实例: UPDATE 实现数据的 更新 实例1: 实例2: 实例3: DQL DML/DQL DML语句 数据库操纵语言: 插入数据INSERT、删除数据DELE…...

【LangChain】Memory
概要 大多数LLM应用都有对话界面。对话的一个重要组成部分是能够引用对话中先前介绍的信息。至少,对话系统应该能够直接访问过去消息的某些窗口。更复杂的系统需要有一个不断更新的世界模型,这使得它能够执行诸如维护有关实体及其关系的信息之类的事情。…...

Java并发编程(六)线程池[Executor体系]
概述 在处理大量任务时,重复利用线程可以提高程序执行效率,因此线程池应运而生。 它是一种重用线程的机制,可以有效降低内存资源消耗提高响应速度。当任务到达时,任务可以不需要的等到线程创建就能立即执行线程池可以帮助我们更好地管理线程的生命周期和资源使用,…...

macOS CLion 使用 bits/stdc++.h
macOS 下 CLion 使用 bits/stdc.h 头文件 terminal运行 brew install gccCLion里配置 -D CMAKE_CXX_COMPILER/usr/local/bin/g-11...

PS出现的问题——为什么PS另存的格式少了很多
在WIN11系统里面新安装的22和23版本PS会出现另存格式少的情况 解决方式:编辑——首选项——文件处理——开启旧版储存为 解决...
【Linux】进程通信篇Ⅱ:共享内存、消息队列、信号量
文章目录 一、共享内存1.1 一些接口1. shmget 函数:申请一个 system v 的共享内存块2. ftok 函数:设置唯一标识码3. shmctl 函数:控制 system v 的共享内存块(可以删除、查看...)4. shmat 函数:将进程与共享…...
8.14 校招 内推 面经
绿泡泡: neituijunsir 交流裙,内推/实习/校招汇总表格 1、半导体芯片一周资讯 - 小米OPPO之后,星纪魅族调整芯片业务,今年应届生或被全部优化,英伟达2024推出比H100更快的芯片 半导体芯片一周资讯 - 小米OPPO之后&…...

阿里云服务器安装部署Docker使用教程
本文阿里云百科分享如何在云服务ECS实例上,部署并使用Docker。Docker是一款开源的应用容器引擎,具有可移植性、可扩展性、高安全性和可管理性等优势。开发者可将应用程序和依赖项打包到一个可移植的容器中,快速发布到Linux机器上并实现虚拟化…...

WebRTC | ICE详解
目录 一、Candidate种类与优先级 二、ICE策略 1. iceServers 2. iceTransportPolicy 三、P2P连接 1.Nat类型 (1)完全锥型NAT (2)IP限制锥型NAT (3)端口限制锥型NAT (4)对称…...

网络设备(防火墙、路由器、交换机)日志分析监控
外围网络设备(如防火墙、路由器、交换机等)是关键组件,因为它们控制进出公司网络的流量。因此,监视这些设备的活动有助于 IT 管理员解决操作问题,并保护网络免受攻击者的攻击。通过收集和分析这些设备的日志来监控这些…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】
微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来,Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...

376. Wiggle Subsequence
376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...

ArcGIS Pro制作水平横向图例+多级标注
今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作:ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等(ArcGIS出图图例8大技巧),那这次我们看看ArcGIS Pro如何更加快捷的操作。…...

初学 pytest 记录
安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...

AI病理诊断七剑下天山,医疗未来触手可及
一、病理诊断困局:刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断",医生需通过显微镜观察组织切片,在细胞迷宫中捕捉癌变信号。某省病理质控报告显示,基层医院误诊率达12%-15%,专家会诊…...
Java数值运算常见陷阱与规避方法
整数除法中的舍入问题 问题现象 当开发者预期进行浮点除法却误用整数除法时,会出现小数部分被截断的情况。典型错误模式如下: void process(int value) {double half = value / 2; // 整数除法导致截断// 使用half变量 }此时...
WEB3全栈开发——面试专业技能点P7前端与链上集成
一、Next.js技术栈 ✅ 概念介绍 Next.js 是一个基于 React 的 服务端渲染(SSR)与静态网站生成(SSG) 框架,由 Vercel 开发。它简化了构建生产级 React 应用的过程,并内置了很多特性: ✅ 文件系…...

边缘计算网关提升水产养殖尾水处理的远程运维效率
一、项目背景 随着水产养殖行业的快速发展,养殖尾水的处理成为了一个亟待解决的环保问题。传统的尾水处理方式不仅效率低下,而且难以实现精准监控和管理。为了提升尾水处理的效果和效率,同时降低人力成本,某大型水产养殖企业决定…...

Appium下载安装配置保姆教程(图文详解)
目录 一、Appium软件介绍 1.特点 2.工作原理 3.应用场景 二、环境准备 安装 Node.js 安装 Appium 安装 JDK 安装 Android SDK 安装Python及依赖包 三、安装教程 1.Node.js安装 1.1.下载Node 1.2.安装程序 1.3.配置npm仓储和缓存 1.4. 配置环境 1.5.测试Node.j…...

Linux系统:进程间通信-匿名与命名管道
本节重点 匿名管道的概念与原理匿名管道的创建命名管道的概念与原理命名管道的创建两者的差异与联系命名管道实现EchoServer 一、管道 管道(Pipe)是一种进程间通信(IPC, Inter-Process Communication)机制,用于在不…...