前言:博主工作后第一个移动端项目,也是博主参考以前的项目瑟瑟发抖从0到1建起来的项目,特此记录一下,过程并不会面面俱到,仅针对本次项目而已。

第一步:vue项目搭建,可参考各大vue项目搭建教程,在这里博主偷懒,直接用了HbuilderX自带的一键创建。

vue3 H5调用android 接口 vue h5ui_ios

 

第二步:项目建立后,先做一些初始化工作,首当其冲是git init,方便管理代码,然后npm下载一些vue常用的包,设置.gitignore文件忽略一些不必往远程仓库上传的文件,如node_modules。

    vue的基本包:vue-router(路由跳转),vuex(自带),axios(用来封装请求)UI库(本次项目是移动端,所以用了vant),sass-loader(用来支持sass)

第三步:基本配置结束后,开始做移动端配置,清空样式,设置移动端样式适配,不许用户放大界面啥啥啥的,此类博客多得是,找找看差不多了。

    这一步,重置全局样式可单独在写一个文件里,然后在main.js里引入,样式配置在public下的index.html书写<meta>标签即可。

第四步:根据设计图划分组件,配置路由,这都是最基础的知识,不提了。

第五步:静态页面画的差不多了,各页面之间跳转关系也做好了,接下来就要做请求配置之类的了。

  五(一):封装axios请求,自行百度axios官网。

  五(二):首先先设置一个过滤器,博主需要对所有请求进行拦截,在请求头里添加用户的token,如下图

                               

vue3 H5调用android 接口 vue h5ui_ios_02

 

  五(三):接下来就可以封装get,post等之类的请求函数了,博主将他们放在Http这个对象里,并对外暴露,到时候请求的时候,只需将Http引入,使用Http.post()函数就可以了。

1 export const Http = {
  2   /**
  3    * get请求
  4    * @param url
  5    * @param param
  6    * @param isLoading
  7    */
  8   get: function (url, param = {}, isLoading = false) {
  9     return new Promise((resolve, reject) => {
 10       if (isLoading) {
 11         var loadingInstance = Loading.service({
 12           text: "拼命加载中"
 13         });
 14       }
 15       axios.get(url, param).then(response => {
 16         if (isLoading) {
 17           loadingInstance.close();
 18         }
 19         var result = response;
 20         if (result.status === 200 || result.status === 201 || result.status === 208) {
 21           resolve(result.data);
 22         } else {
 23             Notify({
 24               message: '系统异常',
 25               type: 'warning'
 26             });
 27           }
 28           reject(result);
 29       }).catch(reason => {
 30         if(reason.response&&reason.response.status === 500){
 31           Notify(reason.toString())
 32           reject(reason);
 33           return
 34         }
 35         if(reason.response&&reason.response.status === 401){
 36           Notify(reason.response.data.message)
 37           reject(reason);
 38           return
 39         }
 40         try {
 41           reject(reason.response.data)
 42         }
 43         catch(e){
 44           Notify(reason.toString())
 45         }
 46       })
 47     })
 48 
 49   },
 50   /**
 51    * post请求
 52    * @param url
 53    * @param param
 54    * @param isLoading
 55    */
 56   post: function (url, param = {}, isLoading = false) {
 57     return new Promise((resolve, reject) => {
 58       if (isLoading) {
 59         var loadingInstance = Loading.service({
 60           text: "拼命加载中"
 61         });
 62       }
 63       axios.post(url, param).then(response => {
 64         if (isLoading) {
 65           loadingInstance.close();
 66         }
 67         var result = response.data;
 68 
 69         if (response.status === 201 || response.status === 200) {
 70           resolve(result);
 71         } else {
 72             Notify({
 73               showClose: true,
 74               message: '系统异常',
 75               type: 'error'
 76             });
 77           reject(result);
 78         }
 79       }).catch(reason => {
 80         console.error(reason);
 81         if (reason.response.status === 401) {
 82           Notify('认证信息失效,请重新登录')
 83           return
 84         }
 85         if(reason.response&&reason.response.status === 500){
 86           Notify(reason.toString())
 87           reject(reason);
 88         }
 89         try {
 90           reject(reason.response.data)
 91         }
 92         catch(e){
 93           Notify(reason.toString())
 94         }
 95       })
 96     })
 97 
 98   },
 99   delete: function name(url, param = {}, isLoading = false) {
100     if (isLoading) {
101       var loadingInstance = Loading.service({
102         text: "拼命加载中"
103       });
104     }
105     return new Promise((resolve, reject) => {
106       axios.delete(url, param)
107         .then(function (response) {
108           if (response.status === 204) {
109             resolve(response.data);
110           } else {
111             reject(response.data);
112           }
113         })
114         .catch(function (reason) {
115           if(reason.response&&reason.response.status === 500){
116             Notify(reason.toString())
117             reject(reason);
118             return
119           }
120           try {
121             reject(reason.response.data)
122           }
123           catch(e){
124             Notify(reason.toString())
125           }
126         });
127     })
128   },
129   put: function name(url, param = '', isLoading = false) {
130     //debugger
131     if (isLoading) {
132       var loadingInstance = Loading.service({
133         text: "拼命加载中"
134       });
135     }
136     return new Promise((resolve, reject) => {
137 
138       axios.put(url, param)
139         .then(function (response) {
140           if (response.status === 204 || response.status === 200) {
141             resolve(response.data)
142           } else {
143             reject(response.data)
144           }
145         })
146         .catch(function (reason) {
147           if(reason.response&&reason.response.status === 500){
148             Notify(reason.toString())
149             reject(reason);
150             return
151           }
152           try {
153             reject(reason.response.data)
154           }
155           catch(e){
156             Notify(reason.toString())
157           }
158         });
159     })
160   },
161   patch: function name(url, param = '', isLoading = false) {
162     //debugger
163     if (isLoading) {
164       var loadingInstance = Loading.service({
165         text: "拼命加载中"
166       });
167     }
168     return new Promise((resolve, reject) => {
169 
170       axios.patch(url, param)
171         .then(function (response) {
172           if (response.status === 201 || response.status === 204||response.status === 200) {
173             resolve(response.data)
174           } else {
175             reject(response.data)
176           }
177         })
178         .catch(function (reason) {
179           if(reason.response&&reason.response.status === 500){
180             Notify(reason.toString())
181             reject(reason);
182             return
183           }
184           try {
185             reject(reason.response.data)
186           }
187           catch(e){
188             Notify(reason.toString())
189           }
190         });
191     })
192   }
193 }
194 
195 export default Http

 

   五(四):请求函数有了,还差接口,封装一个api接口文件,真正请求的时候,Http.请求方式(Api.接口)即可,这时,服务器地址应该也有了,在项目根目录下配置一个.env.development文件,配置服务器地址的全局变量。

       目录如下图:

                                            

vue3 H5调用android 接口 vue h5ui_vue3 H5调用android 接口_03

    在.env.development中书服务器地址的全局变量,变量需大写VUE_APP开头    

                                           

vue3 H5调用android 接口 vue h5ui_vue3 H5调用android 接口_04

 

 

第六步:配置代理

  静态页面和请求函数准备好后,就准备和后端交互了,这时候八成会出现跨域问题。在项目根目录下配置vue.config.js文件,没有的话自己在编辑器创建一个就好,加载项目是会自动载入相关配置。

  下列代码的24行输入自己项目的服务器地址,25行的changeOrigin设置为true,表示允许跨域即可。

1 module.exports = {
 2   
 3   publicPath: "./",
 4   outputDir: "dist",
 5   assetsDir: "static",
 6   lintOnSave: false,
 7   productionSourceMap: false,
 8   devServer: {
 9     port: port,
10     open: true, 
11     overlay: {
12       warnings: false,
13       errors: true
14     },
15     proxy: {
16       [process.env.VUE_APP_BASE_API]: {
17         target: `http://localhost:${port}`,
18         changeOrigin: true,
19         pathRewrite: {
20           ["^" + process.env.VUE_APP_BASE_API]: ""
21         }
22       },
23       "/api": {
24         target: process.env.VUE_APP_API,
25         changeOrigin: true
26       }
27     },
28   },
29   configureWebpack: {
30     name: name,
31     resolve: {
32       alias: {
33         "@": resolve("src")
34       }
35     }
36   },
37 };

第七步 配置vuex

  可以与后端正常交互后,意味着可以用数据渲染页面,开始书写请求接口后的逻辑处理,这时,博主的项目需要用到vuex,有的项目不需要可以跳过这一步。

  七(一):src文件下创建store文件,用来配置vuex,关于vuex的配置博客也很多,可以搜搜看,多看几个模模糊糊就知道大概是什么情况了。

         首先,在store文件里创建一个index.js作为vuex的入口,然后在main.js 引入,即可使用vuex

       store/index.js代码如下图

                         

vue3 H5调用android 接口 vue h5ui_vue3 H5调用android 接口_05

 

      main.js里引入

      

vue3 H5调用android 接口 vue h5ui_vue3 H5调用android 接口_06

 

   七(二):在store里写actions.js、getters.js 、mutations.js文件,分别暴露出actions、getters、mutations,vuex支持模块化,支持每个模块有自己的vuex,博主的项目是第一版,虽然只有一个模块,为了以后好扩展迭代,博主依旧选择了设立了modules文件。

       通过调用actions里的方法,通过mutations改变state里的数据。页面中通过this.$store.dispatch调用actions里的方法,actions里通过commit调用mutations。

       为了方便vuex到底是如何运行的,可以看

第八步:vuex写好后,就是业务逻辑的调试,调试成功后,就要打包发版了。

    开发环境,生产环境和正式环境下,服务器域名不同,需要我们配置不同的全局变量。

    第五步的第四小步中,我们配置了本地的服务器地址变量,在这我们在单独去配置生产环境和正式环境下的就好。

    跟.env.development一样,配置 .env.staging文件用来放测试环境的服务器地址变量和 .env.production来放正式环境的服务器地址。

              

               .env.staging

    

vue3 H5调用android 接口 vue h5ui_服务器_07

 

     .env.production

    

vue3 H5调用android 接口 vue h5ui_vue3 H5调用android 接口_08

最后就是打包部署上线了。