本項目是基于Vue-Cli3腳手架,應(yīng)用VW的自適應(yīng)解決方案構(gòu)建的移動端企業(yè)級工程項目,下面會一步步構(gòu)建起項目結(jié)構(gòu)。大家也可以先下載源代碼下來看下,再跟著操作。Author: Gavin
項目地址:https://github.com/PowerDos/v...
下面是一張自適應(yīng)效果git圖,比較大,需要耐心等待才能看到,或者直接下載圖片查看效果[https://i.loli.net/2019/12/03...]
這里展示的是最終的目錄結(jié)構(gòu),方便查看,后面會一步步說明并搭建此目錄
.├── README.md├── babel.config.js├── package-lock.json├── package.json├── public│ └── index.html├── src│ ├── App.vue│ ├── api│ │ └── homeApi.js│ ├── assets│ │ ├── img│ │ │ └── head.png│ │ └── scss│ │ └── global.scss│ ├── components│ │ └── Footer.vue│ ├── main.js│ ├── page│ │ └── Home.vue│ ├── router│ │ └── index.js│ ├── store│ │ ├── actions.js│ │ ├── getters.js│ │ ├── index.js│ │ ├── modules│ │ │ └── home.js│ │ └── mutations.js│ └── utils│ ├── http.js│ └── tool.js└── vue.config.js
$: vue create vue_cli_3_mobile_vm_demo
$: Please pick a preset: **default (babel, eslint)
$: npm install eslint-config-standard eslint-friendly-formatter eslint-plugin-import eslint-plugin-node eslint-plugin-promise eslint-plugin-standard --save-dev
配置統(tǒng)一規(guī)則,團隊開發(fā)統(tǒng)一規(guī)范,在根目錄創(chuàng)建文件.eslintrc.js。(PS:配置完規(guī)則后,需要根據(jù)自身開發(fā)工具安裝Eslint插件,如VSCode,安裝ESLint插件)可以根據(jù)自身團隊的習(xí)慣,指定規(guī)則,下面只是一種參考
module.exports = { root: true, parserOptions: { parser: 'babel-eslint' }, env: { browser: true, }, extends: [ // https://github.com/vuejs/eslint-plugin-vue#priority-a-essential-error-prevention // consider switching to `plugin:vue/strongly-recommended` or `plugin:vue/recommended` for stricter rules. 'plugin:vue/essential', // https://github.com/standard/standard/blob/master/docs/RULES-en.md 'standard' ], // required to lint *.vue files plugins: [ 'vue' ], // add your custom rules here rules: { "semi": [2, "always"], // allow async-await 'generator-star-spacing': 'off', // allow debugger during development 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off' }}
$: npm install sass-loader node-sass --save-dev
創(chuàng)建全局scss文件./src/scss/global.scss
// 文件中可以寫全局的變量,包括字體大小,主題色,邊距大小等,這樣可以方便后面整個項目風(fēng)格修改// 主題 - 藍$primary-color: #03A9F4;$primary-color-dark: #409EFF;$primary-color-light:#B3E5FC;$primary-color-rgba-1: rgba(3,169,244,.1);$primary-color-rgba-2: rgba(3,169,244,.2);$background-color: #F0F2F5;// 文字樣式$title-text-color: #303133;$normal-text-color: #606266;$sub-text-color: #909399;$temp-text-color: #C0C4CC;
根目錄創(chuàng)建vue.config.js,引入全局文件
module.exports = {... css: { loaderOptions: { sass: { // 根據(jù)自己樣式文件的位置調(diào)整 prependData: '@import "@/assets/scss/global.scss";' } } }...};
具體可以了解下https://www.w3cplus.com/css/v...,這里有講到一些原理,這里不做展開安裝依賴
$: npm i postcss-aspect-ratio-mini postcss-px-to-viewport postcss-write-svg postcss-cssnext postcss-viewport-units postcss-import postcss-cssnext cssnano cssnano-preset-advanced postcss-import postcss-url --save-dev
配置規(guī)則,修改vue.config.js
module.exports = {... css: { loaderOptions: { sass: { // 根據(jù)自己樣式文件的位置調(diào)整 prependData: '@import "@/assets/scss/global.scss";' }, postcss: { plugins: [ require('postcss-px-to-viewport')({ viewportWidth: 750, viewportHeight: 1334, unitPrecision: 3, viewportUnit: 'vw', "selectorBlackList": [".ignore", ".hairlines"], // 這里是過濾不轉(zhuǎn)換的css,支持正則,如果框架本身把單位寫死支持移動端,可以通過這個過濾掉,比如vux UI框架需要過濾掉['.ignore', '.hairlines', /^\.weui/, /^\.dp/, /^\.scroller/, /^\.ignore/], minPixelValue: 1, mediaQuery: false }) ] } } }...};
$: npm install vue-router veux axios --save
.├── App.vue // VUE總?cè)肟讴扩ぉ?api // API請求文件夾│ └── homeApi.js // 分模塊寫請求文件├── assets // 靜態(tài)文件│ ├── img // 圖片資源│ │ └── head.png│ └── scss // scss樣式資源│ └── global.scss├── components // 抽象出來的組建│ └── SubTitle.vue├── main.js // Vue主文件├── page // 應(yīng)用頁面│ └── Home.vue├── router // 路由│ └── index.js├── store // 狀態(tài)存儲│ ├── actions.js│ ├── getters.js│ ├── index.js│ ├── modules│ │ └── home.js│ └── mutations.js└── utils // 工具 ├── http.js └── tool.js
import Vue from 'vue';import App from './App.vue';import router from './router/index';import store from './store/index';Vue.config.productionTip = false;new Vue({ store, router, render: h => h(App)}).$mount('#app');
<template> <div id="app"> <router-view/> </div></template><script>export default { name: 'app', components: {}};</script><style>/* 去除默認(rèn)自帶的所有邊距 */html, body { margin: 0px; padding: 0px;}</style>
創(chuàng)建./src/router/index.js
import Vue from 'vue';import Router from 'vue-router';import Home from '@/page/Home';Vue.use(Router);export default new Router({ routes: [ // 登陸 { path: '/', name: 'Home', component: Home } ]});
最外層的為全局狀態(tài)管理(action.js/getters.js/index.js/mutations.js),modules下放的為每個模塊單獨的狀態(tài)存儲具體可以下載項目看具體代碼內(nèi)容
.├── actions.js├── getters.js├── index.js├── modules│ └── home.js└── mutations.js
這里展示index.js
import Vue from 'vue';import Vuex from 'vuex';// 引入全局存儲import * as actions from './actions';import * as mutations from './mutations';import * as getters from './getters';// 引入模塊存儲import home from './modules/home';Vue.use(Vuex);export default new Vuex.Store({ state: { globalFlag: 0 }, actions, mutations, getters, modules: { home }});
這里以引入Vant UI為例
$: npm install vant --save
安裝按需加載依賴,babel-plugin-import 是一款 babel 插件,它會在編譯過程中將 import 的寫法自動轉(zhuǎn)換為按需引入的方式
$: npm install babel-plugin-import --save-dev
配置babel,修改根目錄下的babel.config.js
module.exports = { presets: [ '@vue/app' ], plugins: [ [ 'import', { libraryName: 'vant', libraryDirectory: 'es', style: true }, 'vant' ] ]};
由于Vant UI本身就自帶了自適應(yīng),所以無需轉(zhuǎn)換為vw單位,我們可以再postcss上過濾掉,修改根目錄的vue.config.js文件
module.exports = { css: { loaderOptions: { sass: { // 根據(jù)自己樣式文件的位置調(diào)整 prependData: '@import "@/assets/scss/global.scss";' }, postcss: { plugins: [ require('postcss-px-to-viewport')({ viewportWidth: 750, viewportHeight: 1334, unitPrecision: 3, viewportUnit: 'vw', selectorBlackList: ['.ignore', '.hairlines', /^\.dp/, /^\.scroller/, /^\.van/], // 這里是過濾不轉(zhuǎn)換的css,支持正則,如果框架本身把單位寫死支持移動端,可以通過這個過濾掉 minPixelValue: 1, mediaQuery: false }) ] } } }};
<template> <div class="home-container"> <!-- 導(dǎo)航 --> <van-nav-bar :title="title" left-text="返回" left-arrow> <van-icon name="shopping-cart-o" slot="right" info="9" size="20px"/> </van-nav-bar> <!-- 通知欄 --> <van-notice-bar :text="notify" left-icon="volume-o" /> <!-- 輪播圖 --> <van-swipe :autoplay="3000" indicator-color="white" class="swipe-container"> <van-swipe-item class="swipe-box swipe-color-1">1</van-swipe-item> <van-swipe-item class="swipe-box swipe-color-2">2</van-swipe-item> <van-swipe-item class="swipe-box swipe-color-3">3</van-swipe-item> <van-swipe-item class="swipe-box swipe-color-4">4</van-swipe-item> </van-swipe> <!-- 菜單 --> <van-grid :column-num="3"> <van-grid-item icon="like-o" text="收藏" /> <van-grid-item icon="clock-o" text="歷史訂單" /> <van-grid-item icon="balance-o" text="資金管理" /> <van-grid-item icon="setting-o" text="設(shè)置" /> <van-grid-item icon="location-o" text="收貨地址" /> <van-grid-item icon="service-o" text="服務(wù)中心" /> </van-grid> <!-- 懶加載 --> <van-skeleton title avatar :row="3" class="skeleton-box"/> <van-skeleton title avatar :row="3" class="skeleton-box"/> <van-skeleton title avatar :row="3" class="skeleton-box"/> <!-- 底部 --> <Footer :msg="copyright"></Footer> </div></template><script>import { Icon, NavBar, NoticeBar, Grid, GridItem, Swipe, SwipeItem, Skeleton } from 'vant';import Footer from '@/components/Footer';import { mapState } from 'vuex';export default { name: 'Home', components: { Footer, [Icon.name]: Icon, [NavBar.name]: NavBar, [NoticeBar.name]: NoticeBar, [Grid.name]: Grid, [GridItem.name]: GridItem, [Swipe.name]: Swipe, [SwipeItem.name]: SwipeItem, [Skeleton.name]: Skeleton }, data () { return { title: 'Vue 企業(yè)級工程架構(gòu)', notify: '本項目是基于Vue-Cli3腳手架,應(yīng)用VW的自適應(yīng)解決方案構(gòu)建的移動端企業(yè)級工程項目,下面會一步步構(gòu)建起項目結(jié)構(gòu),方便大家了解整個過程。' }; }, computed: { ...mapState(['copyright']) }};</script><style lang="scss" scoped>.home-container { width: 100vw; min-height: 100vh; background-color: #fff; .swipe-container { height: 380px; .swipe-box { display: flex; align-items: center; justify-content: center; width: 100%; height: 100%; font-size: 58px; color: #fff; } .swipe-color-1 { background-color: #845EC2; } .swipe-color-2 { background-color: #FFC75F; } .swipe-color-3 { background-color: #008E9B; } .swipe-color-4 { background-color: #4D8076; } } .skeleton-box { margin-top: 15px; }}</style>
由于大部分情況下,我們都是在本地開發(fā),請求后端服務(wù),所以我們這里可以直接在vue.config.js中配置測試服器地址或本地服務(wù)地址,這樣我們就可以直接在本地測試服務(wù)端的功能,并且解決跨域問題配置根目錄下的vue.config.js
module.exports = {... devServer: { proxy: { '/api': { // 需要轉(zhuǎn)發(fā)的接口,如果全轉(zhuǎn)發(fā)就設(shè)置根就行/ target: 'http://xxxx:8080/', // 對應(yīng)自己的接口 changeOrigin: true, ws: true, pathRewrite: { '^/api': '' } } } },...};