前端框架(混合开发框架)

前端框架

基于vue+vuex+vue-router+axios等框架整合的移动端框架.基于此框架可以实现android和ios的同时开发.

  1. 前端采用hbuilder提供的mui框架,并整合了mint-ui+iview等第三方框架
  2. app打包使用hbuilder提供的功能进行原生打包
  3. 采用vue-router实现单页路由和路由之间的相互跳转
  4. 使用.vue文件进行页面的编程开发
  5. 使用webpack实现打包,压缩,混淆,预处理,热加载。

环境安装

  • 下载hbuilder最新版本开发工具其实HBuilder是dcloud 把eclipse的改造成一个专门应用于app打包、多种语言支持:php、jsp、ruby、python、nodejs等web语言,less、coffee等编译型语言均支持的开发工具
  • hbuilder 安装svn插件
    image
    image
  • 下载node.js作为前端web的运行环境。我当前的node.js版本是8.11.1 npm版本5.6.0,安装完node后记得安装cnpm
npm install -g cnpm --registry=https://registry.npm.taobao.org
  • app打包完全是基于manifest.json配置文件,它主要是用来配置app的基本信息(版本号、appid等)、图标(app的应用图标)、sdk配置、模块权限配置、页面引用关系、代码视图,具体参看dcloud提供的文档.
  • 以总量APP作为框架演示,svn地址:https://192.168.106.21/svn/mobile/total/total

模块安装

#进入对应项目的目录
cd 对应目录
#安装依赖组件
cnpm install
# 启动服务
npm run dev
# 打包
npm run build

项目目录说明

|-- build                               // webapck打包后的文件目录
|-- src                                 // 源码目录
|   |-- components                      // 存放公共组件的目录
|       |-- comFooter.vue               // 底部组件
        |-- header.vue                  // 头部组件
|       |-- ...                         // 其他公共组件
    |-- config                          // webpack配置以及app的相关信息
|   |-- css                             // 存放各种css文件目录
|       |-- app.css                     // app的公用样式文件 
|       |-- mui.css                     // mui框架css
|       |-- ...                         // 其他css
|   |-- fonts                           // 存放各种fonts文件目录
|       |-- ...                         // 其他fonts文件
|   |-- image                           // 存放各种图片文件目录
|       |-- company                     // 按照业务存放图片
        |-- ...                         // 其他业务图片
|   |-- js                              // 存放各种js文件目录
        |-- 存放通用的js文件
|   |-- less                                // 存放各种less文件的目录
|   |-- page                                // 按模块和功能存放.vue页面文件
|           |-- guide                       // 引导页面
|           |-- app.vue                     // app页面入口文件
|           |-- login.vue                   //登录页面
|           |...                            //其他业务页面
|   |-- plugins                         // 第三方插件文件
    |-- router                          // 路由配置文件(按照模块区分)
    |-- service                         // api接口配置service层
    |-- store                           // vue状态管理器
|   |-- index.html                      // app的html模板页面
|-- unpackage                           // app编译包目录
|-- .gitignore                          // git忽略文件
|-- index.html                          // webapp的首页加载文件
|-- manifest.json                       // 打包app的配置文件
|-- package.json                        // 配置项目相关信息,通过执行 npm init 命令创建
|-- webpack.config.js                   // webpack配置文件

框架核心逻辑

  • package.json

    申明app的基本信息,创建npm的一些指令用于热部署以及热发布,申明项目中的所使用的依赖库,需要安装对应的依赖可以使用cnpm install –save(对应保存到dependencies)或者cnpm install –save-dev(对应保存到devDependencies) 对应的npm包名来安装依赖js

    devDependencies 里面的插件只用于开发环境,不用于生产环境
    dependencies 是需要发布到生产环境的。

  • main.js
    webpack预编译的入口文件,该文件定义了全局需要引用的js文件和插件,并定义一些全局需要调用的方法.
  • app.vue
    入口文件,定义app框架
  • 重要实例
    app.mui(mui的实例对象)

app.vueApp(vue实例对象)

this.$store(vuex实例对象)

this.$router(vue-router实例对象)

  • http.js
    使用axios框架定义了http的请求变量和请求地址,用来获取远程接口,发布真是版本和发布测试版本需要修改这边的参数
import axios from "axios"
import Qs from 'qs'
var http,chttp; //http请求
var isDebug = true; //调试模式
/******URL配置开始******/
//var mockUrl='http://localhost:9999/mockjs/'
//var mockUrl='http://192.168.10.204:9999/mockjs/'
//var mockUrl = 'http://rapapi.org/mockjs/'; //二者只能选其一
//var realUrl ='http://127.0.0.1:8080/huihuan-yunwei/';//二者只能选其一
var mockUrl=null;
//var realUrl = 'http://127.0.0.1';//徐冬益


//var realUrl = 'http://192.168.10.215:8080';//朱鹏程
// var realUrl = 'http://192.168.10.23:8080';//测试
//var realUrl = 'http://58.221.137.131:28080';//测试外网
var realUrl = 'http://192.168.100.168:9090';//shi
//var realUrl = 'http://192.168.10.102';//姜文峰

//var realUrl = 'http://192.168.10.208:9090';//shi
//var realUrl = 'http://192.168.10.215';//朱鹏程


//var realUrl = 'http://192.168.10.215';//真实地址
var imgPath = "http://192.168.10.23:8080/mobile/"
/******URL配置开始******/
if(mockUrl!=null) {
    //初始化rap插件
    rapglobalproxy.doProxy({
        url: mockUrl, //rap地址
        projectId: projectId //项目ID
    });
    http = axios.create({
        baseURL: '',
    });
} else {
    //正式环境下调用
    http = axios.create({
        baseURL: realUrl+"/online/",
        transformRequest: [function (data) {
            data = Qs.stringify(data);
            return data;
        }],
    });
    chttp = axios.create({
        baseURL: realUrl+"/center/",
        transformRequest: [function (data) {
            data = Qs.stringify(data);
            return data;
        }],
    });
}


//添加请求拦截器
initInterceptors(http);
initInterceptors(chttp);
//初始化拦截器
function initInterceptors(instance) {
    instance.interceptors.request.use(function(config) {
        //在发送请求之前做某事
        if(config.data) {
            if(isDebug) {
                console.log("请求参数:", config.data)
            }
        }
        return config;
    }, function(error) {
        //请求错误时做些事
        console.log("请求发生异常!", error);
        return Promise.reject(error);
    });


    //添加响应拦截器
    instance.interceptors.response.use(function(response) {


        //对响应数据做些事
        if(response) {
            var status = response.status;
            if(status === 200 || status === 304) {
                if(isDebug) {
                    console.log("请求url:" + response.config.url)
                    console.log("返回结果:", response.data)
                }
                return response.data;
            } else if(status == 500) {
                alert("服务器内部错误!")
            } else {
                console.log("response结果:", response)
            }
            return response;
        }
    }, function(error) {
        //请求错误时做些事
        if(!isEmptyObject(error)) {
            console.log("发生异常:", error)
        }
        return Promise.reject(error);
    });
}


function isEmptyObject(e) {
    var t;
    for(t in e)
        return !1;
    return !0
}
 exports.chttp=chttp;
 exports.http=http;
 exports.imgPath=imgPath;
 exports.appConfig = {
    realUrl:realUrl,
    imgPath:imgPath
 }

发布

  • run build 使用webpack打包生成混淆后的html,js,css
    image
  • 配置manifest.json image
  • 云打包image

组件化开发

  • header.vue 定义app通用头部组件
<template>
  <div>
    <header id="header" class="mui-bar mui-bar-nav">
      <!-- <a v-show="showBack" class="mui-action-back mui-icon mui-icon-left-nav mui-pull-left"></a> -->
      <a v-show="showBack" class="mui-icon mui-icon-left-nav mui-pull-left" @click="goback"></a>
      <h1 class="mui-title" :class="{'hasRightBtn':showBtn}">{{titleName}}</h1>
      <button @click="btnevent" v-show="showBtn" class="mui-btn mui-btn-outlined mui-pull-right hh-header-btn">
        {{btnName}}
      </button>
      <img @click="imgevent" src="" alt="" v-show="showImg">
    </header>
  </div>
</template>


<script>
import "../css/mui.css";
import "../css/app.css";
export default {
  data() {
    return {};
  },
  props: {
    titleName: {
      //标题
      type: String
    },
    showBack: {
      //是否显示返回按钮
      type: Boolean,
      default: false
    },
    useSelfBack: {
      //是否显示返回按钮
      type: Boolean,
      default: false
    },
    showBtn: {
      //是否显示右侧按钮
      type: Boolean,
      default: false
    },
    showImg: {
      //是否显示右侧
      type: Boolean,
      default: false
    },
    btnName: {
      //右侧按钮名称
      type: String
    }
  },
  methods: {
    btnevent() {
      this.$emit("btnevent");
    },
    imgevent() {
      this.$emit("imgevent");
    },
    goback() {
        if(this.useSelfBack){
            this.$emit("goback");
        }else{
            this.$store.dispatch("backHistory");
            window.history.go(-1);
        }

    }
  }
};
</script>


<style scoped>
.mui-btn {
  margin: 0;
  padding: 0 5px;
  height: 20px;
  line-height: 20px;
  font-size: 12px;
  color: white;
  border: 1px solid white;
  margin-top: 12px;
  border-radius: 10px;
}
.hasRightBtn {
  right: 80px !important;
}
img {
  float: right;
  width: 15px;
  height: 15px;
  margin-top: 15px;
}
</style>

参考文档

阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页