当前位置: 首页 > ops >正文

uniapp

官方文档:uni-app官网

uni-app 是一个使用 Vue.js 开发所有前端应用的框架,开发一套代码,可以在h5端、app端、小程序端同时使用。

开发一套代码,在微信小程序运行、h5端口、app端(手机模拟器 夜神模拟器)。

uniapp全局配置

index.html

App.vue

main.js

pages.json

globalStyle Object  否   设置默认页面的窗口表现 
pages   Object Array    是   设置页面路径及窗口表现 
easycom Object  否   组件自动引入规则    2.5.5+
tabBar  Object  否   设置底部 tab 的表现  

组件

1、内置组件

视图容器组件:view scroll-view swiper swiper-item

基础内容组件: icon text rich-text

表单组件:form input radio buttom checkbox switch textarea

媒体组件:image radio audio

路由跳转组件:navigator openType="navigate|redirect|switchTab|navigateBack"

map地图

2、扩展 组件 uni-ui

3、第三方组件库 uview-ui 秋云-ucharts (插件市场 )

uView 2.0 - 全面兼容 nvue 的 uni-app 生态框架 - uni-app UI 框架

scss语法(了解)

<template><view class="outer"><view class="c1"><view class="c11">c1-->c11</view></view><view class="c2"><view class="c11">c2-->c11</view></view></view>
</template>
​
<script>export default {data() {return {}},methods: {}}
</script>
​
<style lang="scss">/* css选择器id #标签  标签名类选择  .属性选择器  [name='admin']子元素  >子孙元素  空格通配  **/// .c2{//  background-color: gray;//  height: 150px;// }// .c2>.c11{//  background-color: gold;//  height: 100px;// }.c1{.c11{background-color: red;height: 100px;}}.c2{background-color: gray;height: 150px;.c11{background-color: gold;height: 100px;}}</style>
​

vue2语法(熟悉)

<template><view class="container">{{id}}<button @click="m1()">++</button><button @tap="m1()">++</button></view>
</template>
​
<script>export default {data() {return {id:1,href: 'https://uniapp.dcloud.io/component/README?id=uniui'}},methods: {m1(){console.log("-----m1-----");this.id = ++this.id;},m2(){console.log("=====m2====");}},mounted() {this.m1();}}
</script>
​
<style>.container {padding: 20px;font-size: 14px;line-height: 24px;}
</style>

一、常见的事件类型

‌@click‌

用于处理用户点击操作。 可以绑定在按钮、列表项等元素上,当用户点击时触发相应的逻辑处理。 是标准的HTML DOM事件,在浏览器中通用。

‌@tap‌

也是用于处理用户点击事件。 是小程序和移动端框架(如微信、uni-app)封装的事件,专为触摸交互优化。 在移动端,由于浏览器的click延迟可能会导致用户体验卡顿,而@tap通过原生触摸事件(touchstart/touchend)实现即时响应。 在H5端,@tap会被编译为click(但通过触摸事件模拟,无延迟);在小程序/App端,@tap直接调用原生触摸事件;在PC端可能无效,需用@click。

‌@longpress‌ 和 ‌@longtap‌

用于处理长按操作。 可以绑定在需要长按触发逻辑的元素上,例如长按显示气泡框、长按删除等操作。 这两个事件在功能上相似,但具体实现和触发条件可能略有不同,具体使用哪个事件取决于你的应用需求和uniapp的版本。

‌其他手势事件‌: ‌@touchstart‌:手指触摸动作开始。 ‌@touchmove‌:手指触摸后移动。 ‌@touchcancel‌:手指触摸被打断,如来电提醒、弹窗。 ‌@touchend‌:手指触摸动作结束,如松开按钮。 这些事件为开发者提供了丰富的用户交互手段,可以根据实际需求选择合适的事件来处理用户交互和页面逻辑。

二、api

1、发起网络请求

uni.request

2、页面跳转的

uni.redirectTo

uni.naviateTo

uni.switchTab

uni.navigateBack

uni.relaunch

3、界面交互api

弹出框

uni.showToast uni.HideToast

uni.showLoading uni.HideLoading

4、定时任务

setTimeout

三、完整模块的api

列表查询

<template><view><view class="u-page"><u-list><u-list-item v-for="(item, index) in indexList" :key="index"><u-cell :title="item.channelName"><u-avatarslot="icon"shape="square"size="35":src="item.userImg"customStyle="margin: -3px 5px -3px 0"></u-avatar></u-cell></u-list-item></u-list></view></view>
</template>
​
<script>export default {data() {return {indexList:[]}},methods: {loadChannel(){//发起网络请求,查询数据uni.request({url:"http://localhost:8080/system/channels/list",method:"GET",header: {'authorization': 'Bearer '+uni.getStorageSync('token')},data:{pageNum:1,pageSize:10,},success: (res) => {console.log(res.data);this.indexList = res.data.rows;}})}},onLoad() {this.loadChannel();}}
</script>
​
<style>
​
</style>
​

封装request.js

1. 创建环境配置文件

在项目根目录创建 config/env.js,管理不同环境的 URL:

// config/env.js
const ENV = process.env.NODE_ENV || 'development'; // 获取当前环境
​
const envConfig = {development: { // 开发环境BASE_API: 'http://dev.api.example.com',STATIC_URL: 'http://dev.static.example.com'},production: { // 生产环境BASE_API: 'https://api.example.com',STATIC_URL: 'https://static.example.com'},// 其他环境(如测试环境)test: {BASE_API: 'http://test.api.example.com',STATIC_URL: 'http://test.static.example.com'}
};
​
// 导出当前环境配置
export default envConfig[ENV];

2. 封装全局请求工具

创建 utils/request.js,实现以下功能:

  • 自动拼接基础 URL

  • 拦截请求/响应

  • 统一错误处理

  • 自动携带 Token

// utils/request.js
import env from '@/config/env'; // 引入环境配置
​
/*** 封装 uni.request* @param {Object} options 请求配置*/
const request = (options) => {// 1. 处理请求 URL(拼接环境变量中的 BASE_API)if (!options.url.startsWith('http')) {options.url = env.BASE_API + options.url;}
​// 2. 默认请求配置const defaultOptions = {method: 'POST',header: {'Content-Type': 'application/json','Authorization': uni.getStorageSync('token') || '' // 自动携带 Token}};
​// 3. 合并配置options = { ...defaultOptions, ...options };
​// 4. 返回 Promisereturn new Promise((resolve, reject) => {uni.request({...options,success: (res) => {// 5. 统一处理 HTTP 状态码if (res.statusCode >= 200 && res.statusCode < 300) {resolve(res.data); // 请求成功} else if (res.statusCode === 401) {// Token 过期处理uni.navigateTo({ url: '/pages/login/login' });reject(new Error('未登录或登录已过期'));} else {reject(res.data); // 其他错误}},fail: (err) => {// 6. 网络错误处理uni.showToast({ title: '网络错误', icon: 'none' });reject(err);}});});
};
​
// 7. 快捷方法封装(GET/POST/PUT/DELETE)
export const get = (url, data, options = {}) => {return request({ url, data, method: 'GET', ...options });
};
​
export const post = (url, data, options = {}) => {return request({ url, data, method: 'POST', ...options });
};
​
export default request;

3. 实际使用示例

import { get, post } from '@/utils/request';
​
export default {methods: {// GET 请求async fetchData() {try {const res = await get('/user/info', { id: 123 });console.log(res);} catch (err) {console.error(err);}},
​// POST 请求async submitForm() {try {const res = await post('/user/login', {username: 'admin',password: '123456'});console.log(res);} catch (err) {console.error(err);}}}
};

4、普通表单新增

<template><view><uni-forms ref="form" :modelValue="formData" :rules="rules"><uni-forms-item label="渠道名称" name="channelName"><uni-easyinput type="text" v-model="formData.channelName" placeholder="请输入渠道名称" /></uni-forms-item><uni-forms-item label="渠道编码" name="channelCode"><uni-easyinput type="text" v-model="formData.channelCode" placeholder="请输入渠道名称" /></uni-forms-item>
​</uni-forms><button @click="submit">Submit</button></view>
</template>
​
<script>import {get,post} from '@/utils/request';export default {data() {return {// 表单数据formData: {channelName: '平安好卫士',channelCode: 'pyhws'},rules: {// 对name字段进行必填验证channelName: {rules: [{required: true,errorMessage: '请输入渠道名',},{minLength: 3,maxLength: 5,errorMessage: '长度在 {minLength} 到 {maxLength} 个字符',}]},// 对code字段进行必填验证channelCode: {rules: [{required: true,errorMessage: '请输入渠道编码',}]}}}},methods: {async loadChannel() {const resp = await get('/system/channels/list', {});console.log(resp);},async submit() {const validate = await this.$refs.form.validate();console.log('表单数据信息:', validate);//接收数据console.log(this.formData);//发起网路请求const resp = await post('/system/channels', this.formData);console.log(resp, "新增结果");if (resp.code == 200) { //成功//跳转到列表查询uni.navigateTo({url: "/pages/channel/channel"})} else {console.log("新增失败");}}},onLoad() {this.loadChannel();}}
</script>
​
<style>
</style>

5、文件上传+form表单

<template><view><uni-forms ref="form" :modelValue="formData" :rules="rules"><uni-forms-item label="渠道名称" name="channelName"><uni-easyinput type="text" v-model="formData.channelName" placeholder="请输入渠道名称" /></uni-forms-item><uni-forms-item label="渠道编码" name="channelCode"><uni-easyinput type="text" v-model="formData.channelCode" placeholder="请输入渠道名称" /></uni-forms-item><uni-forms-item label="选择图片" name="userImg"><u-upload :fileList="fileList1" @afterRead="afterRead" @delete="deletePic" name="1" multiple:maxCount="10"></u-upload></uni-forms-item></uni-forms><button @click="submit">Submit</button></view>
</template>
​
<script>import {get,post} from '@/utils/request';export default {data() {return {fileList1: [],// 表单数据formData: {channelName: '平安好卫士',channelCode: 'pyhws'},rules: {// 对name字段进行必填验证channelName: {rules: [{required: true,errorMessage: '请输入渠道名',},{minLength: 3,maxLength: 5,errorMessage: '长度在 {minLength} 到 {maxLength} 个字符',}]},// 对code字段进行必填验证channelCode: {rules: [{required: true,errorMessage: '请输入渠道编码',}]}}}},methods: {async loadChannel() {//const resp = await get('/system/channels/list', {});//console.log(resp);},async submit() {const validate = await this.$refs.form.validate();console.log('表单数据信息:', validate);//接收数据console.log(this.formData);//发起网路请求const resp = await post('/system/channels', this.formData);console.log(resp, "新增结果");if (resp.code == 200) { //成功//跳转到列表查询uni.navigateTo({url: "/pages/channel/channel"})} else {console.log("新增失败");}
​
​
​},// 删除图片deletePic(event) {this[`fileList${event.name}`].splice(event.index, 1);},// 新增图片async afterRead(event) {// 当设置 multiple 为 true 时, file 为数组格式,否则为对象格式let lists = [].concat(event.file);let fileListLen = this[`fileList${event.name}`].length;lists.map((item) => {this[`fileList${event.name}`].push({...item,status: "uploading",message: "上传中",});});for (let i = 0; i < lists.length; i++) {const result = await this.uploadFilePromise(lists[i].url);// console.log(JSON.parse(result).url,"--------");// this.formData.userImg = JSON.parse(result).url;let item = this[`fileList${event.name}`][fileListLen];this[`fileList${event.name}`].splice(fileListLen,1,Object.assign(item, {status: "success",message: "",url: JSON.parse(result).url,}));fileListLen++;}//打印输出所有的文件列表console.log(this.fileList1);//选择第一张照片,存储到数据库表this.formData.userImg =  this.fileList1[0].url;},uploadFilePromise(url) {return new Promise((resolve, reject) => {let a = uni.uploadFile({url: "http://localhost:8080/common/upload", // 仅为示例,非真实的接口地址filePath: url,name: "file",formData: {user: "test",},header: {'authorization': 'Bearer ' + uni.getStorageSync('token')},success: (res) => {setTimeout(() => {console.log(res.data, "文件上传后返回响应对象");resolve(res.data);}, 1000);},});});}
​},onLoad() {this.loadChannel();}}
</script>
​
<style>
</style>

6、删除

request.js

export const put = (url, data, options = {}) => {return request({ url, data, method: 'PUT', ...options });
};
​
export const del = (url, data, options = {}) => {return request({ url, data, method: 'DELETE', ...options });
};
​

<u-list-item v-for="(item, index) in indexList" :key="index"><u-cell :title="item.channelName"><u-avatar slot="icon" shape="square" size="35" :src="item.userImg"customStyle="margin: -3px 5px -3px 0"></u-avatar><text slot="value">修改|</text><text slot="value" @click="deleteChannel(item, index)">删除</text></u-cell></u-list-item>
</u-list>
​
​
​
​
async deleteChannel(item, index){//获取主键console.log(item.channelId);const res = await del("/system/channels/"+item.channelId);console.log(res);//判断失败,提醒//成功,刷新this.loadChannel();},

7、修改

1、点击修改按钮,传递id到修改页面

2、修改页面 onload函数中获取主键id

3、判断id是否存在,存在根据id查询详情,回显数据

4、更新数据到数据库表

5、联调新增和修改。

toEdit(item){//跳转到新增|修改页面  传递主键uni.navigateTo({url:"/pages/channel/channelAdd?id="+item.channelId})},
onLoad(options) {//判断是否是修改if(options != null && options.id!=null && options.id!=''){uni.setNavigationBarTitle({title: '修改渠道'});//调用方法,查询详情this.getChannelDtail(options.id);}}
async submit() {const validate = await this.$refs.form.validate();//接收数据console.log(this.formData);var resp = null ;//发起网路请求if(this.formData.channelId==null || this.formData.channelId==''){//新增resp = await post('/system/channels', this.formData);}else{//修改resp = await put('/system/channels', this.formData);}if (resp.code == 200) { //成功//跳转到列表查询uni.navigateTo({url: "/pages/channel/channel"})} else {console.log("操作失败");}​},

8、下拉刷新

"globalStyle": {"navigationBarTextStyle": "black","navigationBarTitleText": "uni-app","navigationBarBackgroundColor": "#dfd7ce","backgroundColor": "#F8F8F8","app-plus": {"background": "#efeff4"},"enablePullDownRefresh": true}
onPullDownRefresh() {let pageSize = Math.ceil(this.total/3);if(this.currentPage >= pageSize){console.log("已经最后一页");}else{this.loadChannel(++this.currentPage);}setTimeout(()=>{uni.stopPullDownRefresh();},1000);}

9、搜索+分页

<uni-forms ref="form" :modelValue="formData" ><uni-forms-item label="渠道名称" name="channelName"><uni-easyinput type="text" v-model="formData.channelName" placeholder="请输入渠道名称" /></uni-forms-item><uni-forms-item label="渠道编码" name="channelCode"><uni-easyinput type="text" v-model="formData.channelCode" placeholder="请输入渠道编码" /></uni-forms-item></uni-forms><button @click="search">搜索</button>
async search(){this.indexList = [];this.loadChannel(1) ;}, 
http://www.xdnf.cn/news/15486.html

相关文章:

  • 2025秋招突围战:AI智能监考如何重构远程笔试公平防线?
  • 深入解析 AWS RDS Proxy
  • 达梦数据库配置兼容MySQL
  • 从 “洗澡难” 到 “洗得爽”:便携智能洗浴机如何重塑生活?
  • Vue 结合 Zabbix API 获取服务器 CPU、内存、GPU 等数据
  • LabVIEW Occurrence功能
  • go项目实战
  • 高频面试雷区:Java Object六大核心方法源码剖析
  • Linux Ubuntu apt包管理器安装K8s1.30.1+Ingress-Nginx
  • fastadmin中ajax弹窗修改文字为英文
  • AJAX 技术
  • MinIO介绍以及结合SpringBoot的应用场景详解
  • 数据降维方法:PCA
  • 微算法科技研究量子视觉计算,利用量子力学原理提升传统计算机视觉任务的性能
  • flink sql读hive catalog数据,将string类型的时间戳数据排序后写入kafka,如何保障写入kafka的数据是有序的
  • 动态规划题解_打家劫舍【LeetCode】
  • 解决容器dns问题
  • [时序数据库-iotdb]时序数据库iotdb的安装部署
  • Go从入门到精通(25) - 一个简单web项目-实现链路跟踪
  • audiorecord 之 抢占优先级
  • 数据库询问RAG框架Vanna的总体架构
  • CMake基础:覆盖项目开发的五大配套工具
  • 数据结构——顺序表的相关操作
  • 信息学奥赛一本通 1552:【例 1】点的距离
  • 【Keil】C/C++混合编程的简单方法
  • 内存的基础相关知识,什么是内存,内存管理
  • 学习C++、QT---26(QT中实现记事本项目实现文件路径的提示、C++类模板、记事本的行高亮的操作的讲解)
  • LVS(Linux Virtual Server)详细笔记(理论篇)
  • 202507中央城市工作会议
  • 【Java】JUC并发(线程的方法、多线程的同步并发)