
uni-app 实现好看易用的抽屉效果
一. 前言
我之前使用 uni-app 和 uniCloud 开发了一款软考刷题应用,在这个应用中,我使用了抽屉组件来实现一些功能,切换题库,如下图所示:
在移动应用开发中,抽屉(Drawer)是一种常见的界面设计模式,这个组件可以在需要侧边导航或者额外信息展示的地方使用。它允许用户通过侧滑的效果打开一个菜单或额外的内容区域。
这种设计不仅能够节省屏幕空间,还能提供一种直观的交互方式。
例如,在电商应用中,可以将购物车或分类列表放在抽屉里;在新闻阅读器中,可以放置频道选择等;而在有题记刷题软件中,我主要用于题库的选择功能。
本文将介绍如何使用 uni-app 框架来实现一个简单的抽屉组件:DrawerWindow。文末提供完整的代码示例,让你能够轻松地在 uni-app 中实现抽屉效果。
看新机会的
技术大厂,待遇之类的给的还可以,就是偶尔有加班(放心,加班有加班费)
前后端测试捞人,多地有空位,感兴趣的可以试试~
二. 实现分析
Vue 组件的结构通常由三个主要部分组成:模板(<template>)、脚本(<script>)和样式(<style>),标准的的单文件组件(SFC)结构。
uni-app 也是如此,在这个组件中,我们也将使用 Vue 的单文件组件(SFC)结构,这意味着我们将在一个 .vue 文件中同时包含模板、脚本和样式。
接下来我们按照这个格式来简单实现一下。
-
- 模板页面 (<template>)
首先,模版页面是很简单的部分,我们需要创建一个基础的 Vue 组件,该组件包含了主页面、抽屉内容和关闭按钮三个部分。以下是组件的模板代码:
<template>
<view class="drawer-window-wrap">
<scroll-view scroll-y class="DrawerPage" :class="{ show: modalName === 'viewModal' }">
<!-- 主页面 -->
<slot></slot>
</scroll-view>
<!-- 关闭抽屉 -->
<view class="DrawerClose" :class="{ show: modalName === 'viewModal' }" @tap="hide">
<u-icon name="backspace"></u-icon>
</view>
<!-- 抽屉页面 -->
<scroll-view scroll-y class="DrawerWindow" :class="{ show: modalName === 'viewModal' }">
<slot name="drawer"></slot>
</scroll-view>
</view>
</template>
- 模板页面 (<template>)
在模板部分,我们主要定义了三个主要元素:主页面、关闭按钮和抽屉页面。每个元素都有一个class绑定,这个绑定会根据 modalName 的状态来决定是否添加 .show 类。
主页面 (<scroll-view class="DrawerPage">):
这个滚动视图代表应用的主要内容区域。
当抽屉打开时,它会被缩小并移向屏幕右侧。
提供默认插槽 <slot></slot>,允许父组件传递自定义内容到这个位置。
关闭按钮 (<view class="DrawerClose">):
位于屏幕右侧的一个透明背景层,当点击时触发 hide() 方法来关闭抽屉。
包含了一个图标 <u-icon name="backspace"></u-icon>,这里使用的是 uView UI 库中的图标组件。你可以选用其他组件库里的图标或者图片。
抽屉页面 (<scroll-view class="DrawerWindow">):
这是抽屉本身的内容区域,通常包含菜单或其他附加信息。
同样地,定义特有的插槽名称,<slot name="drawer"></slot> 允许从外部插入特定的内容。
抽屉默认是隐藏的,并且当显示时会有动画效果。
在这里,我们主要使用了 <slot> 元素来定义可以插入自定义内容的位置。modalName 属性用来控制抽屉的状态。
- 逻辑处理 (<script>)
接下来,逻辑处理其实也很简单,主要会定义打开和关闭抽屉的方法:
javascript 代码解读复制代码<script>
export default {
data() {
return {
modalName: null
}
},
methods: {
// 打开抽屉
show() {
this.modalName = 'viewModal';
},
// 关闭抽屉
hide() {
this.modalName = null;
}
}
}
</script>
数据 (data):
modalName: 用于控制抽屉状态的数据属性。当它的值为 'viewModal' 时,表示抽屉处于打开状态;否则,抽屉是关闭的。
方法 (methods):
show(): 将 modalName 设置为'viewModal',从而通过 CSS 样式控制抽屉显示。
hide(): 将 modalName 重置为 null,控制抽屉隐藏。
当调用 show() 方法时,modalName 被设置为 'viewModal',这会触发 CSS 中的 .show 类,从而显示抽屉;反之,调用 hide() 方法则会隐藏抽屉。
- 样式设计 (<style>)
在这个组件中,其实要做好的在样式部分,主要是显示抽屉的动画部分。在主页面,我们主要定义了三个主要的样式类:主页面、关闭按钮和抽屉页面。
主页面样式 (DrawerPage):
初始状态下占据整个屏幕宽度和高度。
当抽屉打开时(即有.show类),页面会缩小并移动到屏幕右侧 85%的位置,同时增加阴影效果以模拟深度。
关闭按钮样式 (DrawerClose):
默认情况下是不可见且不响应用户交互的。
当抽屉打开时,按钮变为可见并可点击,提供了一种关闭抽屉的方式。
抽屉页面样式 (DrawerWindow):
初始状态下位于屏幕左侧外侧,不显示也不响应交互。
当抽屉打开时,抽屉平滑滑入屏幕内,变得完全可见且可以与用户互动。
动画与过渡
所有的 .show 类都带有 transition: all 0.4s;,这使得任何属性的变化都会有一个 0.4 秒的平滑过渡效果。
抽屉和主页面的 transform 属性被用来控制它们的位置和大小变化。
opacity 和 pointer-events 属性确保在不需要时抽屉不会影响用户的操作。
如下代码所示,我们主要添加一些 CSS 样式来实现平滑的过渡效果以及视觉上的美观:
scss 代码解读复制代码<style lang="scss">
// 省略其他样式...
.DrawerPage.show,
.DrawerWindow.show,
.DrawerClose.show {
transition: all 0.4s;
}
.DrawerPage.show {
transform: scale(0.9, 0.9) translateX(85vw);
box-shadow: 0 0 60rpx rgba(0, 0, 0, 0.2);
}
.DrawerWindow.show {
transform: scale(1, 1) translateX(0%);
opacity: 1;
pointer-events: all;
}
.DrawerClose.show {
width: 15vw;
color: #fff;
opacity: 1;
pointer-events: all;
}
</style>
以上的这些样式确保了当抽屉显示或隐藏时有流畅的动画效果,并且在不需要的时候不会影响用户的交互。
三. 完整代码
- 完整抽屉组件,复制可使用
html 代码解读复制代码<template>
<view class="drawer-window-wrap">
<scroll-view scroll-y class="DrawerPage" :class="modalName == 'viewModal' ? 'show' : ''">
<!-- 主页面 -->
<slot></slot>
</scroll-view>
<!-- 关闭抽屉 -->
<view class="DrawerClose" :class="modalName == 'viewModal' ? 'show' : ''" @tap="hide()">
<u-icon name="backspace"></u-icon>
</view>
<!-- 抽屉页面 -->
<scroll-view scroll-y class="DrawerWindow" :class="modalName == 'viewModal' ? 'show' : ''">
<slot name="drawer"></slot>
</scroll-view>
</view>
</template>
<script>
export default {
data() {
return {
modalName: null
}
},
methods: {
// 打开抽屉
show() {
this.modalName = 'viewModal'
},
// 关闭抽屉
hide() {
this.modalName = null
}
}
}
</script>
<style lang="scss">
page {
width: 100vw;
overflow: hidden !important;
}
.DrawerPage {
position: fixed;
width: 100vw;
height: 100vh;
left: 0vw;
background-color: #f1f1f1;
transition: all 0.4s;
}
.DrawerPage.show {
transform: scale(0.9, 0.9);
left: 85vw;
box-shadow: 0 0 60rpx rgba(0, 0, 0, 0.2);
transform-origin: 0;
}
.DrawerWindow {
position: absolute;
width: 85vw;
height: 100vh;
left: 0;
top: 0;
transform: scale(0.9, 0.9) translateX(-100%);
opacity: 0;
pointer-events: none;
transition: all 0.4s;
background-image: linear-gradient(45deg, #1cbbb4, #2979ff) !important;
}
.DrawerWindow.show {
transform: scale(1, 1) translateX(0%);
opacity: 1;
pointer-events: all;
}
.DrawerClose {
position: absolute;
width: 40vw;
height: 100vh;
right: 0;
top: 0;
color: transparent;
padding-bottom: 50rpx;
display: flex;
align-items: flex-end;
justify-content: center;
background-image: linear-gradient(90deg, rgba(0, 0, 0, 0.01), rgba(0, 0, 0, 0.6));
letter-spacing: 5px;
font-size: 50rpx;
opacity: 0;
pointer-events: none;
transition: all 0.4s;
}
.DrawerClose.show {
opacity: 1;
pointer-events: all;
width: 15vw;
color: #fff;
}
</style>
- 在父组件中使用抽屉组件
在父组件中,可以通过以下简单的代码使用它,你可以继续进行丰富:
html 代码解读复制代码<template>
<drawer-window ref="drawerWindow">
<view class="main-container" @click="$refs.drawerWindow.show()">
主页面,点击打开抽屉
</view>
<view slot="drawer" class="drawer-container"> 抽屉页面 </view>
</drawer-window>
</template>
<script>
export default {}
</script>
<style lang="scss" scoped>
.main-container,
.drawer-container {
font-weight: 700;
font-size: 20px;
text-align: center;
color: #333;
padding-top: 100px;
}
</style>
以上代码的实现效果如下图所示:
四. 小程序体验
以上的组件,来源于我独立开发的软考刷题小程序中的效果,想要体验或软考刷题的掘友可以参考以下文章,文末获取:
软考小工具重磅更新啦!最好用的软考刷题工具
五. 结语
通过以上步骤,我们已经构建了一个基本的抽屉组件。当然,你也可以根据具体的应用场景对这个组件进行进一步的定制和优化。
——转载自作者:前端梦工厂
一. 前言
我之前使用 uni-app 和 uniCloud 开发了一款软考刷题应用,在这个应用中,我使用了抽屉组件来实现一些功能,切换题库,如下图所示:
在移动应用开发中,抽屉(Drawer)是一种常见的界面设计模式,这个组件可以在需要侧边导航或者额外信息展示的地方使用。它允许用户通过侧滑的效果打开一个菜单或额外的内容区域。
这种设计不仅能够节省屏幕空间,还能提供一种直观的交互方式。
例如,在电商应用中,可以将购物车或分类列表放在抽屉里;在新闻阅读器中,可以放置频道选择等;而在有题记刷题软件中,我主要用于题库的选择功能。
本文将介绍如何使用 uni-app 框架来实现一个简单的抽屉组件:DrawerWindow。文末提供完整的代码示例,让你能够轻松地在 uni-app 中实现抽屉效果。
看新机会的
技术大厂,待遇之类的给的还可以,就是偶尔有加班(放心,加班有加班费)
前后端测试捞人,多地有空位,感兴趣的可以试试~
二. 实现分析
Vue 组件的结构通常由三个主要部分组成:模板(<template>)、脚本(<script>)和样式(<style>),标准的的单文件组件(SFC)结构。
uni-app 也是如此,在这个组件中,我们也将使用 Vue 的单文件组件(SFC)结构,这意味着我们将在一个 .vue 文件中同时包含模板、脚本和样式。
接下来我们按照这个格式来简单实现一下。
-
- 模板页面 (<template>)
首先,模版页面是很简单的部分,我们需要创建一个基础的 Vue 组件,该组件包含了主页面、抽屉内容和关闭按钮三个部分。以下是组件的模板代码:
<template>
<view class="drawer-window-wrap">
<scroll-view scroll-y class="DrawerPage" :class="{ show: modalName === 'viewModal' }">
<!-- 主页面 -->
<slot></slot>
</scroll-view>
<!-- 关闭抽屉 -->
<view class="DrawerClose" :class="{ show: modalName === 'viewModal' }" @tap="hide">
<u-icon name="backspace"></u-icon>
</view>
<!-- 抽屉页面 -->
<scroll-view scroll-y class="DrawerWindow" :class="{ show: modalName === 'viewModal' }">
<slot name="drawer"></slot>
</scroll-view>
</view>
</template>
- 模板页面 (<template>)
在模板部分,我们主要定义了三个主要元素:主页面、关闭按钮和抽屉页面。每个元素都有一个class绑定,这个绑定会根据 modalName 的状态来决定是否添加 .show 类。
主页面 (<scroll-view class="DrawerPage">):
这个滚动视图代表应用的主要内容区域。
当抽屉打开时,它会被缩小并移向屏幕右侧。
提供默认插槽 <slot></slot>,允许父组件传递自定义内容到这个位置。
关闭按钮 (<view class="DrawerClose">):
位于屏幕右侧的一个透明背景层,当点击时触发 hide() 方法来关闭抽屉。
包含了一个图标 <u-icon name="backspace"></u-icon>,这里使用的是 uView UI 库中的图标组件。你可以选用其他组件库里的图标或者图片。
抽屉页面 (<scroll-view class="DrawerWindow">):
这是抽屉本身的内容区域,通常包含菜单或其他附加信息。
同样地,定义特有的插槽名称,<slot name="drawer"></slot> 允许从外部插入特定的内容。
抽屉默认是隐藏的,并且当显示时会有动画效果。
在这里,我们主要使用了 <slot> 元素来定义可以插入自定义内容的位置。modalName 属性用来控制抽屉的状态。
- 逻辑处理 (<script>)
接下来,逻辑处理其实也很简单,主要会定义打开和关闭抽屉的方法:
javascript 代码解读复制代码<script>
export default {
data() {
return {
modalName: null
}
},
methods: {
// 打开抽屉
show() {
this.modalName = 'viewModal';
},
// 关闭抽屉
hide() {
this.modalName = null;
}
}
}
</script>
数据 (data):
modalName: 用于控制抽屉状态的数据属性。当它的值为 'viewModal' 时,表示抽屉处于打开状态;否则,抽屉是关闭的。
方法 (methods):
show(): 将 modalName 设置为'viewModal',从而通过 CSS 样式控制抽屉显示。
hide(): 将 modalName 重置为 null,控制抽屉隐藏。
当调用 show() 方法时,modalName 被设置为 'viewModal',这会触发 CSS 中的 .show 类,从而显示抽屉;反之,调用 hide() 方法则会隐藏抽屉。
- 样式设计 (<style>)
在这个组件中,其实要做好的在样式部分,主要是显示抽屉的动画部分。在主页面,我们主要定义了三个主要的样式类:主页面、关闭按钮和抽屉页面。
主页面样式 (DrawerPage):
初始状态下占据整个屏幕宽度和高度。
当抽屉打开时(即有.show类),页面会缩小并移动到屏幕右侧 85%的位置,同时增加阴影效果以模拟深度。
关闭按钮样式 (DrawerClose):
默认情况下是不可见且不响应用户交互的。
当抽屉打开时,按钮变为可见并可点击,提供了一种关闭抽屉的方式。
抽屉页面样式 (DrawerWindow):
初始状态下位于屏幕左侧外侧,不显示也不响应交互。
当抽屉打开时,抽屉平滑滑入屏幕内,变得完全可见且可以与用户互动。
动画与过渡
所有的 .show 类都带有 transition: all 0.4s;,这使得任何属性的变化都会有一个 0.4 秒的平滑过渡效果。
抽屉和主页面的 transform 属性被用来控制它们的位置和大小变化。
opacity 和 pointer-events 属性确保在不需要时抽屉不会影响用户的操作。
如下代码所示,我们主要添加一些 CSS 样式来实现平滑的过渡效果以及视觉上的美观:
scss 代码解读复制代码<style lang="scss">
// 省略其他样式...
.DrawerPage.show,
.DrawerWindow.show,
.DrawerClose.show {
transition: all 0.4s;
}
.DrawerPage.show {
transform: scale(0.9, 0.9) translateX(85vw);
box-shadow: 0 0 60rpx rgba(0, 0, 0, 0.2);
}
.DrawerWindow.show {
transform: scale(1, 1) translateX(0%);
opacity: 1;
pointer-events: all;
}
.DrawerClose.show {
width: 15vw;
color: #fff;
opacity: 1;
pointer-events: all;
}
</style>
以上的这些样式确保了当抽屉显示或隐藏时有流畅的动画效果,并且在不需要的时候不会影响用户的交互。
三. 完整代码
- 完整抽屉组件,复制可使用
html 代码解读复制代码<template>
<view class="drawer-window-wrap">
<scroll-view scroll-y class="DrawerPage" :class="modalName == 'viewModal' ? 'show' : ''">
<!-- 主页面 -->
<slot></slot>
</scroll-view>
<!-- 关闭抽屉 -->
<view class="DrawerClose" :class="modalName == 'viewModal' ? 'show' : ''" @tap="hide()">
<u-icon name="backspace"></u-icon>
</view>
<!-- 抽屉页面 -->
<scroll-view scroll-y class="DrawerWindow" :class="modalName == 'viewModal' ? 'show' : ''">
<slot name="drawer"></slot>
</scroll-view>
</view>
</template>
<script>
export default {
data() {
return {
modalName: null
}
},
methods: {
// 打开抽屉
show() {
this.modalName = 'viewModal'
},
// 关闭抽屉
hide() {
this.modalName = null
}
}
}
</script>
<style lang="scss">
page {
width: 100vw;
overflow: hidden !important;
}
.DrawerPage {
position: fixed;
width: 100vw;
height: 100vh;
left: 0vw;
background-color: #f1f1f1;
transition: all 0.4s;
}
.DrawerPage.show {
transform: scale(0.9, 0.9);
left: 85vw;
box-shadow: 0 0 60rpx rgba(0, 0, 0, 0.2);
transform-origin: 0;
}
.DrawerWindow {
position: absolute;
width: 85vw;
height: 100vh;
left: 0;
top: 0;
transform: scale(0.9, 0.9) translateX(-100%);
opacity: 0;
pointer-events: none;
transition: all 0.4s;
background-image: linear-gradient(45deg, #1cbbb4, #2979ff) !important;
}
.DrawerWindow.show {
transform: scale(1, 1) translateX(0%);
opacity: 1;
pointer-events: all;
}
.DrawerClose {
position: absolute;
width: 40vw;
height: 100vh;
right: 0;
top: 0;
color: transparent;
padding-bottom: 50rpx;
display: flex;
align-items: flex-end;
justify-content: center;
background-image: linear-gradient(90deg, rgba(0, 0, 0, 0.01), rgba(0, 0, 0, 0.6));
letter-spacing: 5px;
font-size: 50rpx;
opacity: 0;
pointer-events: none;
transition: all 0.4s;
}
.DrawerClose.show {
opacity: 1;
pointer-events: all;
width: 15vw;
color: #fff;
}
</style>
- 在父组件中使用抽屉组件
在父组件中,可以通过以下简单的代码使用它,你可以继续进行丰富:
html 代码解读复制代码<template>
<drawer-window ref="drawerWindow">
<view class="main-container" @click="$refs.drawerWindow.show()">
主页面,点击打开抽屉
</view>
<view slot="drawer" class="drawer-container"> 抽屉页面 </view>
</drawer-window>
</template>
<script>
export default {}
</script>
<style lang="scss" scoped>
.main-container,
.drawer-container {
font-weight: 700;
font-size: 20px;
text-align: center;
color: #333;
padding-top: 100px;
}
</style>
以上代码的实现效果如下图所示:
四. 小程序体验
以上的组件,来源于我独立开发的软考刷题小程序中的效果,想要体验或软考刷题的掘友可以参考以下文章,文末获取:
软考小工具重磅更新啦!最好用的软考刷题工具
五. 结语
通过以上步骤,我们已经构建了一个基本的抽屉组件。当然,你也可以根据具体的应用场景对这个组件进行进一步的定制和优化。
——转载自作者:前端梦工厂
收起阅读 »
uniapp,开发的一些插件,需要自取。有需要优化或者有bug的请发评论。后续有更新新插件会继续加上。
1、uniapp项目,安卓权限说明,顶部蒙层(全局,不需要各个页面引入):https://ext.dcloud.net.cn/plugin?id=21973
uni_modules版本:https://ext.dcloud.net.cn/plugin?id=22675
2、uniapp项目,拖拽组件,悬浮或浮动(按钮、广告、菜单、直播窗口等),两边停靠https://ext.dcloud.net.cn/plugin?id=22044
3、uniapp项目,canvas合成群头像,仿微信群头像https://ext.dcloud.net.cn/plugin?id=22320
4、uniapp项目,二次封装uni的WebSocket(SocketTask)https://ext.dcloud.net.cn/plugin?id=22423
1、uniapp项目,安卓权限说明,顶部蒙层(全局,不需要各个页面引入):https://ext.dcloud.net.cn/plugin?id=21973
uni_modules版本:https://ext.dcloud.net.cn/plugin?id=22675
2、uniapp项目,拖拽组件,悬浮或浮动(按钮、广告、菜单、直播窗口等),两边停靠https://ext.dcloud.net.cn/plugin?id=22044
3、uniapp项目,canvas合成群头像,仿微信群头像https://ext.dcloud.net.cn/plugin?id=22320
4、uniapp项目,二次封装uni的WebSocket(SocketTask)https://ext.dcloud.net.cn/plugin?id=22423

招聘 uni app开发工程师
工作地点:河南郑州市中原区
学历:本科及以上学历
薪资范围:9K~13K*13薪
福利待遇:双休、五险一金、包午餐(四菜一汤一份水果)
职责描述:
1、负责基于H5、uni-App的手机APP 、小程序的设计与开发;
2、负责公司现有小程序、APP的开发、重构与优化;
3、参与公司级APP的发展方向的规划与设计;
4、参与APP研发技术的积累、学习、实践工作;
5、参与公司其他前端技术支持工作。
任职要求:
1、本科及以上学历,计算机、软件、设计等相关专业;
2、1年或以上手机端相关开发经验,一个以上项目跨平台APP开发经验;
3、精通符合W3C标准的Html5、JavaScript和CSS相关技术;
4、精通JSON、XML等通信格式以及基于AJAX请求实现与后台数据交互;
5、精通Vue、React等常见JS开发框架;
6、熟悉使用HBuilder、Webstorem 等IDE编辑器进行开发,并完成打包发布H5、小程序、安卓、ios版本app;
7、精通 Vue、uni-app 框架应用,并能运用uni-app框架完成移动端及小程序开发;
8、注重用户体验,具有快速迭代和敏捷开发思维,具备快速学习能力;
9、良好沟通能力、团队合作精神,积极主动、服从安排,能承受较大压力,责任心和学习能力强,能独立分析问题及解决问题;
10、对IOS,Android 原生有实际开发经验的加分;
11、对后台开发Node.js、Java等有开发经验的加分;
工作地点:河南郑州市中原区
学历:本科及以上学历
薪资范围:9K~13K*13薪
福利待遇:双休、五险一金、包午餐(四菜一汤一份水果)
职责描述:
1、负责基于H5、uni-App的手机APP 、小程序的设计与开发;
2、负责公司现有小程序、APP的开发、重构与优化;
3、参与公司级APP的发展方向的规划与设计;
4、参与APP研发技术的积累、学习、实践工作;
5、参与公司其他前端技术支持工作。
任职要求:
1、本科及以上学历,计算机、软件、设计等相关专业;
2、1年或以上手机端相关开发经验,一个以上项目跨平台APP开发经验;
3、精通符合W3C标准的Html5、JavaScript和CSS相关技术;
4、精通JSON、XML等通信格式以及基于AJAX请求实现与后台数据交互;
5、精通Vue、React等常见JS开发框架;
6、熟悉使用HBuilder、Webstorem 等IDE编辑器进行开发,并完成打包发布H5、小程序、安卓、ios版本app;
7、精通 Vue、uni-app 框架应用,并能运用uni-app框架完成移动端及小程序开发;
8、注重用户体验,具有快速迭代和敏捷开发思维,具备快速学习能力;
9、良好沟通能力、团队合作精神,积极主动、服从安排,能承受较大压力,责任心和学习能力强,能独立分析问题及解决问题;
10、对IOS,Android 原生有实际开发经验的加分;
11、对后台开发Node.js、Java等有开发经验的加分;

vue.runtime.esm.js' does not provide an export named 'default'错误的解决方法
遇到了这个问题,后来把组件的路径改掉,就好了
import date from '@/components/_picker/date.vue'
改为
import date from '@/uni_modules/_picker/date.vue'
遇到了这个问题,后来把组件的路径改掉,就好了
import date from '@/components/_picker/date.vue'
改为
import date from '@/uni_modules/_picker/date.vue'

微信小程序不支持中文方案解决
在 浏览器的环境下 可以使用 <view class="样式"> , {{ 对象.属性 }} ,v-if="f显示隐藏" ,但是在小程序里面不行,
虽然有翻译插件,难免还是需要按一下快捷键或者操作鼠标, 对于开发人员来说 要懒就 就要一劳永逸的懒懒下去
我以前是写个脚本来做转换, 但是调试微信小程序很痛苦, 然后看了 vue2和vue3的打包方式, 决定从打包方式入手, 在打包时 让中文变为小程序可兼容字母,
思路如下:
将中文单个拆分,然后对每个 字符进行转换, 转换方式为 unicode 的36进制来 替换中文,
let code= "中文".split("").map(v=> "_" v.charCodeAt(0).toString(36)).join("");
console.log(code); // 输出 '_ffx_k1z' ;
在每个值之前加上 下划线, 解决不能以数字开头的情况,
Vue2 和 Vue3 的打包方式不同,解决方式 不一样,不过Vue3 相对来说很简单,
我就先提供Vue2的解决方案,
最开始我计划使用 vue.config.js 来解决,但是 Vue2使用 打包方式并不能解决
最终无奈的只能从编译器下手了
首先 找到你的 Hbx 安装目录, 然后找到 plugins\uniapp-cli\node_modules\@dcloudio\vue-cli-plugin-uni\packages\webpack-preprocess-loader 这个文件
完成地址如下,(这是我的地址)
D:\develop\IDEA\HBuilderX\plugins\uniapp-cli\node_modules\@dcloudio\vue-cli-plugin-uni\packages\webpack-preprocess-loader
在这个目录中导入 附件中的 chineseSupport.js 文件
/webpack-preprocess-loader
- preprocess
- chineseSupport.js
- index.js
然后修改 index.js 文件, 这个文件就是对我们写的代码进行一次转义,在这里来处理 css , 以及 中文
当然 附加里面 也给你提供好了 index 文件, 不过 你可能需要稍加改造, 我的项目比较混杂 我是在.vue 文件中来指定哪些文件需要转义的,如果你希望全量转义 就把限制取消掉就可以了
附件里面还有一个 chinesefields.js 用于将对象的的所有 键 转换为 字母, 用来处理 {{ 对象.属性 }} , 这是处理后端返回的变量名是中文的情况
源文件 必须包含 <!-- 开启全量中文 -->
<template>
<!-- 开启全量中文 -->
<view class="con tent 哈哈哈 页面" :class="f名称 + '23'" :vvv="'22'">
<image class="logo" src="/static/logo.png" />
<view class="text-area" :title="f名称" name="名字">
<text class="title">{{ f名称 }}</text>
</view>
<button @click="m点击事件('名称', f名称)">
<span>点击 :{{ f名称 }}</span>
</button>
<view v-for="(item, index) in f数据列表" :key="index">
<view>{{ item.f名称 }}</view>
</view>
</view>
</template>
<script>
import { chineseFields } from '../../assets/chinese-solution/chinesefields.js';
export default {
data() {
return {
f名称: 'Hello',
f数据列表: [
{
f名称: '张三'
}
]
};
},
onLoad() {},
mounted() {
this.m后端加载();
},
methods: {
m后端加载() {
setTimeout(() => {
//-> 假设
this.f数据列表 = chineseFields([
{
f名称: '李四'
}
]);
}, 0);
},
m点击事件(a名称, fname) {
let f字段 = '输出值' + this.f名称;
console.log(f字段, a名称, fname);
}
}
};
</script>
<style lang="scss">
.哈哈哈 .title {
font-size: 40rpx;
}
.哈哈哈 {
background-color: aqua;
}
</style>
输出结果
<template>
<!-- 开启全量中文-->
<view class="con tent _gqw_gqw_gqw _u45_twi" :class="f_glp_o34 '23'" :vvv="'22'" >
<image class="logo" src="/static/logo.png" ></image>
<view class="text-area" :title="f_glp_o34" name="名字" >
<text class="title" >
{{ f_glp_o34 }}
</text>
</view>
<button @click="m_m9l_g6z_fij_fli('名称', f_glp_o34)" >
<span>
点击 :{{ f_glp_o34 }}
</span>
</button>
<view v-for="(item, index) in f_k1c_jn2_g7r_qy0" :key="index" >
<view>
{{ item.f_glp_o34 }}
</view>
</view>
</view>
</template>
<script>
import { chineseFields } from '../../assets/chinese-solution/chinesefields.js';
export default {
data() {
return {
f_glp_o34: 'Hello',
f_k1c_jn2_g7r_qy0: [
{
f_glp_o34: '张三'
}
]
};
},
onLoad() {},
mounted() {
this.m_glq_oa7_gbk_scd();
},
methods: {
m_glq_oa7_gbk_scd() {
setTimeout(() => {
//-> _fuv_rlq
this.f_k1c_jn2_g7r_qy0 = chineseFields([
{
f_glp_o34: '李四'
}
]);
}, 0);
},
m_m9l_g6z_fij_fli(a_glp_o34, fname) {
let f_i1j_l9x = '输出值' this.f_glp_o34;
console.log(f_i1j_l9x, a_glp_o34, fname);
}
}
};</script>
<style lang="scss" >
._gqw_gqw_gqw .title {
font-size: 40rpx;
}
._gqw_gqw_gqw {
background-color: aqua;
}</style>
在 浏览器的环境下 可以使用 <view class="样式"> , {{ 对象.属性 }} ,v-if="f显示隐藏" ,但是在小程序里面不行,
虽然有翻译插件,难免还是需要按一下快捷键或者操作鼠标, 对于开发人员来说 要懒就 就要一劳永逸的懒懒下去
我以前是写个脚本来做转换, 但是调试微信小程序很痛苦, 然后看了 vue2和vue3的打包方式, 决定从打包方式入手, 在打包时 让中文变为小程序可兼容字母,
思路如下:
将中文单个拆分,然后对每个 字符进行转换, 转换方式为 unicode 的36进制来 替换中文,
let code= "中文".split("").map(v=> "_" v.charCodeAt(0).toString(36)).join("");
console.log(code); // 输出 '_ffx_k1z' ;
在每个值之前加上 下划线, 解决不能以数字开头的情况,
Vue2 和 Vue3 的打包方式不同,解决方式 不一样,不过Vue3 相对来说很简单,
我就先提供Vue2的解决方案,
最开始我计划使用 vue.config.js 来解决,但是 Vue2使用 打包方式并不能解决
最终无奈的只能从编译器下手了
首先 找到你的 Hbx 安装目录, 然后找到 plugins\uniapp-cli\node_modules\@dcloudio\vue-cli-plugin-uni\packages\webpack-preprocess-loader 这个文件
完成地址如下,(这是我的地址)
D:\develop\IDEA\HBuilderX\plugins\uniapp-cli\node_modules\@dcloudio\vue-cli-plugin-uni\packages\webpack-preprocess-loader
在这个目录中导入 附件中的 chineseSupport.js 文件
/webpack-preprocess-loader
- preprocess
- chineseSupport.js
- index.js
然后修改 index.js 文件, 这个文件就是对我们写的代码进行一次转义,在这里来处理 css , 以及 中文
当然 附加里面 也给你提供好了 index 文件, 不过 你可能需要稍加改造, 我的项目比较混杂 我是在.vue 文件中来指定哪些文件需要转义的,如果你希望全量转义 就把限制取消掉就可以了
附件里面还有一个 chinesefields.js 用于将对象的的所有 键 转换为 字母, 用来处理 {{ 对象.属性 }} , 这是处理后端返回的变量名是中文的情况
源文件 必须包含 <!-- 开启全量中文 -->
<template>
<!-- 开启全量中文 -->
<view class="con tent 哈哈哈 页面" :class="f名称 + '23'" :vvv="'22'">
<image class="logo" src="/static/logo.png" />
<view class="text-area" :title="f名称" name="名字">
<text class="title">{{ f名称 }}</text>
</view>
<button @click="m点击事件('名称', f名称)">
<span>点击 :{{ f名称 }}</span>
</button>
<view v-for="(item, index) in f数据列表" :key="index">
<view>{{ item.f名称 }}</view>
</view>
</view>
</template>
<script>
import { chineseFields } from '../../assets/chinese-solution/chinesefields.js';
export default {
data() {
return {
f名称: 'Hello',
f数据列表: [
{
f名称: '张三'
}
]
};
},
onLoad() {},
mounted() {
this.m后端加载();
},
methods: {
m后端加载() {
setTimeout(() => {
//-> 假设
this.f数据列表 = chineseFields([
{
f名称: '李四'
}
]);
}, 0);
},
m点击事件(a名称, fname) {
let f字段 = '输出值' + this.f名称;
console.log(f字段, a名称, fname);
}
}
};
</script>
<style lang="scss">
.哈哈哈 .title {
font-size: 40rpx;
}
.哈哈哈 {
background-color: aqua;
}
</style>
输出结果
<template>
<!-- 开启全量中文-->
<view class="con tent _gqw_gqw_gqw _u45_twi" :class="f_glp_o34 '23'" :vvv="'22'" >
<image class="logo" src="/static/logo.png" ></image>
<view class="text-area" :title="f_glp_o34" name="名字" >
<text class="title" >
{{ f_glp_o34 }}
</text>
</view>
<button @click="m_m9l_g6z_fij_fli('名称', f_glp_o34)" >
<span>
点击 :{{ f_glp_o34 }}
</span>
</button>
<view v-for="(item, index) in f_k1c_jn2_g7r_qy0" :key="index" >
<view>
{{ item.f_glp_o34 }}
</view>
</view>
</view>
</template>
<script>
import { chineseFields } from '../../assets/chinese-solution/chinesefields.js';
export default {
data() {
return {
f_glp_o34: 'Hello',
f_k1c_jn2_g7r_qy0: [
{
f_glp_o34: '张三'
}
]
};
},
onLoad() {},
mounted() {
this.m_glq_oa7_gbk_scd();
},
methods: {
m_glq_oa7_gbk_scd() {
setTimeout(() => {
//-> _fuv_rlq
this.f_k1c_jn2_g7r_qy0 = chineseFields([
{
f_glp_o34: '李四'
}
]);
}, 0);
},
m_m9l_g6z_fij_fli(a_glp_o34, fname) {
let f_i1j_l9x = '输出值' this.f_glp_o34;
console.log(f_i1j_l9x, a_glp_o34, fname);
}
}
};</script>
<style lang="scss" >
._gqw_gqw_gqw .title {
font-size: 40rpx;
}
._gqw_gqw_gqw {
background-color: aqua;
}</style>
收起阅读 »

招聘 uni app开发工程师
招聘 uni app开发工程师
工作地点:河南郑州
学历:本科及以上
薪资范围:9K~13K
福利待遇:双休、五险一金、包午餐
职责描述:
1、负责基于H5、uni-App的手机APP 、小程序的设计与开发;
2、负责公司现有APP的开发、重构与优化;
3、参与公司级APP的发展方向的规划与设计;
4、参与APP研发技术的积累、学习、实践工作;
5、参与公司其他前端技术支持工作。
任职要求:
1、本科及以上学历,计算机、软件、设计等相关专业;
2、3年或以上手机端相关开发经验,一个以上项目跨平台APP开发经验;
3、精通符合W3C标准的Html5、JavaScript和CSS相关技术;
4、精通JSON、XML等通信格式以及基于AJAX请求实现与后台数据交互;
5、精通JQuery、Vue等常见JS开发框架;
6、熟悉使用HBuilder IDE编辑器进行开发,并完成打包发布安卓、ios版本app;
7、精通 Vue、uni-app 框架应用,并能运用uni-app框架完成移动端及小程序开发;
8、注重用户体验,具有快速迭代和敏捷开发思维,具备快速学习能力;
9、良好沟通能力、团队合作精神,积极主动、服从安排,能承受较大压力,责任心和学习能力强,能独立分析问题及解决问题;
10、对IOS,Android 原生有实际开发经验的加分;
11、对后台开发(Node.js)有了解的加分;
志同道合者请联系:13526636033、13526636033@163.com
招聘 uni app开发工程师
工作地点:河南郑州
学历:本科及以上
薪资范围:9K~13K
福利待遇:双休、五险一金、包午餐
职责描述:
1、负责基于H5、uni-App的手机APP 、小程序的设计与开发;
2、负责公司现有APP的开发、重构与优化;
3、参与公司级APP的发展方向的规划与设计;
4、参与APP研发技术的积累、学习、实践工作;
5、参与公司其他前端技术支持工作。
任职要求:
1、本科及以上学历,计算机、软件、设计等相关专业;
2、3年或以上手机端相关开发经验,一个以上项目跨平台APP开发经验;
3、精通符合W3C标准的Html5、JavaScript和CSS相关技术;
4、精通JSON、XML等通信格式以及基于AJAX请求实现与后台数据交互;
5、精通JQuery、Vue等常见JS开发框架;
6、熟悉使用HBuilder IDE编辑器进行开发,并完成打包发布安卓、ios版本app;
7、精通 Vue、uni-app 框架应用,并能运用uni-app框架完成移动端及小程序开发;
8、注重用户体验,具有快速迭代和敏捷开发思维,具备快速学习能力;
9、良好沟通能力、团队合作精神,积极主动、服从安排,能承受较大压力,责任心和学习能力强,能独立分析问题及解决问题;
10、对IOS,Android 原生有实际开发经验的加分;
11、对后台开发(Node.js)有了解的加分;
志同道合者请联系:13526636033、13526636033@163.com
收起阅读 »
uni-pay 配置多个商户动态获取,修改下 /uni-pay-co/service/pay.js 经验
目标 用户点击支付是 动态获取商家的支付配置参数,实现多商户配置,思路:商家支付配置参数储存到数据库然后获取给unipay。
第一步安装导入uniapy2组件 这步骤不说了很简单。。

是这样的 调用支付 ref pay
这里就是调用支付的时候所需的参数我们增加一个商家ID 然后打开\uni_modules\uni-pay\components\uni-pay 这个文件里看一下后面发生的事
这里它调用了创建订单函数就在下面我看了一下 这个才是真正的给unipay云函数传参数的
好这个也看了 我们看下他最后怎么做了
接下来我们去找到这个看一下
\uniCloud\cloudfunctions\uni-pay-co\service\pay,js
这是核心的地方
你因为这就完了,确实完了 但是接受这个参数过程还复杂 我这小白研究半天才实现了
看下面
最后就是按这个格式数据库存储配置信息然后在这个通过商家ID获取对应的配置信息给他就好了
我的思路在这里结束 记录一下吧
目标 用户点击支付是 动态获取商家的支付配置参数,实现多商户配置,思路:商家支付配置参数储存到数据库然后获取给unipay。
第一步安装导入uniapy2组件 这步骤不说了很简单。。
是这样的 调用支付 ref pay
这里就是调用支付的时候所需的参数我们增加一个商家ID 然后打开\uni_modules\uni-pay\components\uni-pay 这个文件里看一下后面发生的事
这里它调用了创建订单函数就在下面我看了一下 这个才是真正的给unipay云函数传参数的
好这个也看了 我们看下他最后怎么做了
接下来我们去找到这个看一下
\uniCloud\cloudfunctions\uni-pay-co\service\pay,js
这是核心的地方
你因为这就完了,确实完了 但是接受这个参数过程还复杂 我这小白研究半天才实现了
看下面
最后就是按这个格式数据库存储配置信息然后在这个通过商家ID获取对应的配置信息给他就好了
我的思路在这里结束 记录一下吧
收起阅读 »
国际化vue-i18n报错是版本问题
按照官方文档 推荐使用vue-i18n@9.1.9固定版本安装到项目报一下错误
Uncaught TypeError: Cannot read properties of undefined (reading 'install')
at Vue.use (chunk-vendors.js:20622:23)
at eval (main.js:14:5)
at Object.Vtdi (index.js:3865:1)
at webpack_require (index.js:854:30)
at fn (index.js:151:20)
at 1 (index.js:1244:18)
at webpack_require (index.js:854:30)
at checkDeferredModules (index.js:46:23)
at index.js:994:18****
查看本项目vue版本是2.6.14 而vue-i18n@9.1.9是vue3.0版本 经过查阅资料vue2.0版本需要 vue-i18n@5版本 安装5版本即可解决问题
按照官方文档 推荐使用vue-i18n@9.1.9固定版本安装到项目报一下错误
Uncaught TypeError: Cannot read properties of undefined (reading 'install')
at Vue.use (chunk-vendors.js:20622:23)
at eval (main.js:14:5)
at Object.Vtdi (index.js:3865:1)
at webpack_require (index.js:854:30)
at fn (index.js:151:20)
at 1 (index.js:1244:18)
at webpack_require (index.js:854:30)
at checkDeferredModules (index.js:46:23)
at index.js:994:18****
查看本项目vue版本是2.6.14 而vue-i18n@9.1.9是vue3.0版本 经过查阅资料vue2.0版本需要 vue-i18n@5版本 安装5版本即可解决问题
收起阅读 »
荣耀200真机运行到HBuilder检测不到手机
手机型号是荣耀200,用数据线进行调试项目,百度了很多方法,各种方法都尝试了,但是始终检测不到手机!这个问题困扰我很久了
1、安装荣耀手机助手 HonorSuite
2、安装Android SDK Platform-Tools
解决方案:
手机型号是荣耀200,用数据线进行调试项目,百度了很多方法,各种方法都尝试了,但是始终检测不到手机!这个问题困扰我很久了
1、安装荣耀手机助手 HonorSuite
2、安装Android SDK Platform-Tools
解决方案:
参考文章:
关于荣耀Magic UI系列HBuilder真机调试检测不到解决办法

【经验分享】uniappX中实现类似pinia-plugin-persist-uni的本地数据缓存
主要的实现方法
export function defineStore<T>(name : string, obj : T) : T {
let storage = uni.getStorageSync(name);
if (storage instanceof UTSJSONObject) {
let data = JSON.parse<T>(JSON.stringify(storage));
if (data != null) {
let newVal = data as T;
obj = reactive(newVal);
}
}
watch(obj as any, () => {
uni.setStorage({
key: name,
data: obj as any
});
}, {
deep: true
})
return obj;
}
调用示例:
type UserStore = {
initReady : boolean;
userInfo: UTSJSONObject;
}
export const app = defineStore("app", reactive<UserStore>({
initReady: false,
userInfo:{}
}))
页面中app.xxx就是响应式,参考官方文档:https://doc.dcloud.net.cn/uni-app-x/tutorial/store.html#%E5%85%A8%E5%B1%80%E5%8F%98%E9%87%8F%E4%B8%8E%E7%8A%B6%E6%80%81%E7%AE%A1%E7%90%86
如果没有这种处理,app每次启动的时候,状态都会重置。加了后数据就能本地持久化了。
主要的实现方法
export function defineStore<T>(name : string, obj : T) : T {
let storage = uni.getStorageSync(name);
if (storage instanceof UTSJSONObject) {
let data = JSON.parse<T>(JSON.stringify(storage));
if (data != null) {
let newVal = data as T;
obj = reactive(newVal);
}
}
watch(obj as any, () => {
uni.setStorage({
key: name,
data: obj as any
});
}, {
deep: true
})
return obj;
}
调用示例:
type UserStore = {
initReady : boolean;
userInfo: UTSJSONObject;
}
export const app = defineStore("app", reactive<UserStore>({
initReady: false,
userInfo:{}
}))
页面中app.xxx就是响应式,参考官方文档:https://doc.dcloud.net.cn/uni-app-x/tutorial/store.html#%E5%85%A8%E5%B1%80%E5%8F%98%E9%87%8F%E4%B8%8E%E7%8A%B6%E6%80%81%E7%AE%A1%E7%90%86
如果没有这种处理,app每次启动的时候,状态都会重置。加了后数据就能本地持久化了。

HBuilderX linux 平台安装包更新,解决一些低版本模块和vue2的编译问题
Linux 环境:
推荐node 版本为 v18.20.7
uapp 版本 >= 2.3.5,uapp -v
可以查看当前使用版本
Ubuntu 22.04 不要使用 apt install nodejs, 这个版本目前发现问题。建议使用 nvm 安装
安装后,必须确认modules 版本为108,如果109或其他的,sass 插件会有问题。查看版本方法:
node -p "process.versions.modules"
输出 108 就对了,否则都有问题。
下载:
https://artisansoft.feishu.cn/docx/NZRHdetSzoi8VEx7KcYcuivpnqd
Linux 环境:
推荐node 版本为 v18.20.7
uapp 版本 >= 2.3.5,uapp -v
可以查看当前使用版本
Ubuntu 22.04 不要使用 apt install nodejs, 这个版本目前发现问题。建议使用 nvm 安装
安装后,必须确认modules 版本为108,如果109或其他的,sass 插件会有问题。查看版本方法:
node -p "process.versions.modules"
输出 108 就对了,否则都有问题。
下载:
https://artisansoft.feishu.cn/docx/NZRHdetSzoi8VEx7KcYcuivpnqd
收起阅读 »
Some App Tech Support
一、软件介绍
名称:小秘书
类型:办公类应用
二、功能
小秘书是一款办公助手类app,兼具便签、日记本、待办事项等功能,虽然简单却功能齐全、门类清晰,方便统一处理。
【功能】
1.【idea闪现】:将突然出现的好点子捕捉下来
2.【挑战出现】:记录难题和应对方法
3.【经验总结】:帮助你将工作经验记录下来
4.【日程安排】:有序规划生活,达成你的目标
还有更多隐藏功能供探索。
让你随时随地记录灵感!更便捷地处理工作!!并形成经验总结方便日后翻阅
三、Getting Support:
邮箱: royalulugemma@yeah.net
或者评论留言
一、软件介绍
名称:小秘书
类型:办公类应用
二、功能
小秘书是一款办公助手类app,兼具便签、日记本、待办事项等功能,虽然简单却功能齐全、门类清晰,方便统一处理。
【功能】
1.【idea闪现】:将突然出现的好点子捕捉下来
2.【挑战出现】:记录难题和应对方法
3.【经验总结】:帮助你将工作经验记录下来
4.【日程安排】:有序规划生活,达成你的目标
还有更多隐藏功能供探索。
让你随时随地记录灵感!更便捷地处理工作!!并形成经验总结方便日后翻阅
三、Getting Support:
邮箱: royalulugemma@yeah.net
或者评论留言
收起阅读 »