Vue.js 资料工作总结Vue.js专区

vue 项目总结 pc端 stepOne

2019-01-25  本文已影响6人  轩轩小王子

首先需要说明的是,我用的是 vue 2.x的语法,vuea-cli 用的是3.x

1.用vue-cli 3.x 构建项目

首先你需要下载node (Vue CLI requiresNode.jsversion 8.9 or above (8.11.0+ recommended) 我想这句话就不用翻译了,大家应该都看的懂)

npm install -g @vue/cli (下载3.x脚手架)

vue --version (查看当前版本)

vue create hello-world (创建一个名字为hello-world的vue项目)

更多问题请参考官网:https://cli.vuejs.org/guide/installation.html

2.vue-cli 2.x 与 3.x 的区别

其实我觉得最大的区别就是,3.x 需要自己手动去写一些配置文件,比如跟src 同级的vue.config.js(主要是做些打包输出路径的配置及下载的一些plugins 的配置 和 是否开启eslint保存检测  ) 而这个 vue.config.js 打包的时候是必须要有的 ,不然后台发布到线上会或由于路径问题找不到一些文件

更多问题请参考官网 :https://cli.vuejs.org/zh/config/#lintonsave

mock数据:

2.x: config---->index.js 

proxyTable: {

      '/api':{

        target:"http://localhost:8081",

        pathRewrite:{

          '^/api':'/static/mock'

        }

      }

    },

然后在mock 文件夹下 建一些json 文件夹 就可以了

3.x: JSON Server

npm install -g json-server (先下载相应依赖)

建一个 db.json (跟src 平级)

然后 npm run json:server 就可以开始mock数据了

更多可以参考:https://github.com/typicode/json-server

3.api 路径的动态配置

const environment = "dev"; //需要根据环境进行修改  “dev”、“preview”、“prod”

export default {

    getHost() { //这是后台api 路径

        switch (environment) {

            case "dev": //开发

                return "xxx";

            case "preview": //预发布

                return "xxx";

            case "prod": //正式

                return "xxx";

        }

    },

    getHref(){ //这是网页线上地址

        switch (environment) {

            case "dev": //开发

            return "xxxx"

            case "preview": //预发布

            return "xxx"

            case "prod": //正式

            return"xxx"

        }

    },

    isDev:false, // 是否为开发版

    getEnvironment(){

        return environment

    }

}

4.网络请求的封装

1.npm install axios(必须下载)

2.npm install qs(用途:1.将对象序列化,多个对象之间用&拼(qs.stringify(params)) 2.将序列化的内容拆分成一个个单一的对象(qs.parse(params))

3. api.js  

axios.defaults.baseURL = getHost.getHost() + "/api"; //动态配置网络请求不同环境下的地址

<pre>

//封装获取数据

export function get(url, params = {}, context) { //context vue 实例

    return new Promise((resolve, reject) => {

        url += "?";

let keys = Object.keys(params); //处理对象,返回可枚举的属性数组

        console.log('keys',keys)

        for (let i = 0, length = keys.length; i < length; i++) {

            if (i === 0) {

                url += keys[i] + "=";

                url += params[keys[i]];

            } else {

                url += "&" + keys[i] + "=";

                url += params[keys[i]];

            }

        }

        console.log('url',url)

        if(userToken){

            url += '&userToken='+ userToken;

        }

        url += "&timestamp="+new Date().getTime(); //加了个时间戳

        url = encodeURI(url);//对url 进行编码

        axios.get(url).then(res => {

            if (res.status === 200) { //http 请求成功

                if (res.data.code === 1000) { //公司内部定义的 code 数据正常返回

                    resolve(res.data.result);

                }else if(res.data.code === 2999){  //请求成功,但数据返回异常

                    xxx //具体不同公司不同code

                    } else {

                                                xxxxx

                    }

                } else {

                    let msgContent = res.data.msgContent;

                    if (!isEmpty(msgContent) && context) {

                        context.$toast(msgContent); 

                    }

                    reject({

                        errorMsg: msgContent,

                        detail: res.data

                    });

                }

            } else {

                reject({

                    errorMsg: res.statusText

                })

            }

        }).catch(err => {

            reject(err)

        })

    })

}

//封装发送数据

export function post(url, params = {}, context) {

    if(userToken){

        Object.assign(params,{userToken:userToken}); //合并两个对象

    }

    return new Promise((resolve, reject) => {

        axios.post(url, qs.stringify(params)).then(res => { //序列化字符串

            if (res.status === 200) { 

                if (res.data.code === 1000) { 

                    resolve(res.data.result);

                } else if(res.data.code === 2999){

                    if (getHost.isDev) {

                    xxxxxx

                    } else {

                     xxxxxx

                    }

                } else {

                    let msgContent = res.data.msgContent;

                    if (!isEmpty(msgContent) && context) {

                        context.$toast(msgContent);

                    }

                    reject(res.data.result);

                }

            } else {

                reject({

                    errorMsg: res.statusText

                })

            }

        }).catch(err => {

            reject(err)

        })

    })

}

//封装上传文件、图片

export function uploadFile(url, params = {}, context) {

    if(userToken){

        Object.assign(params,{userToken:userToken});

    }

    return new Promise((resolve, reject) => {

        let formData = new FormData(); //  不支持ie8,ie9  formData里面存储的数据是以健值对的形式存在的

        let keys = Object.keys(params);

        for (let i = 0, length = keys.length; i < length; i++) {

            formData.append(keys[i], params[keys[i]]);

        }

        let config = {

            headers: {

                'Content-Type': 'multipart/form-data' //此处需要添加这个headers

            }

        };

        axios.post(url, formData, config).then(res => {

            if (res.status === 200) {

                if (res.data.code === 1000) {

                    resolve(res.data.result);

                } else if(res.data.code === 2999){

                    if (getHost.isDev) {

                        xxxxx

                    } else {

                        xxxxxx

                    }

                } else {

                    let msgContent = res.data.msgContent;

                    if (!isEmpty(msgContent) && context) {

                        context.$toast(msgContent);

                    }

                    reject(res.data.result);

                }

            } else {

                reject({

                    errorMsg: res.statusText

                })

            }

        }).catch(err => {

            reject(err)

        })

    })

}

main.js

import {get,post,uploadFile} from '../../common/js/api.js'

Vue.prototype.$get = get;

Vue.prototype.$post = post;

Vue.prototype.$uploadFile = uploadFile;

xxx.vue 调用:

this.$post(url,codeLoginObj,this).then((response)=>{

   })</pre>

5.vue-cli 3.x多页面配置

1.需要在vue.config.js里面进行配置:

<code>

const webpack = require('webpack')

module.exports = {

    pages:{

        index:{

            entry:'./src/login/login.js', //page 入口文件

            template:'public/index.html', //模版来源

            filename:'index.html' //打包好的文件名称

        },

        views:{

            entry:'./src/views/main.js',

            template:'public/index.html',

            filename:'view.html'

        },

    }

}

</code>

6.vue-cli 3.x 中使用jquery

1.npm install jquery --save

2.在vue.config.js 里面配置:

<code>

const webpack = require('webpack')

module.exports = {

    configureWebpack: {

       plugins: [

          new webpack.ProvidePlugin({

            $:"jquery",

            jQuery:"jquery",

            "windows.jQuery":"jquery"

          })

        ]

    }

}

3、一般安装成功后在package.json文件内的dependencies项中会有"jquery": "^1.12.4"(jquery的版本不同人下载可能会有差异)然后才里面找到此处:

找到env ,在里面 添加 jquery:true

4、在main.js中添加“import $ from 'jquery”

然后你就可以用jquery了(不过建议最好不要用,毕竟他们两个的设计理念不同)

7.结合elment-ui做一些表单验证

<code>

//1.validate.js 

//验证手机号码

export function isvalidPhone(str) { //方法封装

  const reg = /^1[3-9][0-9]{9}$/;

  return reg.test(str)

}

......

import {isvalidPhone} from '../../../../common/js/validate.js' //方法调用

data(){

            var mobile=(rule,value,callback)=>{ //validator: mobile 对应的方法

                if(!isvalidPhone(value)){

                    callback(new Error('手机号格式有误'))

                }else{

                    callback()

                }

            }

            return{

                bindMobileForm:{

                    mobile:'',

                    code:''

                },

                 Rules:{

                    "mobile":[

                        { required:true,message:"手机号不能为空",trigger:"blur"},

                        { required: true, trigger:'blur',validator: mobile}

                    ],

                    "code":[

                        { required:true,message:"验证码不能为空",trigger:"blur"},

                    ]

                }

            }

        }

<el-form :model="bindMobileForm" ref="bindMobileForm" :rules="Rules" key="code"> </el-form>

this.$refs[bindMobileForm].validate((valid) => {

                    if (valid) {

                        //表单验证通过

                    } 

                });

</code>

8.样式穿透 

1.<style scoped src="../../../../common/css/form.css"></style> //引入别的css

2.由于项目中使用了element-ui 有些样式死活覆盖不了,就用了

<style scoped>

    .el-form-item >>>.el-form-item__error{

        margin-left: 120px;

    }

</style>

9. data里面引入图片

data(){

            return {

logoImage:require('../../assets/image/logo_white.png')

            }

        }

10.页面跳转

1. <router-link :to="{name:'loginLink'}">登录</router-link></span>

2. this.$router.push('/loginIndex');

3.this.$router.go(-1); //返回上一页

11.pc端点击 enter 键登录

<el-form-item prop="accountName">

                                <el-input type="text" v-model.trim="accountForm.accountName" autocomplete="off" placeholder="请输入账号" clearable class="mobile"></el-input>

                            </el-form-item>

                            <el-form-item  prop="password">

@keyup.enter.native="submitAccountForm('accountForm')">

                            </el-form-item>

submitAccountForm(accountForm) {

                this.$refs[accountForm].validate((valid) => {

                    if (valid) {

                    } 

                });

            },

11.路由重定向问题

router---> index.js

{

            path: '/views',

 beforeEnter(to, from, next) {

                if (config.isDev) {

                    window.location = '/view.html'

                } else {

                              window.location = '/h5/saas/index.html'

                }

            }

        }

12.vuex

store.js:

import Vue from 'vue'

import Vuex from 'vuex'

Vue.use(Vuex);

export const store = new Vuex.Store({

    state:{

        userId:''

    },

    getters:{

        isLogin(state){

            if (!state.userId) {     //防止刷新页面获取不到

                state.userId=sessionStorage.getItem('userId');

            } 

            return state.userId

        }

    },

    mutations:{ 

        removeUserId(state,payload){ //更新 state 方法

            sessionStorage.removeItem("userId"); 

            state.userId = ''

        }

    }

})

调用:computed:{

        companyInfo(){

 return this.$store.state.enterpriseInfo

 return this.$store.getters.getWelfareTotalNumber //这个地方取得是getters 刷新页面中也会有

        }

    },

主动更新:

this.$store.commit("authentEnterPrise",{companyData:companyObj});

13.判断是否需要登录

login.js

router.beforeEach((to, from, next) => {

  /* 判断该路由是否需要登录权限 */

    if(to.matched.some(record => record.meta.requiresAuth)){

        //是否登录

        if(!sessionStorage.getItem('userId')){

            next({

                path: '/loginIndex',

                query: { redirect: to.fullPath }

            })

        }else{

             next()

        }

    }else{

        next();

    }

})

views router.js

routes: [

        {

            path: '*',

            redirect:'/views',

            meta: {

                keepAlive: true,

 requiresAuth: true

            }

        }

]

14.data里面的数据

data(){

        return{

            userId:sessionStorage.getItem('userId') //可以直接取缓存

        }

    }

15.组件间数据传递

1.子组件通知父组件

子组件内

this.$emit('resetInputValue', this.searchCondition);

父组件

<my-filter-form  @resetInputValue="onReset"></my-filter-form>

2.父组件向子组件 传参数

<my-page :totalPage="tableList.length" v-show="tableList.length >= 10" :pageSize="selectedListOnePageSize" ></my-page>

16.element-ui date-picker、el-dropdown

<div class="input-box f-left birthday-picker-box">

            <span>生日</span>

            <el-date-picker

                    v-model="birthdayStart"

                    name="birthdayStart"

                    format="MM-dd"

                    value-format="timestamp"

                    type="date"

                    placeholder=""

                    :editable="inputEditable"

                    :picker-options="pickerBirthdayBefore"

            >

            </el-date-picker>

            <div class="line f-left">-</div>

        </div>

<el-dropdown trigger="click" @command="handleCommand">

                            <span class="el-dropdown-link btn send time-send small-hand" id="custom-sebd-btn"  :class="{active:customActive}">

                                {{custom}}

                            </span>

                            <el-dropdown-menu slot="dropdown">

                                <el-dropdown-item :command="commandOne">生日当天发送</el-dropdown-item>

                                <el-dropdown-item :command="commandTwo">生日前一天发送</el-dropdown-item>

                                <el-dropdown-item :command="commandThr">生日前一星期发送</el-dropdown-item>

                            </el-dropdown-menu>

                        </el-dropdown>

data() {

      return {

        pickerBirthdayBefore: { 

          //disabledDate通常是一个函数,

          disabledDate: time => { // time.getTime() >= beginDateVal false 可用,true 不可用

            let beginDateVal = this.birthdayEnd;

            if (beginDateVal) {

              return time.getTime() >= beginDateVal;  //开始时间小于结束时间

               return time.getTime() <= beginDateVal || time.getTime() > Date.now(); //结束时间大于开始时间且小于当前时间

                return time.getTime() >= Date.now()-8.64e7 //今天及以后的日期都不能选

            }

          }

        },

//自定义时间 发送 下拉

        handleCommand(command){

            this.custom = command.desc;

        },

17.vue中使用动画 animate.css

1.npm install animate.css --save

2.import animate from 'animate.css'

3.<transition enter-active-class="animated fadeIn" leave-active-class="animated fadeOut"></transition>

18.    邮箱 部分用*代替

        encryptedmailbox(email) {

          if (String(email).indexOf('@') > 0) {

               var str = email.split('@');

               var  _s = '';

                var new_email = "";

            if (str[0].length > 3) { //@前面多于3位

              for (var i = 3; i < str[0].length; i++) {

                _s += '*';

              }

                new_email= str[0].substr(0, 3) + _s + '@' + str[1];

            }else{ //@前面小于等于于3位

                for(var i = 1;i<str[0].length;i++){

                    _s+='*'

                }

                new_email = str[0].substr(0,1)+ _s + '@' + str[1]

            }

          }

          return new_email;

        }

19.三目运算符 双层if 判断:

{{item.errorField == 1 ? item.email== "" ? '邮箱为空' :"格式不正确" : item.email}}

20.动态绑定 class

:class="{'emailError':item.errorField == 1}" //emailError  class 名称


上一篇 下一篇

猜你喜欢

热点阅读