文章目录
- 原型是用的码前做的,大家可以通过www.devbefore.com/protomobile/47942983009476608查看
- 本项目中前端采用APICloud AVM多端开发技术进行开发,要点包括 swiper 轮播图、网络请求封装等。使用 APICloud 多端技术进行开发,实现一套代码多端运行,支持编译成 Android & iOS App 以及微信小程序。
- (1)下载 APICloud Studio 3 作为开发工具。下载地址:www.apicloud.com/studio3 (2)注册账号后在控制台创建app,控制台地址:www.apicloud.com/console (3)设置证书,一键创建安卓证书 (4)APICloud Studio3 拉取代码,点击项目,导出云端检出 检出 检出后工作目录 (5)修改或者提交项目源码,并为当前项目云编译自定义 Loader 进行真机同步调试预览。 使用 AppLoader 进行真机同步调试预览,后台自动以loader下载到手机端,安装后,点击小圆圈,输入ip地址:192.168.2.152 端口:10916,连接后真机同步,可以看到刚创建后的结果。
- 为什么选择AVM? 易用:有 Vue、React 基础,可快速上手,配套专用的开发工具APICloud Studio3。 多端:一次开发,多端渲染,一个技术栈搞定移动端开发。 功能 API 丰富:提供 1千+ 模块和 2万+ API 可直接调用,面向行业和场景无限制) (1)UI 官方文档:https://docs.apicloud.com/apicloud3/#/component/view?index=4&subIndex=0 原来有一个叫流浪男的做的AUI框架,还不错,后来就是用一些简单的大公司的框架,这个看自己了。好多UI都是自己设计,自己写一些UI。字体图标用的阿里字体图标。CSS框架,要是没啥选择推荐可以用AUI,这个框架有CSS基础的一看就知道写的啥,而且特别好修改。实在不行了直接改源码。 APICloud官网组装了一套vant的,https://docs.apicloud.com/Client-API/AVM-Components/readme.md (2)ajax网络交互 // 表单方式提交数据或文件 // 表单方式提交数据或文件api.ajax({ url: 'http://192.168.1.101:3101/upLoad', method: 'post', data: { values: { name: 'haha' }, files: { file: 'fs://a.gif' } }}, function(ret, err) { if (ret) { api.alert({ msg: JSON.stringify(ret) }); } else { api.alert({ msg: JSON.stringify(err) }); }});// 提交JSON数据api.ajax({ url: 'http://192.168.1.101:3101/upLoad', method: 'post', headers: { 'Content-Type': 'application/json;charset=utf-8' }, data: { body: { name: 'haha' } }}, function(ret, err) { if (ret) { api.alert({ msg: JSON.stringify(ret) }); } else { api.alert({ msg: JSON.stringify(err) }); }}); (3)vue指令使用(v-for v-show v-if v-else v-for v-on v-bind v-model等) 1>数据绑定 使用 Mustache 语法: <text text={{msg}}></text> 使用v-bind指令: <text v-bind:text="msg"></text> 2>事件绑定 <template> <text onclick="doThis('avm');">Click me!</text></template><script> export default { name: 'test', methods: { doThis(msg){ api.alert({ msg: msg }); } } }</script> (4)注册、登录 1>注册接口链接:http://showdoc.deui.cn/web/#/27?page_id=365 注册代码 <template name='tpl'> <view class="page"> <div class="page1"> <safe-area class="header"> <!-- <text class="header__title">APICloud</text> --> </safe-area> <scroll-view class="main"> <view> <image src="https://baodinglingqian.oss-cn-beijing.aliyuncs.com/1.png" class="touxiang " /> </view> <div class="zhanghao"> <input placeholder="请输入账号" v-model="zhanghao" maxlength="10" autofocus /> </div> <div class="mima"> <input type="password" placeholder="请输入密码" v-model="password" /> </div> <text class="zhuce" @click="reg()">注册</text> <text class="denglu" @click="handleClick()">登录</text> </scroll-view> </div> <image class="originImage" mode="scaleToFill" src={src}></image> </view></template><script>export default { name: "tpl", apiready() { api.setStatusBarStyle({ style: "light", color: "-" }); }, data() { return { zhanghao: '', password: '', src: "https://baodinglingqian.oss-cn-beijing.aliyuncs.com/bg.png" }; }, computed: { }, methods: { handleClick(e) { api.openWin({ name: 'main', url: './main.stml', pageParam: { name: 'test' } }); }, reg() { var _this = this; // 提交JSON数据 api.ajax({ url: 'http://yy.deui.cn/api.php/index/re', method: 'get', // headers: { // 'Content-Type': 'application/json;charset=utf-8' // }, data: { body: { username: _this.zhanghao, password: _this.password } } }, function (ret, err) { console.log(JSON.stringify(ret)) if (ret.msg == '返回成功') { api.toast({ msg: '注册成功', location: "middle" }); } else { api.alert({ msg: JSON.stringify(err) }); } }); } }};</script><style>.denglu { margin-top: 10px; font-size: 14px;}.touxiang { margin-top: 10%; width: 150px; height: 150px; border-radius: 100px; margin: 0 auto;}html { width: 100%; height: 100%;}body { width: 100%; height: 100%;}.originImage { position: absolute; top: 0px; left: 0px; right: 0px; bottom: 0px; z-index: 1;}.page { /* position:fixed; */ position: relative; z-index: 9; width: 100%; height: 100%;}.page1 { position: absolute; top: 0px; left: 0px; right: 0px; bottom: 0px; z-index: 2;}input { padding-left: 10px; line-height: 35px; height: 35px; border-radius: 5px;}.zhanghao { display: block; margin: 0 auto; margin-top: 15%; margin-bottom: 15px; height: 60px;}.mima { display: block; margin: 0 auto; margin-top: 25px;}.zhuce { width: 100%; height: 35px; line-height: 35px; background-color: coral; text-align: center; color: #fff; margin-top: 25px;}.page { height: 100%; background-color: white;}.header { background: #81a9c3; justify-content: center; align-items: center;}.header__title { color: #fff; font-size: 18px; font-weight: bold; height: 50px; line-height: 50px;}.main { flex: 1; padding: 15px;}.h1 { font-size: 24px;}.item { flex-direction: row; padding: 10px 0;}.item__text { color: #333; white-space: nowrap;}.item__value { margin-left: 5px;}.footer { background: #81a9c3; flex-direction: row; justify-content: center; align-items: center;}.footer__text { color: #fff; font-size: 14px; height: 30px; line-height: 30px;}</style> 2>登录接口链接:http://showdoc.deui.cn/web/#/27?page_id=364 登录代码 <template name='tpl'> <view class="page"> <div class="page1"> <safe-area class="header"> <!-- <text class="header__title">APICloud</text> --> </safe-area> <scroll-view class="main"> <view> <image src="https://baodinglingqian.oss-cn-beijing.aliyuncs.com/1.png" class="touxiang " /> </view> <div class="zhanghao"> <input placeholder="请输入账号" v-model="zhanghao" maxlength="10" autofocus /> </div> <div class="mima"> <input type="password" placeholder="请输入mima" v-model="password" /> </div> <text class="zhuce" @click="login()">登录</text> <text class="denglu" @click="handleClick()">注册</text> </scroll-view> </div> <image class="originImage" mode="scaleToFill" src={src}></image> </view></template><script>export default { name: "tpl", apiready() { api.setStatusBarStyle({ style: "light", color: "-" }); var value = localStorage.getItem('uid'); api.openWin({ name: 'home', url: './home.stml' }); }, data() { return { zhanghao: '', password: '', src: "https://baodinglingqian.oss-cn-beijing.aliyuncs.com/bg.png" }; }, computed: { }, methods: { handleClick(e) { api.openWin({ name: 'region', url: './region.stml', pageParam: { name: 'test' } }); // api.toast({ // msg: this.data.text, // location: "middle" // }); }, login() { var _this = this; api.ajax({ url: 'http://yy.deui.cn/api.php/index/login', method: 'get', // headers: { // 'Content-Type': 'application/json;charset=utf-8' // }, data: { body: { username: _this.zhanghao, password: _this.password } } }, function (ret, err) { console.log(JSON.stringify(ret)) localStorage.setItem('uid', ret.data.data[0]['id']); if (ret.msg == '返回成功') { api.toast({ msg: '登录成功', location: "middle" }); api.openWin({ name: 'home', url: './home.stml' }); } else { api.alert({ msg: JSON.stringify(err) }); } }); } }};</script><style>.denglu { margin-top: 10px; font-size: 14px;}.touxiang { margin-top: 10%; width: 150px; height: 150px; border-radius: 100px; margin: 0 auto;}html { width: 100%; height: 100%;}body { width: 100%; height: 100%;}.originImage { position: absolute; top: 0px; left: 0px; right: 0px; bottom: 0px; z-index: 1;}.page { /* position:fixed; */ position: relative; z-index: 9; width: 100%; height: 100%;}.page1 { position: absolute; top: 0px; left: 0px; right: 0px; bottom: 0px; z-index: 2;}input { padding-left: 10px; line-height: 35px; height: 35px; border-radius: 5px;}.zhanghao { display: block; margin: 0 auto; margin-top: 15%; margin-bottom: 15px; height: 60px;}.mima { display: block; margin: 0 auto; margin-top: 25px;}.zhuce { width: 100%; height: 35px; line-height: 35px; background-color: coral; text-align: center; color: #fff; margin-top: 25px;}.page { height: 100%; background-color: white;}.header { background: #81a9c3; justify-content: center; align-items: center;}.header__title { color: #fff; font-size: 18px; font-weight: bold; height: 50px; line-height: 50px;}.main { flex: 1; padding: 15px;}.h1 { font-size: 24px;}.item { flex-direction: row; padding: 10px 0;}.item__text { color: #333; white-space: nowrap;}.item__value { margin-left: 5px;}.footer { background: #81a9c3; flex-direction: row; justify-content: center; align-items: center;}.footer__text { color: #fff; font-size: 14px; height: 30px; line-height: 30px;}</style> (5)首页轮播图 轮播图链接:http://showdoc.deui.cn/web/#/27?page_id=366 <template name='tpl'> <view class="page"> <div class="page1"> <safe-area class="header"> <text class="header__title">首页</text> </safe-area> <scroll-view class="main" scroll-y> <swiper class="swiper" id="customSwiper" autoplay circular indicator-dots indicator-color="#ddd" indicator-active-color="#f0f"> <swiper-item class="swiper-item" v-for="(_item,_index) in bannerlist"> <!-- <text class="desc">{_item.image}</text> --> <image mode="scaleToFill" src={_item.image}></image> </swiper-item> </swiper> <div> <a-cell-group> <a-cell v-bind:title="_item.name" v-bind:value="_item.content" v-bind:label="_item.address" arrow-direction="right" @click="godetial(_item)" v-for="(_item,_index) in shangjialist" /> <!-- <a-cell title="单元格" value="内容" label="描述信息" /> --> </a-cell-group> </div> </scroll-view> </div> <image class="originImage" mode="scaleToFill" src={src}></image> </view></template><script>import ACellGroup from "../../components/act/a-cell-group";import ACell from "../../components/act/a-cell";export default { name: 'test', data() { return { shangjialist: [], bannerlist: [], current: 0, src: "https://baodinglingqian.oss-cn-beijing.aliyuncs.com/bg.png" } }, methods: { apiready() { this.banner() this.allstores() // var customSwiper = document.getElementById('customSwiper'); // customSwiper.load({ // data: this.data.dataList // }); }, onchange(e) { this.data.current = e.detail.current; }, godetial(item) { console.log(JSON.stringify(item)) api.openWin({ name: 'detial', url: './detial.stml', pageParam: { id: item.id } }); }, banner() { var _this = this; api.ajax({ url: 'http://yy.deui.cn/api.php/index/banner', method: 'get', }, function (ret, err) { if (ret.msg == '返回成功') { _this.data.bannerlist = ret.data.data // var customSwiper = document.getElementById('customSwiper'); // customSwiper.load({ // data: _this.data.bannerlist // }); // console.log(JSON.stringify(_this.bannerlist)) } else { api.alert({ msg: JSON.stringify(err) }); } }); }, allstores() { var _this = this; api.ajax({ url: 'http://yy.deui.cn/api.php/index/stores', method: 'get', }, function (ret, err) { if (ret.msg == '返回成功') { console.log(1) console.log(JSON.stringify(ret.data.data)) console.log(1) var obj = ret.data.data for (let index = 0; index < obj.length; index++) { const element = obj[index]; element['content'] = element['content'].substring(0, 9) + '...' } console.log(JSON.stringify(obj)) _this.data.shangjialist = obj } else { api.alert({ msg: JSON.stringify(err) }); } }); } }}</script><style>.denglu { margin-top: 10px; font-size: 14px;}.touxiang { margin-top: 10%; width: 150px; height: 150px; border-radius: 100px; margin: 0 auto;}html { width: 100%; height: 100%;}body { width: 100%; height: 100%;}.originImage { position: absolute; top: 0px; left: 0px; right: 0px; bottom: 0px; z-index: 1;}.page { /* position:fixed; */ position: relative; z-index: 9; width: 100%; height: 100%;}.page1 { position: absolute; top: 0px; left: 0px; right: 0px; bottom: 0px; z-index: 2;}input { padding-left: 10px; line-height: 35px; height: 35px; border-radius: 5px;}.zhanghao { display: block; margin: 0 auto; margin-top: 15%; margin-bottom: 15px; height: 60px;}.mima { display: block; margin: 0 auto; margin-top: 25px;}.zhuce { width: 100%; height: 35px; line-height: 35px; background-color: coral; text-align: center; color: #fff; margin-top: 25px;}.page { height: 100%; background-color: white;}.header { background: #81a9c3; justify-content: center; align-items: center;}.header__title { color: #fff; font-size: 18px; font-weight: bold; height: 50px; line-height: 50px;}.main { flex: 1; padding: 0px;}.h1 { font-size: 24px;}.item { flex-direction: row; padding: 10px 0;}.item__text { color: #333; white-space: nowrap;}.item__value { margin-left: 5px;}.footer { background: #81a9c3; flex-direction: row; justify-content: center; align-items: center;}.footer__text { color: #fff; font-size: 14px; height: 30px; line-height: 30px;}.main { width: 100%; height: 100%;}.swiper { width: 100%; height: 190px; /* background-color: blue; */}.swiper-item { justify-content: center;}.title { padding: 10px 0; font-size: 20px;}.desc { width: 100%; text-align: center;}.container { width: 100%; height: 200px;}.indicator { flex-direction: row; justify-content: center; position: absolute; width: 100%; height: 20px; bottom: 8px;}.indicator-item { width: 15px; height: 8px; margin: 3px;}.indicator-item-normal { background-color: #ddd;}.indicator-item-active { background-color: red;}</style> (6)首页列表 所有店铺链接:http://showdoc.deui.cn/web/#/27?page_id=369 上面的5的代码里面含有了。 <a-cell-group> <a-cell v-bind:title="_item.name" v-bind:value="_item.content" v-bind:label="_item.address" arrow-direction="right" @click="godetial(_item)" v-for="(_item,_index) in shangjialist" /></a-cell-group> shangjialist: [],allstores() { var _this = this; api.ajax({ url: 'http://yy.deui.cn/api.php/index/stores', method: 'get', }, function (ret, err) { if (ret.msg == '返回成功') { console.log(1) console.log(JSON.stringify(ret.data.data)) console.log(1) var obj = ret.data.data for (let index = 0; index < obj.length; index++) { const element = obj[index]; element['content'] = element['content'].substring(0, 9) + '...' } console.log(JSON.stringify(obj)) _this.data.shangjialist = obj } else { api.alert({ msg: JSON.stringify(err) }); } }); } (7)页面传参获取详情 api.openWin({ name: 'detial', url: './detial.stml', pageParam: { id: 123 } }); apiready() {//like created if (api.pageParam.id) { this.data.id = api.pageParam.id } console.log(this.data.id) } 店铺详情:http://showdoc.deui.cn/web/#/27?page_id=370 <template> <view class="page"> <view> <a-nav-bar v-bind:title="title" left-text="返回" left-arrow @click-left="onClickLeft" @click-right="onClickRight" /> </view> <view> <a-cell-group> <a-cell title="名称" v-bind:value="store.name" /> <a-cell title="电话" v-bind:value="store.phone" /> <a-cell title="城市" v-bind:value="store.city" /> <a-cell title="地址" v-bind:value="store.address" /> <a-cell title="内容" v-bind:value="store.content" /> </a-cell-group> <!-- <text text={{store.name}}></text> <text text={{store.city}}></text> <text text={{store.content}}></text> <text text={{store.address}}></text> <text text={{store.phone}}></text> --> </view> <view> <a-button type="success">产品</a-button> </view> <view> <a-cell-group> <a-cell v-bind:title="_item.name" v-bind:value="_item.content" label="点击可预约" v-for="(_item,_index) in product" @click="yuyuproduct(_item)" /> </a-cell-group> </view> </view></template><script>import ACellGroup from "../../components/act/a-cell-group";import ACell from "../../components/act/a-cell";import ANavBar from "../../components/act/a-nav-bar";import AButton from "../../components/act/a-button";export default { name: 'detial', apiready() {//like created if (api.pageParam.id) { this.data.id = api.pageParam.id } console.log(this.data.id) this.init() }, data() { return { title: "详情", id: 1, store: {}, product:[] } }, methods: { init() { var _this = this; api.ajax({ url: 'http://yy.deui.cn/api.php/index/searchstore', method: 'get', data: { body: { id: _this.data.id } } }, function (ret, err) { if (ret.msg == '返回成功') { console.log(1) console.log(JSON.stringify(ret.data.product)) console.log(1) _this.data.store = ret.data.data[0] _this.data.product = ret.data.product } else { api.alert({ msg: JSON.stringify(err) }); } }); }, yuyuproduct(_item){ console.log(JSON.stringify(_item)) }, onClickLeft() { api.closeWin(); }, onClickRight() { } }}</script><style>.page { height: 100%;}</style> (8)导航栏组件 import ANavBar from "../../components/act/a-nav-bar"; <view> <a-nav-bar v-bind:title="title" left-text="返回" left-arrow @click-left="onClickLeft" @click-right="onClickRight" /> </view> 注意:导航栏组件的使用,文档中的引用 import ACell from"../../components/act/a-nav-bar.stml"; 使用中建议去掉stml后缀,import ACell from"../../components/act/a-nav-bar"; (9)localStorage 对象使用 main.stml里面的这个,就是用的这个对象 localStorage.setItem('uid', ret.data.data[0]['id']); 下面是localStorage的用法 // 设置存储.sessionStorage.setItem('key', 'value');// 获取存储.var value = sessionStorage.getItem('key');// 移除存储sessionStorage.removeItem('key');// 清除所有存储项sessionStorage.clear();// 获取已有存储项数var length = sessionStorage.length;// 根据存储项索引获取存储键名var keyName = sessionStorage.key(index); (10)APICloud组件、模块的使用 模块中添加模块,如果是H5的需要下载后,放到自己的代码中;如果是原生的模块,需要添加到自己应用中,去require去使用。网上有专门介绍这块的教程,不清楚的可以去搜搜。
- 这块是自己写的php后台,用的tp5框架。 tp5下的fastadmin框架,可以根据fastadmin一键生成简单后台,数据库文件为: 后台接口代码 <?phpnamespace app\api\controller;use app\common\controller\Api;use think\Db;/** * 首页接口 */class Index extends Api{ protected $noNeedLogin = ['*']; protected $noNeedRight = ['*']; /** * 首页 * */ public function index() { $this->success('请求成功'); } //注册 public function re(){ $username = $this->request->request("username"); $password = md5($this->request->request("password")); $sql = " INSERT INTO `yuyuuser` (`id`, `group_id`, `username`, `nickname`, `password`, `salt`, `email`, `mobile`, `avatar`, `level`, `gender`, `birthday`, `bio`, `money`, `score`, `successions`, `maxsuccessions`, `prevtime`, `logintime`, `loginip`, `loginfailure`, `joinip`, `jointime`, `createtime`, `updatetime`, `token`, `status`, `verification`) VALUES (NULL, '0', '', '".$username ."', '".$password."', '', '', '', '', '0', '0', NULL, '', '0.00', '0', '1', '1', NULL, NULL, '', '0', '', NULL, NULL, NULL, '', '', '')"; $rst = Db::query($sql); $data =1; $this->success('返回成功', ['data' => $data]); } //登录 public function login(){ $username = $this->request->request("username"); $password = md5($this->request->request("password")); $sql = "SELECT nickname,id FROM yuyuuser where nickname='".$username."' and password='".$password."' order by id DESC LIMIT 1"; $rst = Db::query($sql); $this->success('返回成功', ['data' => $rst]); } //获取轮播图 public function banner() { $sql = "SELECT * FROM `yuyubanner`"; $rst = Db::query($sql); $this->success('返回成功', ['data' => $rst]); } //获取网络协议 public function xieyi() { $sql = "SELECT * FROM `yuyuxieyi`"; $rst = Db::query($sql); $this->success('返回成功', ['data' => $rst]); } //所有类型 public function leixing() { $sql = " SELECT * FROM `yuyutype`"; $rst = Db::query($sql); $this->success('返回成功', ['data' => $rst]); } //所有店面 public function stores() { $sql = " SELECT * FROM `yuyustore`"; $rst = Db::query($sql); $this->success('返回成功', ['data' => $rst]); } //店铺信息 public function searchstore() { $id = $this->request->request("id"); $sql = " SELECT * FROM `yuyustore` where id = ".$id; $sql1 = "SELECT * FROM `yuyuproduct` where store_id = ".$id; $rst = Db::query($sql); $rst1 = Db::query($sql1); $this->success('返回成功', ['data' => $rst,'product'=>$rst1]); }}
前段时间跟朋友一起搞了一个预约的项目,前端用的APICloud的AVM框架做的,后端用的php开发的,用的tp5框架,没几天就搞出来了。简单跟大家分享一下开发中的一些功能点的实现吧。也欢迎大家一起探讨。

原型是用的码前做的,大家可以通过www.devbefore.com/protomobile/47942983009476608查看
本项目中前端采用APICloud AVM多端开发技术进行开发,要点包括 swiper 轮播图、网络请求封装等。使用 APICloud 多端技术进行开发,实现一套代码多端运行,支持编译成 Android & iOS App 以及微信小程序。
(1)下载 APICloud Studio 3 作为开发工具。下载地址:www.apicloud.com/studio3
(2)注册账号后在控制台创建app,控制台地址:www.apicloud.com/console

(3)设置证书,一键创建安卓证书

(4)APICloud Studio3 拉取代码,点击项目,导出云端检出

检出

检出后工作目录
(5)修改或者提交项目源码,并为当前项目云编译自定义 Loader 进行真机同步调试预览。
使用 AppLoader 进行真机同步调试预览,后台自动以loader下载到手机端,安装后,点击小圆圈,输入ip地址:192.168.2.152 端口:10916,连接后真机同步,可以看到刚创建后的结果。



为什么选择AVM?
- 易用:有 Vue、React 基础,可快速上手,配套专用的开发工具APICloud Studio3。
- 多端:一次开发,多端渲染,一个技术栈搞定移动端开发。
- 功能 API 丰富:提供 1千+ 模块和 2万+ API 可直接调用,面向行业和场景无限制)
(1)UI
官方文档:https://docs.apicloud.com/apicloud3/#/component/view?index=4&subIndex=0
原来有一个叫流浪男的做的AUI框架,还不错,后来就是用一些简单的大公司的框架,这个看自己了。好多UI都是自己设计,自己写一些UI。字体图标用的阿里字体图标。CSS框架,要是没啥选择推荐可以用AUI,这个框架有CSS基础的一看就知道写的啥,而且特别好修改。实在不行了直接改源码。
APICloud官网组装了一套vant的,https://docs.apicloud.com/Client-API/AVM-Components/readme.md
(2)ajax网络交互
// 表单方式提交数据或文件
// 表单方式提交数据或文件
api.ajax({
url: 'http://192.168.1.101:3101/upLoad',
method: 'post',
data: {
values: {
name: 'haha'
},
files: {
file: 'fs://a.gif'
}
}
}, function(ret, err) {
if (ret) {
api.alert({ msg: JSON.stringify(ret) });
} else {
api.alert({ msg: JSON.stringify(err) });
}
});
// 提交JSON数据
api.ajax({
url: 'http://192.168.1.101:3101/upLoad',
method: 'post',
headers: {
'Content-Type': 'application/json;charset=utf-8'
},
data: {
body: {
name: 'haha'
}
}
}, function(ret, err) {
if (ret) {
api.alert({ msg: JSON.stringify(ret) });
} else {
api.alert({ msg: JSON.stringify(err) });
}
});
(3)vue指令使用(v-for v-show v-if v-else v-for v-on v-bind v-model等)
1>数据绑定
使用 Mustache 语法:
<text text={{msg}}></text>
使用v-bind指令:
<text v-bind:text="msg"></text>
2>事件绑定
<template>
<text onclick="doThis('avm');">Click me!</text>
</template>
<script>
export default {
name: 'test',
methods: {
doThis(msg){
api.alert({
msg: msg
});
}
}
}
</script>
(4)注册、登录
1>注册接口链接:http://showdoc.deui.cn/web/#/27?page_id=365
注册代码
<template name='tpl'>
<view class="page">
<div class="page1">
<safe-area class="header">
<!-- <text class="header__title">APICloud</text> -->
</safe-area>
<scroll-view class="main">
<view>
<image src="https://baodinglingqian.oss-cn-beijing.aliyuncs.com/1.png" class="touxiang " />
</view>
<div class="zhanghao">
<input placeholder="请输入账号" v-model="zhanghao" maxlength="10" autofocus />
</div>
<div class="mima">
<input type="password" placeholder="请输入密码" v-model="password" />
</div>
<text class="zhuce" @click="reg()">注册</text>
<text class="denglu" @click="handleClick()">登录</text>
</scroll-view>
</div>
<image class="originImage" mode="scaleToFill" src={src}></image>
</view>
</template>
<script>
export default {
name: "tpl",
apiready() {
api.setStatusBarStyle({
style: "light",
color: "-"
});
},
data() {
return {
zhanghao: '',
password: '',
src: "https://baodinglingqian.oss-cn-beijing.aliyuncs.com/bg.png"
};
},
computed: {
},
methods: {
handleClick(e) {
api.openWin({
name: 'main',
url: './main.stml',
pageParam: {
name: 'test'
}
});
},
reg() {
var _this = this;
// 提交JSON数据
api.ajax({
url: 'http://yy.deui.cn/api.php/index/re',
method: 'get',
// headers: {
// 'Content-Type': 'application/json;charset=utf-8'
// },
data: {
body: {
username: _this.zhanghao,
password: _this.password
}
}
}, function (ret, err) {
console.log(JSON.stringify(ret))
if (ret.msg == '返回成功') {
api.toast({
msg: '注册成功',
location: "middle"
});
} else {
api.alert({ msg: JSON.stringify(err) });
}
});
}
}
};
</script>
<style>
.denglu {
margin-top: 10px;
font-size: 14px;
}
.touxiang {
margin-top: 10%;
width: 150px;
height: 150px;
border-radius: 100px;
margin: 0 auto;
}
html {
width: 100%;
height: 100%;
}
body {
width: 100%;
height: 100%;
}
.originImage {
position: absolute;
top: 0px;
left: 0px;
right: 0px;
bottom: 0px;
z-index: 1;
}
.page {
/* position:fixed; */
position: relative;
z-index: 9;
width: 100%;
height: 100%;
}
.page1 {
position: absolute;
top: 0px;
left: 0px;
right: 0px;
bottom: 0px;
z-index: 2;
}
input {
padding-left: 10px;
line-height: 35px;
height: 35px;
border-radius: 5px;
}
.zhanghao {
display: block;
margin: 0 auto;
margin-top: 15%;
margin-bottom: 15px;
height: 60px;
}
.mima {
display: block;
margin: 0 auto;
margin-top: 25px;
}
.zhuce {
width: 100%;
height: 35px;
line-height: 35px;
background-color: coral;
text-align: center;
color: #fff;
margin-top: 25px;
}
.page {
height: 100%;
background-color: white;
}
.header {
background: #81a9c3;
justify-content: center;
align-items: center;
}
.header__title {
color: #fff;
font-size: 18px;
font-weight: bold;
height: 50px;
line-height: 50px;
}
.main {
flex: 1;
padding: 15px;
}
.h1 {
font-size: 24px;
}
.item {
flex-direction: row;
padding: 10px 0;
}
.item__text {
color: #333;
white-space: nowrap;
}
.item__value {
margin-left: 5px;
}
.footer {
background: #81a9c3;
flex-direction: row;
justify-content: center;
align-items: center;
}
.footer__text {
color: #fff;
font-size: 14px;
height: 30px;
line-height: 30px;
}
</style>

2>登录接口链接:http://showdoc.deui.cn/web/#/27?page_id=364
登录代码
<template name='tpl'>
<view class="page">
<div class="page1">
<safe-area class="header">
<!-- <text class="header__title">APICloud</text> -->
</safe-area>
<scroll-view class="main">
<view>
<image src="https://baodinglingqian.oss-cn-beijing.aliyuncs.com/1.png" class="touxiang " />
</view>
<div class="zhanghao">
<input placeholder="请输入账号" v-model="zhanghao" maxlength="10" autofocus />
</div>
<div class="mima">
<input type="password" placeholder="请输入mima" v-model="password" />
</div>
<text class="zhuce" @click="login()">登录</text>
<text class="denglu" @click="handleClick()">注册</text>
</scroll-view>
</div>
<image class="originImage" mode="scaleToFill" src={src}></image>
</view>
</template>
<script>
export default {
name: "tpl",
apiready() {
api.setStatusBarStyle({
style: "light",
color: "-"
});
var value = localStorage.getItem('uid');
api.openWin({
name: 'home',
url: './home.stml'
});
},
data() {
return {
zhanghao: '',
password: '',
src: "https://baodinglingqian.oss-cn-beijing.aliyuncs.com/bg.png"
};
},
computed: {
},
methods: {
handleClick(e) {
api.openWin({
name: 'region',
url: './region.stml',
pageParam: {
name: 'test'
}
});
// api.toast({
// msg: this.data.text,
// location: "middle"
// });
},
login() {
var _this = this;
api.ajax({
url: 'http://yy.deui.cn/api.php/index/login',
method: 'get',
// headers: {
// 'Content-Type': 'application/json;charset=utf-8'
// },
data: {
body: {
username: _this.zhanghao,
password: _this.password
}
}
}, function (ret, err) {
console.log(JSON.stringify(ret))
localStorage.setItem('uid', ret.data.data[0]['id']);
if (ret.msg == '返回成功') {
api.toast({
msg: '登录成功',
location: "middle"
});
api.openWin({
name: 'home',
url: './home.stml'
});
} else {
api.alert({ msg: JSON.stringify(err) });
}
});
}
}
};
</script>
<style>
.denglu {
margin-top: 10px;
font-size: 14px;
}
.touxiang {
margin-top: 10%;
width: 150px;
height: 150px;
border-radius: 100px;
margin: 0 auto;
}
html {
width: 100%;
height: 100%;
}
body {
width: 100%;
height: 100%;
}
.originImage {
position: absolute;
top: 0px;
left: 0px;
right: 0px;
bottom: 0px;
z-index: 1;
}
.page {
/* position:fixed; */
position: relative;
z-index: 9;
width: 100%;
height: 100%;
}
.page1 {
position: absolute;
top: 0px;
left: 0px;
right: 0px;
bottom: 0px;
z-index: 2;
}
input {
padding-left: 10px;
line-height: 35px;
height: 35px;
border-radius: 5px;
}
.zhanghao {
display: block;
margin: 0 auto;
margin-top: 15%;
margin-bottom: 15px;
height: 60px;
}
.mima {
display: block;
margin: 0 auto;
margin-top: 25px;
}
.zhuce {
width: 100%;
height: 35px;
line-height: 35px;
background-color: coral;
text-align: center;
color: #fff;
margin-top: 25px;
}
.page {
height: 100%;
background-color: white;
}
.header {
background: #81a9c3;
justify-content: center;
align-items: center;
}
.header__title {
color: #fff;
font-size: 18px;
font-weight: bold;
height: 50px;
line-height: 50px;
}
.main {
flex: 1;
padding: 15px;
}
.h1 {
font-size: 24px;
}
.item {
flex-direction: row;
padding: 10px 0;
}
.item__text {
color: #333;
white-space: nowrap;
}
.item__value {
margin-left: 5px;
}
.footer {
background: #81a9c3;
flex-direction: row;
justify-content: center;
align-items: center;
}
.footer__text {
color: #fff;
font-size: 14px;
height: 30px;
line-height: 30px;
}
</style>

(5)首页轮播图
轮播图链接:http://showdoc.deui.cn/web/#/27?page_id=366
<template name='tpl'>
<view class="page">
<div class="page1">
<safe-area class="header">
<text class="header__title">首页</text>
</safe-area>
<scroll-view class="main" scroll-y>
<swiper class="swiper" id="customSwiper" autoplay circular indicator-dots indicator-color="#ddd"
indicator-active-color="#f0f">
<swiper-item class="swiper-item" v-for="(_item,_index) in bannerlist">
<!-- <text class="desc">{_item.image}</text> -->
<image mode="scaleToFill" src={_item.image}></image>
</swiper-item>
</swiper>
<div>
<a-cell-group>
<a-cell v-bind:title="_item.name" v-bind:value="_item.content" v-bind:label="_item.address"
arrow-direction="right" @click="godetial(_item)" v-for="(_item,_index) in shangjialist" />
<!-- <a-cell title="单元格" value="内容" label="描述信息" /> -->
</a-cell-group>
</div>
</scroll-view>
</div>
<image class="originImage" mode="scaleToFill" src={src}></image>
</view>
</template>
<script>
import ACellGroup from "../../components/act/a-cell-group";
import ACell from "../../components/act/a-cell";
export default {
name: 'test',
data() {
return {
shangjialist: [],
bannerlist: [],
current: 0,
src: "https://baodinglingqian.oss-cn-beijing.aliyuncs.com/bg.png"
}
},
methods: {
apiready() {
this.banner()
this.allstores()
// var customSwiper = document.getElementById('customSwiper');
// customSwiper.load({
// data: this.data.dataList
// });
},
onchange(e) {
this.data.current = e.detail.current;
},
godetial(item) {
console.log(JSON.stringify(item))
api.openWin({
name: 'detial',
url: './detial.stml',
pageParam: {
id: item.id
}
});
},
banner() {
var _this = this;
api.ajax({
url: 'http://yy.deui.cn/api.php/index/banner',
method: 'get',
}, function (ret, err) {
if (ret.msg == '返回成功') {
_this.data.bannerlist = ret.data.data
// var customSwiper = document.getElementById('customSwiper');
// customSwiper.load({
// data: _this.data.bannerlist
// });
// console.log(JSON.stringify(_this.bannerlist))
} else {
api.alert({ msg: JSON.stringify(err) });
}
});
},
allstores() {
var _this = this;
api.ajax({
url: 'http://yy.deui.cn/api.php/index/stores',
method: 'get',
}, function (ret, err) {
if (ret.msg == '返回成功') {
console.log(1)
console.log(JSON.stringify(ret.data.data))
console.log(1)
var obj = ret.data.data
for (let index = 0; index < obj.length; index++) {
const element = obj[index];
element['content'] = element['content'].substring(0, 9) + '...'
}
console.log(JSON.stringify(obj))
_this.data.shangjialist = obj
} else {
api.alert({ msg: JSON.stringify(err) });
}
});
}
}
}
</script>
<style>
.denglu {
margin-top: 10px;
font-size: 14px;
}
.touxiang {
margin-top: 10%;
width: 150px;
height: 150px;
border-radius: 100px;
margin: 0 auto;
}
html {
width: 100%;
height: 100%;
}
body {
width: 100%;
height: 100%;
}
.originImage {
position: absolute;
top: 0px;
left: 0px;
right: 0px;
bottom: 0px;
z-index: 1;
}
.page {
/* position:fixed; */
position: relative;
z-index: 9;
width: 100%;
height: 100%;
}
.page1 {
position: absolute;
top: 0px;
left: 0px;
right: 0px;
bottom: 0px;
z-index: 2;
}
input {
padding-left: 10px;
line-height: 35px;
height: 35px;
border-radius: 5px;
}
.zhanghao {
display: block;
margin: 0 auto;
margin-top: 15%;
margin-bottom: 15px;
height: 60px;
}
.mima {
display: block;
margin: 0 auto;
margin-top: 25px;
}
.zhuce {
width: 100%;
height: 35px;
line-height: 35px;
background-color: coral;
text-align: center;
color: #fff;
margin-top: 25px;
}
.page {
height: 100%;
background-color: white;
}
.header {
background: #81a9c3;
justify-content: center;
align-items: center;
}
.header__title {
color: #fff;
font-size: 18px;
font-weight: bold;
height: 50px;
line-height: 50px;
}
.main {
flex: 1;
padding: 0px;
}
.h1 {
font-size: 24px;
}
.item {
flex-direction: row;
padding: 10px 0;
}
.item__text {
color: #333;
white-space: nowrap;
}
.item__value {
margin-left: 5px;
}
.footer {
background: #81a9c3;
flex-direction: row;
justify-content: center;
align-items: center;
}
.footer__text {
color: #fff;
font-size: 14px;
height: 30px;
line-height: 30px;
}
.main {
width: 100%;
height: 100%;
}
.swiper {
width: 100%;
height: 190px;
/* background-color: blue; */
}
.swiper-item {
justify-content: center;
}
.title {
padding: 10px 0;
font-size: 20px;
}
.desc {
width: 100%;
text-align: center;
}
.container {
width: 100%;
height: 200px;
}
.indicator {
flex-direction: row;
justify-content: center;
position: absolute;
width: 100%;
height: 20px;
bottom: 8px;
}
.indicator-item {
width: 15px;
height: 8px;
margin: 3px;
}
.indicator-item-normal {
background-color: #ddd;
}
.indicator-item-active {
background-color: red;
}
</style>
(6)首页列表
所有店铺链接:http://showdoc.deui.cn/web/#/27?page_id=369
上面的5的代码里面含有了。
<a-cell-group>
<a-cell v-bind:title="_item.name" v-bind:value="_item.content" v-bind:label="_item.address" arrow-direction="right" @click="godetial(_item)" v-for="(_item,_index) in shangjialist" />
</a-cell-group>
shangjialist: [],
allstores() {
var _this = this;
api.ajax({
url: 'http://yy.deui.cn/api.php/index/stores',
method: 'get',
}, function (ret, err) {
if (ret.msg == '返回成功') {
console.log(1)
console.log(JSON.stringify(ret.data.data))
console.log(1)
var obj = ret.data.data
for (let index = 0; index < obj.length; index++) {
const element = obj[index];
element['content'] = element['content'].substring(0, 9) + '...'
}
console.log(JSON.stringify(obj))
_this.data.shangjialist = obj
} else {
api.alert({ msg: JSON.stringify(err) });
}
});
}

(7)页面传参获取详情
api.openWin({
name: 'detial',
url: './detial.stml',
pageParam: {
id: 123
}
});
apiready() {//like created
if (api.pageParam.id) {
this.data.id = api.pageParam.id
}
console.log(this.data.id)
}
店铺详情:http://showdoc.deui.cn/web/#/27?page_id=370
<template>
<view class="page">
<view>
<a-nav-bar v-bind:title="title" left-text="返回" left-arrow @click-left="onClickLeft"
@click-right="onClickRight" />
</view>
<view>
<a-cell-group>
<a-cell title="名称" v-bind:value="store.name" />
<a-cell title="电话" v-bind:value="store.phone" />
<a-cell title="城市" v-bind:value="store.city" />
<a-cell title="地址" v-bind:value="store.address" />
<a-cell title="内容" v-bind:value="store.content" />
</a-cell-group>
<!-- <text text={{store.name}}></text>
<text text={{store.city}}></text>
<text text={{store.content}}></text>
<text text={{store.address}}></text>
<text text={{store.phone}}></text> -->
</view>
<view>
<a-button type="success">产品</a-button>
</view>
<view>
<a-cell-group>
<a-cell v-bind:title="_item.name" v-bind:value="_item.content" label="点击可预约" v-for="(_item,_index) in product" @click="yuyuproduct(_item)" />
</a-cell-group>
</view>
</view>
</template>
<script>
import ACellGroup from "../../components/act/a-cell-group";
import ACell from "../../components/act/a-cell";
import ANavBar from "../../components/act/a-nav-bar";
import AButton from "../../components/act/a-button";
export default {
name: 'detial',
apiready() {//like created
if (api.pageParam.id) {
this.data.id = api.pageParam.id
}
console.log(this.data.id)
this.init()
},
data() {
return {
title: "详情",
id: 1,
store: {},
product:[]
}
},
methods: {
init() {
var _this = this;
api.ajax({
url: 'http://yy.deui.cn/api.php/index/searchstore',
method: 'get',
data: {
body: {
id: _this.data.id
}
}
}, function (ret, err) {
if (ret.msg == '返回成功') {
console.log(1)
console.log(JSON.stringify(ret.data.product))
console.log(1)
_this.data.store = ret.data.data[0]
_this.data.product = ret.data.product
} else {
api.alert({ msg: JSON.stringify(err) });
}
});
},
yuyuproduct(_item){
console.log(JSON.stringify(_item))
},
onClickLeft() {
api.closeWin();
},
onClickRight() {
}
}
}
</script>
<style>
.page {
height: 100%;
}
</style>
(8)导航栏组件
import ANavBar from "../../components/act/a-nav-bar";
<view>
<a-nav-bar v-bind:title="title" left-text="返回" left-arrow @click-left="onClickLeft"
@click-right="onClickRight" />
</view>
注意:导航栏组件的使用,文档中的引用
import ACell from"../../components/act/a-nav-bar.stml";
使用中建议去掉stml后缀,import ACell from"../../components/act/a-nav-bar";

(9)localStorage 对象使用
main.stml里面的这个,就是用的这个对象
localStorage.setItem('uid', ret.data.data[0]['id']);
下面是localStorage的用法
// 设置存储.
sessionStorage.setItem('key', 'value');
// 获取存储.
var value = sessionStorage.getItem('key');
// 移除存储
sessionStorage.removeItem('key');
// 清除所有存储项
sessionStorage.clear();
// 获取已有存储项数
var length = sessionStorage.length;
// 根据存储项索引获取存储键名
var keyName = sessionStorage.key(index);
(10)APICloud组件、模块的使用
模块中添加模块,如果是H5的需要下载后,放到自己的代码中;如果是原生的模块,需要添加到自己应用中,去require去使用。网上有专门介绍这块的教程,不清楚的可以去搜搜。

这块是自己写的php后台,用的tp5框架。

tp5下的fastadmin框架,可以根据fastadmin一键生成简单后台,数据库文件为:
后台接口代码
<?php
namespace app\api\controller;
use app\common\controller\Api;
use think\Db;
/**
* 首页接口
*/
class Index extends Api
{
protected $noNeedLogin = ['*'];
protected $noNeedRight = ['*'];
/**
* 首页
*
*/
public function index()
{
$this->success('请求成功');
}
//注册
public function re(){
$username = $this->request->request("username");
$password = md5($this->request->request("password"));
$sql = " INSERT INTO `yuyuuser` (`id`, `group_id`, `username`, `nickname`, `password`, `salt`, `email`, `mobile`, `avatar`, `level`, `gender`, `birthday`, `bio`, `money`, `score`, `successions`, `maxsuccessions`, `prevtime`, `logintime`, `loginip`, `loginfailure`, `joinip`, `jointime`, `createtime`, `updatetime`, `token`, `status`, `verification`) VALUES (NULL, '0', '', '".$username ."', '".$password."', '', '', '', '', '0', '0', NULL, '', '0.00', '0', '1', '1', NULL, NULL, '', '0', '', NULL, NULL, NULL, '', '', '')";
$rst = Db::query($sql);
$data =1;
$this->success('返回成功', ['data' => $data]);
}
//登录
public function login(){
$username = $this->request->request("username");
$password = md5($this->request->request("password"));
$sql = "SELECT nickname,id FROM yuyuuser where nickname='".$username."' and password='".$password."' order by id DESC LIMIT 1";
$rst = Db::query($sql);
$this->success('返回成功', ['data' => $rst]);
}
//获取轮播图
public function banner()
{
$sql = "SELECT * FROM `yuyubanner`";
$rst = Db::query($sql);
$this->success('返回成功', ['data' => $rst]);
}
//获取网络协议
public function xieyi()
{
$sql = "SELECT * FROM `yuyuxieyi`";
$rst = Db::query($sql);
$this->success('返回成功', ['data' => $rst]);
}
//所有类型
public function leixing()
{
$sql = " SELECT * FROM `yuyutype`";
$rst = Db::query($sql);
$this->success('返回成功', ['data' => $rst]);
}
//所有店面
public function stores()
{
$sql = " SELECT * FROM `yuyustore`";
$rst = Db::query($sql);
$this->success('返回成功', ['data' => $rst]);
}
//店铺信息
public function searchstore()
{
$id = $this->request->request("id");
$sql = " SELECT * FROM `yuyustore` where id = ".$id;
$sql1 = "SELECT * FROM `yuyuproduct` where store_id = ".$id;
$rst = Db::query($sql);
$rst1 = Db::query($sql1);
$this->success('返回成功', ['data' => $rst,'product'=>$rst1]);
}
}