成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

基于vue-cli3.0構(gòu)建功能完善的移動(dòng)端架子

Loong_T / 958人閱讀

摘要:對(duì)應(yīng)每一個(gè)環(huán)境可能都會(huì)有所差異,比如說服務(wù)器地址接口地址地址等等。具體的值取決于應(yīng)用運(yùn)行的模式。會(huì)和中的選項(xiàng)相符,即你的應(yīng)用會(huì)部署到的基礎(chǔ)路徑。

基于vue-cli3.0構(gòu)建功能完善的移動(dòng)端架子,主要功能包括

webpack 打包擴(kuò)展

css:sass支持、normalize.css、_mixin.scss、_variables.scss

vw、rem布局

跨域設(shè)置

eslint設(shè)置

cdn引入

路由設(shè)計(jì)、登錄攔截

axios、api 設(shè)計(jì)

vuex狀態(tài)管理

項(xiàng)目地址: vue-cli3-H5

demo地址: https://zhouyupeng.github.io/vuecli3H5/#/

webpack 打包擴(kuò)展

vue-cli3.*后目錄結(jié)構(gòu)大改,去除了以往的build,config文件夾,要實(shí)現(xiàn)配置的改動(dòng)在根目錄下增加vue.config.js進(jìn)行配置

css:sass支持、normalize.css、_mixin.scss、_variables.scss

使用的css預(yù)處理器是sass,對(duì)于css mixin,變量這里做了全局引入,并且引入normalize.css 使HTML元素樣式在跨瀏覽器上表現(xiàn)得的高度一致性
vue.config.js配置

css: {
        // 是否使用css分離插件 ExtractTextPlugin
        extract:isProduction ? true:false,
        // 開啟 CSS source maps?
        sourceMap: false,
        // css預(yù)設(shè)器配置項(xiàng)
        // 啟用 CSS modules for all css / pre-processor files.
        modules: false,
            sass: {
                data: "@import "style/_mixin.scss";@import "style/_variables.scss";" // 全局引入
            }
        }
    }
vw、rem布局

對(duì)于移動(dòng)端適配方案使用的是網(wǎng)易新聞的方法,
使用vw + rem布局

/**
750px設(shè)計(jì)稿
    取1rem=100px為參照,那么html元素的寬度就可以設(shè)置為width: 7.5rem,于是html的font-size=deviceWidth / 7.5
**/
html {
    font-size: 13.33333vw
}

@media screen and (max-width: 320px) {
    html {
        font-size: 42.667PX;
        font-size: 13.33333vw
    }
}

@media screen and (min-width: 321px) and (max-width:360px) {
    html {
        font-size: 48PX;
        font-size: 13.33333vw
    }
}

@media screen and (min-width: 361px) and (max-width:375px) {
    html {
        font-size: 50PX;
        font-size: 13.33333vw
    }
}

@media screen and (min-width: 376px) and (max-width:393px) {
    html {
        font-size: 52.4PX;
        font-size: 13.33333vw
    }
}

@media screen and (min-width: 394px) and (max-width:412px) {
    html {
        font-size: 54.93PX;
        font-size: 13.33333vw
    }
}

@media screen and (min-width: 413px) and (max-width:414px) {
    html {
        font-size: 55.2PX;
        font-size: 13.33333vw
    }
}

@media screen and (min-width: 415px) and (max-width:480px) {
    html {
        font-size: 64PX;
        font-size: 13.33333vw
    }
}

@media screen and (min-width: 481px) and (max-width:540px) {
    html {
        font-size: 72PX;
        font-size: 13.33333vw
    }
}

@media screen and (min-width: 541px) and (max-width:640px) {
    html {
        font-size: 85.33PX;
        font-size: 13.33333vw
    }
}

@media screen and (min-width: 641px) and (max-width:720px) {
    html {
        font-size: 96PX;
        font-size: 13.33333vw
    }
}

@media screen and (min-width: 721px) and (max-width:768px) {
    html {
        font-size: 102.4PX;
        font-size: 13.33333vw
    }
}

@media screen and (min-width: 769px) {
    html {
        font-size: 102.4PX;
        font-size: 13.33333vw
    }
}

@media screen and (min-width: 769px) {
    html {
        font-size: 102.4PX;

        #app {
            margin: 0 auto
        }
    }


}

vue.config.js配置

loaderOptions: {
    postcss: {
        // 這是rem適配的配置
        plugins: [
            require("postcss-px2rem")({
                remUnit: 100
            })
        ]
    }
}
開發(fā)時(shí)跨域設(shè)置
devServer: {
        open: true, // 啟動(dòng)服務(wù)后是否打開瀏覽器
        host: "127.0.0.1",
        port: 8088, // 服務(wù)端口
        https: false,
        hotOnly: false,
        proxy: "https://easy-mock.com/" // 設(shè)置代理
    }

配置完后,本地開發(fā)環(huán)境的axios的baseUrl要寫為 "" ,即空字符串。
發(fā)布到線上時(shí)如果前端代碼不是和后臺(tái)api放在同源下的,后臺(tái)還需做跨域處理,

eslint standard設(shè)置

使用的是JavaScript standard 代碼規(guī)范,一個(gè)好的編碼風(fēng)格它可以幫助減少團(tuán)隊(duì)之間的摩擦,代碼閱讀起來也更加清爽,更加可讀性,不要覺得煩,用了都說好。
這是 JavaScript standard 代碼規(guī)范的全文

自定義配置,在.eslintrc.js里修改,這里是我給出的配置,4個(gè)空格縮進(jìn),不檢查結(jié)尾分號(hào),關(guān)閉單var 聲明,可自行配置

rules: {
    "no-console": process.env.NODE_ENV === "production" ? "error" : "off",
    "no-debugger": process.env.NODE_ENV === "production" ? "error" : "off",
    indent: [
        "error",
        4,
        {
            SwitchCase: 1
        }
    ],
    semi: 0, // 不檢查結(jié)尾分號(hào),
    // 強(qiáng)制使用單引號(hào)
    quotes: ["error", "single"],
    // 關(guān)閉函數(shù)名與后面括號(hào)間必須空格規(guī)則
    "space-before-function-paren": 0,
    // 關(guān)閉var 聲明,每個(gè)聲明占一行規(guī)則。
    "one-var": 0
    }
cdn引入

對(duì)于 vue、vue-router、vuex、axios等等這些不經(jīng)常改動(dòng)的庫、我們讓webpack不對(duì)他們進(jìn)行打包,通過cdn引入,可以減少代碼的大小、也可以減少服務(wù)器的帶寬
這里使用的是360的cdn,附上一份公共cdn評(píng)測(cè)文章 點(diǎn)我

vue.config.js配置

const externals = {
    vue: "Vue",
    "vue-router": "VueRouter",
    vuex: "Vuex",
    "mint-ui": "MINT",
    axios: "axios"

}

const cdn = {
    // 開發(fā)環(huán)境
    dev: {
        css: [
            "https://lib.baomitu.com/mint-ui/2.2.13/style.min.css"
        ],
        js: []
    },
    // 生產(chǎn)環(huán)境
    build: {
        css: [
            "https://lib.baomitu.com/mint-ui/2.2.13/style.min.css"
        ],
        js: [
            "https://lib.baomitu.com/vue/2.6.6/vue.min.js",
            "https://lib.baomitu.com/vue-router/3.0.1/vue-router.min.js",
            "https://lib.baomitu.com/vuex/3.0.1/vuex.min.js",
            "https://lib.baomitu.com/axios/0.18.0/axios.min.js",
            "https://lib.baomitu.com/mint-ui/2.2.13/index.js"
        ]
    }
}

configureWebpack: config => {
        if (isProduction) {
            // externals里的模塊不打包
            Object.assign(config, {
                externals: externals
            })
       
        } else {
            // 為開發(fā)環(huán)境修改配置...
        }
    },
chainWebpack: config => {
    // 對(duì)vue-cli內(nèi)部的 webpack 配置進(jìn)行更細(xì)粒度的修改。
    // 添加CDN參數(shù)到htmlWebpackPlugin配置中, 詳見public/index.html 修改
    config.plugin("html").tap(args => {
        if (process.env.NODE_ENV === "production") {
            args[0].cdn = cdn.build
        }
        if (process.env.NODE_ENV === "development") {
            args[0].cdn = cdn.dev
        }
        return args
    })
}




    
    
    
    
    
    
    
    <% for (var i in
    htmlWebpackPlugin.options.cdn&&htmlWebpackPlugin.options.cdn.css) { %>
    
    
    <% } %>

    vuedemo



    
    
<% for (var i in htmlWebpackPlugin.options.cdn&&htmlWebpackPlugin.options.cdn.js) { %> <% } %>
路由設(shè)計(jì)、登錄攔截
const router = new Router({
    routes: [
        {
            path: "/",
            name: "home",
            component: Home,
            meta: {
                auth: false, // 是否需要登錄
                keepAlive: true // 是否緩存組件
            }
        },
        {
            path: "/about",
            name: "about",
            component: () =>
                import(/* webpackChunkName: "about" */ "./views/About.vue"),
            meta: {
                auth: true,
                keepAlive: true
            }
        },
        {
            path: "/login",
            name: "login",
            component: () =>
                import(/* webpackChunkName: "login" */ "./views/login.vue"),
            meta: {
                auth: false,
                keepAlive: true
            }
        },
        {
            path: "*", // 未匹配到路由時(shí)重定向
            redirect: "/",
            meta: {
                // auth: true,
                // keepAlive: true
            }
        }
    ]
})

// 全局路由鉤子函數(shù) 對(duì)全局有效
router.beforeEach((to, from, next) => {
    let auth = to.meta.auth
    let token = store.getters["login/token"];

    if (auth) { // 需要登錄
        if (token) {
            next()
        } else {
            next({
                path: "/login",
                query: {
                    redirect: to.fullPath
                }
            })
        }
    } else {
        next()
    }
})

在meta中設(shè)置是否需要登錄以及是否緩存當(dāng)前組件,
在router.beforeEac路由鉤子函數(shù)中對(duì)登錄權(quán)限判斷,沒有登錄的跳到登錄頁面,并且把當(dāng)前頁面?zhèn)鬟^去,登錄后跳回這個(gè)頁面。

對(duì)于頁面緩存的在app.vue里進(jìn)行處理


    

axios、api 設(shè)計(jì)

對(duì)于axios的設(shè)計(jì)主要是請(qǐng)求攔截器, respone攔截器,以及get,post的二次封裝

axios.defaults.timeout = 12000 // 請(qǐng)求超時(shí)時(shí)間
axios.defaults.baseURL = process.env.VUE_APP_BASE_API

axios.defaults.headers.post["Content-Type"] =
    "application/x-www-form-urlencoded;charset=UTF-8" // post請(qǐng)求頭的設(shè)置
// axios 請(qǐng)求攔截器
axios.interceptors.request.use(
    config => {
        // 可在此設(shè)置要發(fā)送的token
        let token = store.getters["login/token"];
        token && (config.headers.token = token)
        Indicator.open("數(shù)據(jù)加載中")
        return config
    },
    error => {
        return Promise.error(error)
    }
)
// axios respone攔截器
axios.interceptors.response.use(
    response => {
        // 如果返回的狀態(tài)碼為200,說明接口請(qǐng)求成功,可以正常拿到數(shù)據(jù)
        // 否則的話拋出錯(cuò)誤 結(jié)合自身業(yè)務(wù)和后臺(tái)返回的接口狀態(tài)約定寫respone攔截器
        Indicator.close()
        if (response.status === 200 && response.data.code === 0) {
            return Promise.resolve(response)
        } else {
            Toast({
                message: response.data.msg,
                position: "middle",
                duration: 2000
            });
            return Promise.reject(response)
        }
    },
    error => {
        Indicator.close()
        const responseCode = error.response.status
        switch (responseCode) {
            // 401:未登錄
            case 401:
                break
            // 404請(qǐng)求不存在
            case 404:
                Toast({
                    message: "網(wǎng)絡(luò)請(qǐng)求不存在",
                    position: "middle",
                    duration: 2000
                });
                break
            default:
                Toast({
                    message: error.response.data.message,
                    position: "middle",
                    duration: 2000
                });
        }
        return Promise.reject(error.response)
    }
)
/**
 * 封裝get方法,對(duì)應(yīng)get請(qǐng)求
 * @param {String} url [請(qǐng)求的url地址]
 * @param {Object} params [請(qǐng)求時(shí)攜帶的參數(shù)]
 */
function get (url, params = {}) {
    return new Promise((resolve, reject) => {
        axios
            .get(url, {
                params: params
            })
            .then(res => {
                resolve(res.data)
            })
            .catch(err => {
                reject(err.data)
            })
    })
    // 或者return axios.get();
}
/**
 * post方法,對(duì)應(yīng)post請(qǐng)求
 * @param {String} url [請(qǐng)求的url地址]
 * @param {Object} params [請(qǐng)求時(shí)攜帶的參數(shù)]
 */
function post (url, params) {
    return new Promise((resolve, reject) => {
        axios
            .post(url, qs.stringify(params))
            .then(res => {
                resolve(res.data)
            })
            .catch(err => {
                reject(err.data)
            })
    })
    //  或者return axios.post();
}

為了方便管理api路徑,這里把所以請(qǐng)求都放在了api文件夾下,如

import { get, post } from "@/axios/http.js"
function getIndex (params) {
    return get("/mock/5cb48c7ed491cd741c54456f/base/index", params)
}
function login(params) {
    return post("/mock/5cb48c7ed491cd741c54456f/base/login", params)
}
export {
    getIndex,
    login
}
其他 去除console.log

裝uglifyjs-webpack-plugin插件

 // 上線壓縮去除console等信息
config.plugins.push(
    new UglifyJsPlugin({
        uglifyOptions: {
            compress: {
                warnings: false,
                drop_console: true,
                drop_debugger: false,
                pure_funcs: ["console.log"] // 移除console
            }
        },
        sourceMap: false,
        parallel: true
    })
)
設(shè)置alias目錄別名

在項(xiàng)目中經(jīng)常會(huì)引用各個(gè)地方的文件,配置后可以更加方便的引入了

config.resolve.alias
            .set("assets", "@/assets")
            .set("components", "@/components")
            .set("view", "@/view")
            .set("style", "@/style")
            .set("api", "@/api")
            .set("store", "@/store")
環(huán)境變量和模式

在一個(gè)產(chǎn)品的前端開發(fā)過程中,一般來說會(huì)經(jīng)歷本地開發(fā)、測(cè)試腳本、開發(fā)自測(cè)、測(cè)試環(huán)境、預(yù)上線環(huán)境,然后才能正式的發(fā)布。對(duì)應(yīng)每一個(gè)環(huán)境可能都會(huì)有所差異,比如說服務(wù)器地址、接口地址、websorket地址…… 等等。在各個(gè)環(huán)境切換的時(shí)候,就需要不同的配置參數(shù),所以就可以用環(huán)境變量和模式,來方便我們管理。

.env                # 在所有的環(huán)境中被載入
.env.local          # 在所有的環(huán)境中被載入,但會(huì)被 git 忽略
.env.[mode]         # 只在指定的模式中被載入
.env.[mode].local   # 只在指定的模式中被載入,但會(huì)被 git 忽略

自定義的變量VUE_APP_開頭,兩個(gè)特殊的變量:

NODE_ENV - 會(huì)是 "development"、"production" 或 "test" 中的一個(gè)。具體的值取決于應(yīng)用運(yùn)行的模式。

BASE_URL - 會(huì)和 vue.config.js 中的 baseUrl 選項(xiàng)相符,即你的應(yīng)用會(huì)部署到的基礎(chǔ)路徑。

如我們定義的.env

NODE_ENV = "development"
BASE_URL = "/"
VUE_APP_BASE_API = ""

.env.production

NODE_ENV = "production"
BASE_URL = "./"
VUE_APP_BASE_API = "https://easy-mock.com/"

在項(xiàng)目中可以用process.env.VUE_APP_*,如process.env.VUE_APP_BASE_API獲取到定義的值

全局引入filter

把多個(gè)地方用到的過濾器寫在一個(gè)js里面,復(fù)用代碼。

// 過濾日期格式,傳入時(shí)間戳,根據(jù)參數(shù)返回不同格式
const formatTimer = function(val, hours) {
    if (val) {
        var dateTimer = new Date(val * 1000)
        var y = dateTimer.getFullYear()
        var M = dateTimer.getMonth() + 1
        var d = dateTimer.getDate()
        var h = dateTimer.getHours()
        var m = dateTimer.getMinutes()
        M = M >= 10 ? M : "0" + M
        d = d >= 10 ? d : "0" + d
        h = h >= 10 ? h : "0" + h
        m = m >= 10 ? m : "0" + m
        if (hours) {
            return y + "-" + M + "-" + d + " " + h + ":" + m
        } else {
            return y + "-" + M + "-" + d
        }
    }
}
export default {
    formatTimer
}

main.js引入

import filters from "./filters/index"
// 注入全局過濾器
Object.keys(filters).forEach(item => {
    Vue.filter(item, filters[item])
})

使用

{{1555851774 | formatTimer()}}
vue中使用mock.js

查看我以前寫的文章點(diǎn)擊我

wepback的可視化資源分析工具插件---webpack-bundle-analyzer

用來分析哪些模塊引入了哪些代碼,進(jìn)行有目的性的優(yōu)化代碼

在打包環(huán)境中加,使用命令npm run build --report

if (process.env.npm_config_report) {
    config.plugins.push(new BundleAnalyzerPlugin())
}

代碼地址
項(xiàng)目地址: vue-cli3-H5

demo地址: https://zhouyupeng.github.io/vuecli3H5/#/

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/103791.html

相關(guān)文章

  • 基于vue-cli3.0項(xiàng)目工程重新構(gòu)建空白版,拿來即用

    摘要:寫在前面使用框架開發(fā)時(shí),很多人會(huì)選擇官方提供的腳手架,最新的已經(jīng)更新到完全無配置,只需下載就能方便的使用構(gòu)建的項(xiàng)目工程,但基礎(chǔ)的并不能滿足正常的項(xiàng)目開發(fā),在開發(fā)中我們需要根據(jù)自己的習(xí)慣和業(yè)務(wù)功能而添加些基礎(chǔ)功能。 寫在前面 使用vue框架開發(fā)時(shí),很多人會(huì)選擇vue官方提供的cli腳手架,最新的cli已經(jīng)更新到3.0完全無配置,只需下載就能方便的使用vuecli構(gòu)建的項(xiàng)目工程,但基礎(chǔ)的c...

    xingpingz 評(píng)論0 收藏0
  • 關(guān)于Vue2一些值得推薦文章 -- 五、六月份

    摘要:五六月份推薦集合查看最新的請(qǐng)點(diǎn)擊集前端最近很火的框架資源定時(shí)更新,歡迎一下。蘇幕遮燎沈香宋周邦彥燎沈香,消溽暑。鳥雀呼晴,侵曉窺檐語。葉上初陽乾宿雨,水面清圓,一一風(fēng)荷舉。家住吳門,久作長(zhǎng)安旅。五月漁郎相憶否。小楫輕舟,夢(mèng)入芙蓉浦。 五、六月份推薦集合 查看github最新的Vue weekly;請(qǐng)::點(diǎn)擊::集web前端最近很火的vue2框架資源;定時(shí)更新,歡迎 Star 一下。 蘇...

    sutaking 評(píng)論0 收藏0
  • 關(guān)于Vue2一些值得推薦文章 -- 五、六月份

    摘要:五六月份推薦集合查看最新的請(qǐng)點(diǎn)擊集前端最近很火的框架資源定時(shí)更新,歡迎一下。蘇幕遮燎沈香宋周邦彥燎沈香,消溽暑。鳥雀呼晴,侵曉窺檐語。葉上初陽乾宿雨,水面清圓,一一風(fēng)荷舉。家住吳門,久作長(zhǎng)安旅。五月漁郎相憶否。小楫輕舟,夢(mèng)入芙蓉浦。 五、六月份推薦集合 查看github最新的Vue weekly;請(qǐng)::點(diǎn)擊::集web前端最近很火的vue2框架資源;定時(shí)更新,歡迎 Star 一下。 蘇...

    khs1994 評(píng)論0 收藏0
  • 基于vue + element uitable編輯,保存和刪除

    摘要:在最近年的工作中遇到過幾次很基礎(chǔ)的基于的開發(fā)簡(jiǎn)單的增刪改查功能閑下來想整理一下以備后用架子用最新的此處可以參考我之前的最好的系列環(huán)境搭建篇項(xiàng)目基礎(chǔ)構(gòu)建好以后這個(gè)小我們暫且將數(shù)據(jù)存在之后我將更新基于前端操作數(shù)據(jù)庫的操作點(diǎn)擊新增按鈕點(diǎn)擊保存 在最近2年的工作中遇到過幾次很基礎(chǔ)的基于element-ui的table開發(fā),簡(jiǎn)單的增刪改查功能,閑下來想整理一下~ 以備后用 vue架子,用最新的...

    frontoldman 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<