开源软件名称:easy-mobile
开源软件地址:https://gitee.com/ericfang/easy-mobile
开源软件介绍:
Easy Mobile功能- 完善的路由系统,提供常规前进路由功能,同时支持返回钩子、强制刷新、返回跳过等功能;
- 全局布局组件,提供上中下三层布局结构;
- 无限滚动组件,提供下拉刷新和下拉加载功能;
- 页面切换动画效果,类似 APP 的前进后退效果;
- 所有动画效果均采用 CSS 动画,无论是无限滚动组件还是页面切换动画均丝滑流畅。
- 可直接封装至 hybird APP 打包,无需再做原生页面跳转等繁琐功能;
路由跳转函数跳转到某一个页面 <!-- 使用原型链助手函数 --> <div @click="$navigate.to('path')"></div> <!-- webStorm 貌似现在不支持自动提示手动加载 Vue 上的原型连方法,因此特地加入的全局助手函数混入。 --> <!-- 使用全局混入助手函数 --> <div @click="g_navigate.to('path')"></div> 跳转到某个页面并传入参数 <!-- params 传参--> <div @click="$navigate.to('path', {params: {id:5}})"></div> <div @click="$navigate.toParams('path', {id:5})"></div> <!-- query 传参 --> <div @click="$navigate.to('path', {query: {id:5}})"></div> <div @click="$navigate.toQuery('path', {id:5})"></div> 返回上一页 <!-- 正常返回上一页 --> <div @click="$navigate.back()"></div> <!-- 返回并跳过上一页,可添加 p1,p2 等参数 --> <div @click="$navigate.backSkip(p1,p2)"></div> <!-- 返回并执行上一页 methods 中的 hook 函数,可传入 p1,p2 等参数 --> <div @click="$navigate.backInvoke('hook', p1,p2)" 返回跳过上一页继承 事实上,返回跳过上一页,只是执行了 $navigate.backInvoke('BACK_SKIP', ... params ) 。 而 PageMixin 混入中有默认的 BACK_SKIP 函数会被触发。 如果在 PageMixin 混入的页面中 将 PAGE_BACK_SKIP_INHERIT 参数设置为 true , 则会继续继承跳转并执行以上函数,因此所传递的参数将被保留和传递到更上一页,中间也可以有页面覆盖 BACK_SKIP 函数来拦截并自由操作。 具体使用可参考案例源码; navigate 方法 方法 | 作用 | 参数 | 备注 |
---|
to | 跳转到某一个页面 | String : 路由path, Object : vue-route的参数 | 第二参数可不填 | toQuery | 带 query 参数跳转 | String : 路由path, Object: query 参数 | 第二参数可不填 | toParams | 带 params 参数跳转 | String : 路由path, Object: params 参数 | 第二参数可不填 | back | 常规返回上一页 | | | backInvoke | 返回上一页并执行钩子函数 | String : 上一页的函数名, ... params : 参数 | 返回后将执行上一页 methods 中的指定方法 | backSkip | 返回并跳过上一页 | | |
路由配置和混入NavigateMixin 组件级导航混入 组件级混入,可在任意组件中使用,将会自动判断当前组件所在页面是否为前进还是后退,并相应执行对应的钩子函数。 当页面是从其他页面前进而来,则自动执行组件methods中的init() 函数。 相反的,如果当前页是从其他页面返回而来,则自动执行组件 methods 中的 backInit() 函数。 可通过在组件中覆盖这些函数来实现对应功能; import {NavigateMixin} from "@/mixin/navigate.mixin";export default { name: 'component', mixins: [NavigateMixin], data() { return { // 强制刷新,无论是返回还是打开 NAV_FORCE_RELOAD: false, // 初始化执行延迟时间(尽量和切换动画时间一致,防止动画在执行js时卡顿) // 页面切换后多少 ms 后执行 init() 函数 NAV_INIT_DELAY: 400, // 返回钩子函数执行延时 // 页面切换返回后多少 ms 后执行 backInit() 函数 NAV_BACK_HOOK_DELAY: 1, } }, methods: { // 当页面混入添加了 NavigateMixin 后 // 同时页面是被前进到此(打开页面) // 则 init() 函数将会被自动回调 init() { // 初始化页面操作(获取数据、刷新页面等) }, // 与 init 正好相反,返回到此页 执行 backInit(){ // 如果是返回到此页的话 }, }}; PageMixin 页面级导航混入 如果当前组件为路由页面,则使用 PageMixin 混入,此混入包含返回跳过等功能和配置 import {PageMixin} from "@/mixin/navigate.mixin"; export default { name: 'component', mixins: [PageMixin], data() { return { // 自动返回,当页面为返回情况下,自动再次返回到上一页 PAGE_AUTO_BACK: false, // 返回跳过继承,上一页如果是返回跳过的话是否本页也继承跳过 PAGE_BACK_SKIP_INHERIT: false, } }, methods: { // 当页面混入添加了 NavigateMixin 后 // 同时页面是被前进到此(打开页面) // 则 init() 函数将会被自动回调 init() { // 初始化页面操作(获取数据、刷新页面等) }, // 与 init 正好相反,返回到此页 执行 backInit(){ // 如果是返回到此页的话 }, } };
请求使用request 方法介绍 request 方法是由 axios 封装而来,添加了请求拦截和响应拦截。 文件位置: src/utils/request.util.js ; 请求拦截 添加延时反馈,用于调试 mockjs 瞬间返回请求等问题; 添加 serialize 识别,在 headers 中添加 serialize : true 则自动将 data 参数做 urlEncode 操作, 默认使用 json 格式做 post 提交; 响应拦截 添加标准格式解析,默认接受后端反馈标准格式为 : resp = { "code": 200, // 状态码 100:常规错误带message提示;200:正常; "message": "", // 文本信息 "data": null // 内容,可以是任意格式 } 拦截器会自动识别 code 状态,当 code === 200 时,将 data 返回,因此使用 request 函数, then 中回调参数是 data , 而不是整个反馈内容。 如果 code !== 200 则会执行 src/utils/response.error.util.js 中定义的对应 code[code] 函数,不存在则忽略,可自行在以上文件中定义不同的 code 回调函数; 更多自定义可根据自身需求在对应文件中修改。
request 使用方法1 直接传入 axios 的 option 配置返回 Promise 对象 import {request} from "@/utils/request.util"; request({ url : 'api/address', method: 'get', params: { id: 1 } }).then( resp => { // 这里的 resp 返回的是已经经过处理后的 data 内容 console.log( resp ); }) request 使用方法2 链式调用 request 函数 import {request} from "@/utils/request.util";// 目前仅提供 get 和 post 方法,其他需要可自行添加。request("api/address").get({id : 1}).then( resp => { console.log( resp );})
无限滚动基础组件为 better-scroll ,在此组件上封装了一层业务逻辑,让开发变得轻松一些; 无限滚动组件需要和 Paginate 配合使用,Paginate 实现比较简单,可自行查看源码; 如需修改下拉和上拉样式,可自行修改 ezm-scroll-box 组件; 下拉加载和上拉加载的完整案例 <template> <div class=""> <ezm-layout> <van-nav-bar slot="nav" title="下拉刷新加上拉加载更多" left-arrow @click-left="g_navigate.back()" ></van-nav-bar> <!-- 无限滚动组件 --> <!-- 如需下拉或上拉功能,则必须传入分页对象 --> <ezm-scroll-box :pull-down="true" :pull-up="true" :paginate="paginate" > <van-cell v-for="item in list" :key="item.id" :title="item.title" :label="item.label" :value="item.id" ></van-cell> </ezm-scroll-box> </ezm-layout> </div> </template> <script> import EzmLayout from "@/components/layout/ezm-layout"; import EzmScrollBox from "@/components/scroll/ezm-scroll-box"; import Paginate from "@/utils/paginate.util"; import {mockUtil} from "@/utils/common.util"; import {request} from "@/utils/request.util"; import {PageMixin} from "@/mixin/navigate.mixin"; export default { name: 'BetterScrollAll', mixins: [PageMixin], components: {EzmScrollBox, EzmLayout}, data() { return { // 生成分页对象 // 分页接受两个参数 Function : 下拉或上拉的回调方法,(可选)Integer : 每页数量 paginate: new Paginate(this.getList), list: [], } }, methods: { /** * 进入页面时将自动触发 init() 函数 * 返回到此页则不会被执行 */ init() { // 自动触发下拉刷新操作 this.paginate.autoPullDown(); }, /** * 将会被下拉和上拉回调的函数 * paginate 在回调此函数的时候会自动传入 refresh 参数 * 下拉刷新则 传入 true, 上拉加载更多则传入 false * @param refresh 是否为下拉刷新 */ getList(refresh = false) { // 预先使用 mockjs 模拟数据,如有真实接口则无需模拟 this.mockData(); // 请求 BetterScrollAll 的 get 接口,并传入分页参数 // this.paginate.getRequestParams() 可以从分页对象中提取后端需要的分页参数 request('BetterScrollAll') .get(this.paginate.getRequestParams()) .then(resp => { // 将数据并入 list 或覆盖 list this.list = refresh ? resp.records : this.list.concat(resp.records); // 完成数据加载 // 记得一定要传入 resp ,paginate 会根据 resp 结果判定是否还有下一页 // 分别显示不同的底部内容,如 ’没有更多了‘ 等; this.paginate.finishLoading(resp); }) // 如果请求失败,则必须调用完成数据加载 // 无需传递参数,仅结束加载动画 .catch(_ => this.paginate.finishLoading()); }, /** * 模拟 2 页 完整数据, * 第三页数据为 5 条 */ mockData() { mockUtil.mock(/BetterScrollAll/i, 'get', { code: 200, message: '', data: { current: this.paginate.toPage, size: this.paginate.size, [`records|${this.paginate.toPage > 2 ? 5 : this.paginate.size}`]: [{ 'id|+1': (this.paginate.toPage - 1) * this.paginate.size + 1, 'title': '@cname', 'label': '@name', }], } }) } } }; </script>
待办队列我们都知道单页应用都存在一些小问题,比如:打开一个 dialog, 之后点击浏览器返回按钮,发现 dialog 不会消失,因此在弹出 dialog 的时候,可以把 关闭 dialog 的函数添加到 待办队列 , 并且在关闭 dialog 的时候,把之前添加进去的 待办函数 移出 待办队列 。 待办列表中的函数会在页面离开之前执行,如果强行点击浏览器返回按钮,则一次性执行全部待办函数,如调用 navigate 中的方法进行前进或后退,则会依次(倒序)执行待办函数 (点一次执行一个待办); 具体案例在 demo 中有比较详细的演示,这里提供一个对 vant 的 Dialog.config 封装案例 let confirm = (content, title = "确认信息", type = 'warning') => { let dialog = Dialog.confirm({ title: title, message: content, }); let task = Events.addWaitTask(() => Dialog.close()); return dialog.then(() => { Events.removeWaitTask(task); return Promise.resolve(); }).catch(() => { Events.removeWaitTask(task); return Promise.reject(); }) } Events 对象中包含了返回回调函数 和 待办列表队列,这里只列出经常使用到的待办相关方法 方法 | 功能 | 参数 | 返回 | 备注 |
---|
addWaitTask | 添加待办任务 | Function: 待办函数 | WaitForTask : 待办任务 | | removeWaitTask | 移除待办任务 | WaitForTask : 待办任,| String: 待办任务id | | 留空则清空所有待办任务 |
待办任务 WaitForTask 结构,当使用 Events.addWaitTask 的时候, id 会自动生成一个 uuid ,无需手动生成 id , export class WaitForTask { constructor(id, task) { this.id = id; this.task = task; } id = ''; task = null;} |
请发表评论