从零开始搭建vue移动端项目

Vue项目搭建

初始化

1.安装node.js
2.使用npm全局安装webpack npm install webpack -g
3.全局安装vue-cli npm install --global vue-cli
4.安装脚手架 npm install --g vue-cli
5.在目标文件夹目录建立项目 vue init webpack myproject(项目目录名称)
6.注意:
    (1)Install vue-router? Yes
    (2)Use ESLint to lint your code? Yes
    (3)Set Up Unit tests No
    (4)Setup e2e tests with Nightwatch? No
    (5)Yes,use NPM
7.搭建目录结构
    build                               webpack项目配置文件
    config                              项目配置目录,运行环境,端口之类的
    dist                                npm run build输出目录
    node_modules                        项目依赖包                     
    src                                 项目主要文件存放目录
        api                             请求模块
            common-api.js               定义公共请求
            home-api.js                 定义模块请求
        apiconfig                       请求封装
            index.js                    
        assets                          项目静态文件存放目录(会通过webpack处理,图片之类的静态资源)
        components                      公共组件
            tabbar.vue                  tabbar底部导航
        pages                           主逻辑组件页面
            home.vue                    主页
        router                          路由配置
            index.js                    
        store                           vuex状态管理
            modules                     各个模块的状态
                home.js                 
            index.js                    统一输出各个模块状态
            mutation-type.js            定义改变状态的方法
        styles                          统同样式
            base.less                   全局css的字体型号
            index.less                  样式统一入口
            mixin.less                  基准字体大小及算法
            reset.less                  重置默认样式
            variable.less               定义主题颜色等基本样式
    App.vue                             统一入口组件
    main.js                             入口js文件
    static                              静态文件存放目录(不会受到webpack的影响,第三方的静态资源库)

路由(vue-router)

1.搭建时已安装router
2.配置router router/index.js
import Vue from 'vue'
   import Router from 'vue-router'
   Vue.use(Router)
   // "@"至关于".."
   export default new Router({
     routes: [{
       path: '/',
       name: 'Home',//首页
       component: (resolve) => require(['@/pages/Home'], resolve)
     }{
       path: '/User',
       name: 'User',//个人
       component: (resolve) => require(['@/pages/User'], resolve)
     }]
   })
3.使用路由跳转
this.$router.push('/Home')
this.$router.go('/Home')
this.$router.replace('/Home')

Vuex(状态管理)

1.安装vuex npm install vuex --save
2.引入vuex main.js
import Vue from 'vue'
    import App from './App'
    import router from './router'
    import Vuex from 'vuex'
    import store from './store'
    Vue.config.productionTip = false
    Vue.use(Vuex)
    /* eslint-disable no-new */
    new Vue({
      el: '#app',
      router,
      store,
      components: { App },
      template: '<App/>'
    })
3.配置使用vuex (暂时省略,后补)

Axios(数据请求模块)

1.安装axios和js-cookie npm install axios js-cookie --save
2.配置axios
    (1)配置请求封装部分 apiconfig/index.js
/* eslint-disable */
    import axios from 'axios'
    /**
     * 定义请求常量
     */
    export const baseUrl = "http://192.168.1.220:8001/api/update.ashx";
    
    // 请求超时时间
    axios.defaults.timeout = 2000;
    
    // 请求拦截
    axios.interceptors.request.use(
        config => {
            // 在发送请求以前作些什么
            return config
        },
        error => {
            // 对请求错误作些什么
            return Promise.reject(error)
        }
    )
    
    // 响应拦截
    axios.interceptors.response.use(
        response  => {
            // 对响应数据作点什么
            let {data} = response;
            if(response.config.url == baseUrl){
                return Promise.resolve(data.result);
            }else if(!data.Result){
                // 服务器错误处理
                return Promise.reject(data.Message);
            }else{
                return Promise.resolve(data.Data);
            }
        },
        error => {
            // 对响应错误作点什么
            return Promise.reject(error)
        }
    )
    
    // 封装post请求
    export function fetch(requestUrl, params = '') {
        return axios({
            url: requestUrl,
            method: 'post',
            data: {
                'body': params
            }
        })
    }
(2)定义模块请求 api/home-api.js
/**
     * 引入fetch
     * @param params
     * @returns {*}
     */
    import {fetch} from 'config/index'
    // 获取UserID
    export function GetUserAndKey(params) {
        return fetch('http://192.168.1.220:8002/api/GetUserAndKey.ashx', params)
    }
(3)在页面使用
import * as homeApi from 'api/home-api'  // 引入api
    export default {
        name: '',
        data() {
            return {
                
            };
        },
        watch: {
            
        },
        methods: {
            getUserAndKey(){
                let params = {
                    "UserID":"",
                    "KeyID": ""
                }
                homeApi.GetUserAndKey(params).then((res) => {
                    console.log(res);
                }).catch(() => {
    
                })
            },
        },
        computed: {
    
        }
    };
(4)在文件里引入fetch方法,能够简写成'config/index',须要作如下配置
    找到build/webpack.base.conf.js文件下resolve.alias添加代码
    resolve: {
        extensions: ['.js', '.vue', '.json'],
        alias: {
            'vue$': 'vue/dist/vue.esm.js',
            '@': resolve('src'),
            'config': resolve('src/apiconfig'),//添加的代码
            'api': resolve('src/api'),//添加的代码
        }
    },
4.跨域问题
在vue-cli里面已经配置了解决跨域问题的模块,
咱们能够在config/index.js里面配置一下要代理的地址,
将以root开头的api转发出去,将地址指向接口地址
// Paths
assetsSubDirectory: 'static',
assetsPublicPath: '/',
proxyTable: {
    '/root/':{target: 'http://xxx'} //添加的代码
},

使用Less

1.安装less和less-loader npm install less less-loader --save-dev
2.配置less 
在build/webpack.base.conf.js 的module.exports.module.rules 里面添加
{
    test: /\.less$/,
    loader: 'style-loader!css-loader!less-loader',
}
3.使用less 
<style scoped lang="less"></style>

移动端适配

1.安装lib-flexible npm i lib-flexible --save
2.引入lib-flexible 
在main.js添加 import 'lib-flexible/flexible'
3.安装px2rem-loader npm install px2rem-loader
4.配置px2rem-loader 
在build文件中找到util.js,将px2rem-loader添加到cssLoaders中,在generateLoaders方法中添加px2remLoader
// 添加的代码
    const px2remLoader = {
        loader: 'px2rem-loader',
        options: {
          remUnit: 75 // 这里设置html根字体,vant-UI的官方根字体大小是37.5
        }
    }
    // generate loader string to be used with extract text plugin
    function generateLoaders (loader, loaderOptions) {
        const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader, px2remLoader]// 添加的代码
        if (loader) {
            loaders.push({
                loader: loader + '-loader',
                options: Object.assign({}, loaderOptions, {
                    sourceMap: options.sourceMap
                })
            })
        }
        // Extract CSS when that option is specified
        // (which is the case during production build)
        if (options.extract) {
            return ExtractTextPlugin.extract({
                use: loaders,
                fallback: 'vue-style-loader'
            })
        } else {
            return ['vue-style-loader'].concat(loaders)
        }
    }
5.注意事项
不用在index.html的头部加name为viewport的meta标签,flexible会自动为咱们添加;
对css中文字样式增长/* px */后缀,会编译出适应不一样dpr的字号;
font-size: 28px; /* px */
对边框样式增长/* no */后缀,会保持原样;
border: 1px solid #fff; /* no */

移动端页面切换动画

移动端通常,第一级菜单切换不须要转场动画,第一级菜单向第二级菜单转场时须要过渡动画
使用vue的transition
1.在 App.vue设置动画
<template>
       <div id="app">
          <transition :name="transitionName">
              <router-view class="Router"></router-view>
          </transition>
      </div>
    </template>
    <script>
        import Vue from 'vue'
        window.Vue = Vue;
        export default {
          name: 'App',
              data() {
                return {
                    transitionName: "fade"
                };
            },
            created:function(){
         
            },
            methods: {
               
            },
            watch: {
                $route() {
                    // 监听路由变化从新赋值
                    if (this.$router.isleft) {
                        this.transitionName = "slideleft";
                    }else if (this.$router.isright) {
                        this.transitionName = "slideright";
                    }else{
                        this.transitionName = "fade";
                    }
                }
            }
        }
    </script>
    <style lang="less">
        @import "./styles/index.less";
        #app {
            -webkit-tap-highlight-color:rgba(0,0,0,0); 
            font-family: "Avenir", Helvetica, Arial, sans-serif;
            -webkit-font-smoothing: antialiased;
            -moz-osx-font-smoothing: grayscale;
            text-align: center;
            color: #2c3e50;
            font-size: 28px;
        }
        .Router {
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            width: 100%;
            height: 100%;
            transition: all 0.5s ease;
            -webkit-transition: all 0.5s ease;
            -moz-transition: all 0.5s ease;
        }
        .fade-enter{
            opacity: 0;
        }
        .fade-leave-active {
            opacity: 0;
        }
        .slideleft-enter,
        .slideright-leave-active {
            opacity: 0;
            -webkit-transform: translate(100%, 0);
            transform: translate(100%, 0);
        }
        .slideleft-leave-active,
        .slideright-enter {
            opacity: 0;
            -webkit-transform: translate(-100%, 0);
            transform: translate(-100%, 0);
        }
    </style>
2.在rounter/index.js 配置路由跳转类
// 须要左方向动画的路由用this.$router.togo('****')
    Router.prototype.togo = function (path) {
        this.isleft = true
        this.isright = false
        this.push(path)
    }
    // 须要右方向动画的路由用this.$router.goRight('****')
    Router.prototype.goRight = function (path) {
      this.isleft = false
        this.isright = true
        this.push(path)
    }
    // 须要返回按钮动画的路由用this.$router.goBack(),返回上一个路由
    Router.prototype.goBack = function () {
      this.isleft = false
        this.isright = true
        this.go(-1)
    }
    // 须要replace使用this.$router.goReplace()
    Router.prototype.goReplace= function () {
      this.isleft = true
        this.isright = false
      router.replace(path)
    }
    // 点击浏览器返回按钮执行,此时不须要路由回退
    Router.prototype.togoback = function () {
      this.isleft = false
        this.isright = true
    }
三、使用方法
this.$router.togo('****') // 进入页面,动画往左
this.$router.goRight('****') // 进入页面,动画往右
this.$router.goReplace('****') // 进入页面不保存当前页面,动画往左
this.$router.goBack('****') // 返回,动画往右
四、监听点击浏览器返回按钮 main.js 添加
window.addEventListener('popstate', function (e) {
  router.togoback()
}, false)

Ui框架

1.选择Vant
2.安装Vant npm i vant -S
3.导入组件 main.js添加
import Vant from 'vant';
import 'vant/lib/index.css';
Vue.use(Vant)
4.使用时还须要引入
import { Dialog } from 'vant';

打包

若是将项目打包用于移动端浏览器,则直接打包上传至服务器,使用nginx作下接口转发便可
若是想将打包的静态文件进一步打包成移动端应用,则须要修改如下config/index.js里build.assetsPublicPath
在config/prod.env.js新增baseUrl

其余

1.ios上点击元素会闪出来一个半透明的灰色框,这里须要在#app的css加一句css兼容
-webkit-tap-highlight-color:rgba(0,0,0,0); 
2.解决点击事件300ms延迟,采用fastclick.js
安装npm install fastclick --save
在main.js 添加
import FastClick from 'fastclick'
FastClick.attach(document.body)
3.开发时配置浏览路径 config/index.js 修改host
如:host: '192.168.1.72', 
4.eslint报错 找到build目录下的webpack.base.conf.js文件,注释掉其中的与有关的eslint规则便可
// ...(config.dev.useEslint ? [createLintingRule()] : []),

安装汇总

npm install vuex axios js-cookie vant fastclick lib-flexible px2rem-loader --save
npm install less less-loader --save-dev
相关文章
相关标签/搜索