项目搭建
所用技术: uni-app vue3 javaScript pinia axios uView-plus
使用vscode开发uni-app项目
- 下载需要的技术的版本(uni-app官网)👇👇👇👇
- 使用vscode引入,并安装依赖,并安装对应插件
npm install
-
👉 安装 uni-app 开发插件
- uni-create-view :快速创建 uni-app 页面
- uni-helper :uni-app 代码提示
- uniapp 小程序扩展 :鼠标悬停查文档
-
👉 JSON 注释问题
- 设置文件关联,把
manifest.json
和pages.json
设置为jsonc
- 设置文件关联,把
修改路径:左上角文件-首选项-设置
{
"editor.formatOnSave": true,
"files.autoSave": "afterDelay",
"[vue]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[javascript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
// 配置语言的文件关联
"files.associations": {
"pages.json": "jsonc", // pages.json 可以写注释
"manifest.json": "jsonc" // manifest.json 可以写注释
},
"Codegeex.Privacy": false,
"[jsonc]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
}
}
- 尝试启动项目,启动项目的配置在项目根目录下的
package.json
- 启动成功是这样子
- 如果你想运行成小程序需要在
manifest.json
配置文件中添加appId和其它的单独的设置
"mp-weixin": {
"appid": "你自己的appid",
"setting": {
"urlCheck": false
},
"usingComponents": true,
// 配置位置服务信息
"permission": {
"scope.userLocation": {
"desc": "您的位置信息将用于提供相关服务"
}
}
},
开发中遇到的单位问题
如果你是开发小程序,后者同时开发h5页面手机端和小程序,那么单位推荐你使用rpx作为首选单位。
选择好单位后就是下载对应的自动转换的插件,我这里是准备的将px转为rpx单位
。
- vscode中搜索插件:
- 安装好后在设置中搜索这个:
- 然后修改设计稿的宽度为基准值即可:
- 设置完就可以使用了(如果没有自动转换提示,可以重启,或者Ctlr + i快捷键试试)
引入pinia和pinia持久化
- 下载插件
npm i pinia-plugin-persistedstate
2. 多端持久化
// 兼容多端API
uni.setStorageSync()
uni.getStorageSync()
- 配置自动持久化
export const useMemberStore = defineStore(
'member',
() => {
//…省略
},
{
// 配置持久化
persist: {
// 调整为兼容多端的API
storage: {
setItem(key, value) {
uni.setStorageSync(key, value)
},
getItem(key) {
return uni.getStorageSync(key)
},
},
},
},
)
注意在我们配置pinia的时候会可能出现pinia报hasInjectionContext问题
原因是pinia的版本跟vue的版本对不上,我们可以手动的更改一下版本就可以了
npm i pinia@2.0.36
如果你还是报这个错误请自己去官网查询解决版本对应的问题
引入框架
前端框架:uView-plus(支持vue3)
- npm 下载
npm install uview-plus
2. 安装配置
// 安装sass
npm i sass -D
// 安装sass-loader,注意需要版本10,否则可能会导致vue与sass的兼容问题而报错
npm i sass-loader@10 -D
// 安装
npm install dayjs
npm install clipboard
3. 引入uview-plus主JS库(main.js)
import { createSSRApp } from "vue";
import uviewPlus from "uview-plus";
import pinia from "./stores/index";
import App from "./App.vue";
export function createApp() {
const app = createSSRApp(App);
app.use(uviewPlus);
app.use(pinia);
return {
app,
};
}
- 引入样式
在
uni.scss
引入或者在APP.vue
的样式表的第一样引入都可以
@import 'uview-plus/theme.scss';
- 配置easycom组件模式
// pages.json
{
"easycom": {
// 注意一定要放在custom里,否则无效,https://ask.dcloud.net.cn/question/131175
"custom": {
"^u--(.*)": "uview-plus/components/u-$1/u-$1.vue",
"^up-(.*)": "uview-plus/components/u-$1/u-$1.vue",
"^u-([^-].*)": "uview-plus/components/u-$1/u-$1.vue"
}
},
// 此为本身已有的内容
"pages": [
// ......
]
}
这样就可以使用uView-plus组件库了
封装自定义头部导航栏
- 安全区域
不同手机的安全区域不同,适配安全区域能防止页面重要内容被遮挡。
可通过 uni.getSystemInfoSync()
获取屏幕边界到安全区的距离。
- 自定义导航配置
// src/pages.json
{
"path": "pages/index/index",
"style": {
"navigationStyle": "custom", // 隐藏默认导航
"navigationBarTextStyle": "white",
"navigationBarTitleText": "首页"
}
}
- 组件适配安全区域
<script>
// 获取屏幕边界到安全区域距离
const { safeAreaInsets } = uni.getSystemInfoSync()
</script>
<template>
<!-- 顶部占位 -->
<view class="navbar" :style="{ paddingTop: safeAreaInsets?.top + 'px' }">
<!-- ...省略 -->
</view>
</template>
<template>
<div class="navbar" :style="{ paddingTop: safeAreaInsets?.top + 'px' }">
<div @click="goToHome">
<img class="nav-img" src="../static/home.png" alt="点击返回首页" />
</div>
<div class="nav-title">
<span class="sp">XXXX</span>
</div>
<div></div>
</div>
</template>
<script setup>
import {} from "vue";
import { onShow } from "@dcloudio/uni-app";
const { safeAreaInsets } = uni.getSystemInfoSync();
onShow(() => {
// console.log("我被执行", safeAreaInsets);
});
const goToHome = () => {
uni.switchTab({
url: "/pages/index", // 首页的路由路径
});
};
</script>
<style lang="scss" scoped>
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
height: 80rpx;
width: 100%;
// position: fixed;
top: 0;
// height: 40px;
background-color: #fff;
// background-color: aqua;
.nav-img {
width: 34rpx;
height: 32rpx;
margin-left: 24rpx;
}
.nav-title {
.sp {
width: 122rpx;
height: 24rpx;
font-size: 25rpx;
font-family: SourceHanSansCN;
font-weight: 300;
color: #000000;
}
}
}
</style>
注意,因为小程序中不支持标签名选择器,所以在vscode中写的css样式最好不用标签名选择器
使用uView-plus组件时样式不会同时生效
我们在给按钮组件设置样式的时候,发现同样的代码在不同的平台展示的效果不一样,在微信小程序中就完全不显示样式
查询文档 uView-plus 3.0后才发现,我们需要custom-style属性来定义外部样式:
按着文档中提到的我们设置了一个custom-styles属性,在里面设置自定义的样式就可以了
<up-button
class="search-btn"
text="确定"
:custom-style="{
color: '#fff',
background: '#ff960c',
borderRadius: '28rpx',
}"
></up-button>
页面之间传参
使用uni.$on
和 uni.$emit
进行页面之间的传值
- 页面配合uni.navigateBack使用
uni.navigateBack({
delta: 1, // 回退的层数
success: () => {
uni.$emit("dataBack", {
regionId: id,
titleFull: showCity.value,
});
},
});
- 接收参数的页面在钩子函数中
onLoad( () => {
uni.$on("dataBack", function (data) {
searchObject.value.region = data.regionId;
address.value = data.titleFull;
});
})
配置小程序界面分享
- 给单独页面设置允许分享
需要再钩子函数中调用并配置下面代码(配置完成后就可以分享给好友和朋友圈了)
onLoad((options) => {
getResourceId(options);
HouseDetail();
// #ifdef MP-WEIXIN
uni.showShareMenu({
withShareTicket: true, // 是否使用带 shareTicket 的转发
menus: ['shareAppMessage', 'shareTimeline'], // 需要显示的菜单列表,例如分享到朋友圈等
});
// #endif
});
如果你想自定义修改标题和封面图片可以利用钩子函数
!!!!跟onLoad同级,并且vue3开发需要引入
import { onShareAppMessage } from '@dcloudio/uni-app'; // 这句话很重要
// 允许页面被分享
onShareAppMessage(() => {
return {
title: roomDetail.value.resourceName, // 自定义标题
imageUrl: roomDetail.value.picArr[0], // 自定义图片 URL
path: `/pages/Tenant/roomDetail?resourceId=${resourceId.value}&roomPrimaryId=${roomPrimaryId.value}&coreArr=${coreArr.value}&checkInTime=${checkInTime.value}&checkOutTime=${checkOutTime.value}`, // 自定义分享参数
success: function () {
console.log('分享成功');
},
fail: function () {
console.log('分享失败');
},
};
});
- 全局页面都可以分享
首先你需要新建一个js文件
export default {
onLoad() {
uni.showShareMenu({
withShareTicket: true, // 是否使用带 shareTicket 的转发
menus: ['shareAppMessage', 'shareTimeline'], // 需要显示的菜单列表,例如分享到朋友圈等
});
},
};
然后在main.js文件中引入并使用
import { createSSRApp } from 'vue';
import uviewPlus from 'uview-plus';
import pinia from './stores/index';
import App from './App.vue';
// 下面的注释是条件编译,如果你只开发小程序,可以不用条件编译
// #ifdef MP-WEIXIN
import shareMixin from './utils/share';
// #endif
export function createApp() {
const app = createSSRApp(App);
app.use(uviewPlus);
app.use(pinia);
// #ifdef MP-WEIXIN
app.mixin(shareMixin);
// #endif
return {
app,
};
}
这样你的小程序的每个界面都可以分享给好友和朋友圈了。
拨打电话功能
<view class="call-msg">
<text class="call_text" @click="makeCall(roomDetail.servMobile)">
{{ roomDetail.servMobile }}
</text>
<img style="width: 32rpx; height: 32rpx; margin-left: 10rpx" src="电话小图标的互联网那个地址、或者临时目录文件" alt="" />
</view>
// 给房东打电话
const makeCall = (servMobile) => {
uni.makePhoneCall({
phoneNumber: servMobile, // servMobile改为需要打的电话号码
});
};
.call-msg {
font-size: 13px;
display: inline-flex;
align-items: center;
.call_text {
text-decoration: underline;
color: #2196f3;
}
}
图片保存功能
首先你需要在manifest.json文件中添加配置使用vscode开发uni-app
const bindSavePic = () => {
uni.showModal({
title: '提示',
content: '是否保存照片到相册',
cancelText: '是',
confirmText: '否',
showCancel: true,
success: function (res) {
if (!res.confirm) {
uni.downloadFile({
url: 'https://s2.loli.net/2022/02/21/wRltb4a2cXoPhCk.jpg', //仅为示例,并非真实的资源
success: (res) => {
if (res.statusCode === 200) {
uni.saveImageToPhotosAlbum({
//保存图片到系统相册。
filePath: res.tempFilePath, //图片文件路径
success: function () {
uni.showToast({
title: '图片保存成功',
icon: 'none',
});
},
fail: function (e) {
uni.showToast({
title: '图片保存失败',
icon: 'none',
});
},
});
}
},
});
}
},
});
};
uni-app中获取dom实例
<template>
<div class="dropdown-menu"></div>
<button @click="getDomInstant">点击获取DOM元素实例</button>
</template>
<script setup>
import { ref, onMounted,nextTick } from "vue";
import { getCurrentInstance } from "vue";
let query; // 获取dom实例
const currentInstance = ref(); // 组件实例
onMounted(() => {
currentInstance.value = getCurrentInstance(); // 获取组件实例
query = uni.createSelectorQuery().in(currentInstance.value);
});
const getDomInstant = async () => {
await nextTick()
query
.select(".dropdown-menu")
.boundingClientRect((rect) => {
console.log(val, rect);
})
.exec();
};
</script>
<style lang="scss" scoped></style>