国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

詳解基于vue-cli3.0如何構建功能完善的前端架子

2019-11-19 12:45:37
字體:
來源:轉載
供稿:網友

上一篇文章寫了vue和typescript的整合,發現很多小伙伴對vue-cli構建出來的項目很感興趣,所以今天打算寫寫怎么在vue-cli3.0的架子上,在進一步完善,整合出具備基礎功能的前端架子,主要包括以下幾個功能點:

  1. webpack 打包擴展
  2. css:sass支持、normalize.css
  3. rem布局
  4. 路由設計:懶加載、前置檢查、合法性校驗
  5. api 設計
  6. 請求體設計-防重復提交
  7. vuex狀態管理

webpack 打包擴展

vue-cli3 最大的特點就是 零配置 ,腳手架把webpack相關的配置都隱藏在@vue/preload-webpack-plugin中,默認的配置可以滿足大部分應用場景,優點是我們可以節省很多折騰配置的時間,webpack對于新手來說,還是有點門檻的,這樣一來,新人上手可以更關注于vue的編碼上。缺點也很明顯,對于想自己進行自定義配置的時候,就會稍微麻煩些。

查看當前webpack的詳細配置

使用 vue inspect 可以查看到詳細的配置列表

擴展webpack配置

當我們想要修改或者擴展webpack配置項時,可以在根目錄下新增 vue.config.js 文件,列舉個我自己寫的簡單小栗子

// webpack 擴展module.exports = { baseUrl: 'production' === process.env.NODE_ENV ?  '/production-sub-path/' :  '/', chainWebpack: config => {  config.module   .rule('images')   .use('url-loader')   .tap(options => Object.assign(options, { limit: 500 })); }, devServer: {  open: 'darwin' === process.platform,  // host: '0.0.0.0',  port: 8088,  https: false,  hotOnly: false,  // proxy: 'https://api.douban.com' // string | Object   proxy: 'http://localhost:3000' // string | Object  }, lintOnSave: false};

官網Vue.js 開發的標準工具 的介紹非常詳細,而且還有中文版,非常易懂,

sass支持

<style lang="scss"></style>
<style lang="scss">@import "./assets/style/app";</style>

在組件中使用自定義的 functions 和 mixin,我暫時沒找到全局引用的辦法,只能在需要使用的組件文件中手動引用,如下

<style lang="scss">@import "../assets/style/functions";@import "../assets/style/mixin";.rem { height: px2rem(187.5px); //自定義的函數}.mimi { @include clearfix(); //自定義的mixin}</style>

為了抹平各個瀏覽器間的差異,我們需要引入 normalize.css

// app.scss@import "./node_modules/normalize.css/normalize"; //引用第三方normalize@import "custom_normalize"; // 自定義的normalize

rem布局

在移動端下使用rem布局是個不錯的選擇,既然我們使用里的scss,那么可以使用函數來簡化我們的重復計算的工作。設計給到的通常是2倍圖,寬為750px,那么我們可以將基準設為 document.getElementsByTagName('html')[0].style.fontSize = window.innerWidth / 10 + 'px'; 然后寫個轉換函數,如下:

// _functions.scss@function px2rem($px) { $rem: 75px; @return ($px/$rem) + rem;}

我們在使用的時候,就可以這么寫

.rem { height: px2rem(300px); // 2倍圖下的寬是300px,}

轉換成css就是

.rem { height: 4rem;}

路由設計

主要包括路由懶加載、路由前置檢查、合法性校驗邏輯,以下是我寫的一個簡單路由

import Vue from 'vue';import Router from 'vue-router';// 路由懶加載const getComponent = (name: string) => () => import(`./views/${name}.vue`);Vue.use(Router);const router = new Router({ routes: [  {   path: '/',   name: 'home',   component: getComponent('home')  },  {   path: '/about',   name: 'about',   component: getComponent('about'),   meta: {    auth: true   }  },  {   path: '*',   name: 'not_fount',   component: getComponent('notFount')  } ]});/** * 路由前置檢查 */router.beforeEach((to, from, next) => { // 合法性校驗 if (to.meta.auth) {  console.log('into auth');  next(); } next();});export default router;

api 設計

新建 service 文件夾用于存放api腳本,根據業務模塊來劃分文件,如用戶相關的api一個文件、購買相關的一個文件, api.ts 是各模塊api的集合,如下

// service/api.tsexport { userApi } from './user';export { buyApi } from './buy';// service/user.tsexport const userApi = { /**  * 獲取用戶數據  */ userInfo: '/node_api/read/userInfo'};// service/buy.tsexport const buyApi = { /**  * 購買  */ shoping: '/node_api/shop/buy'};

這么劃分,是為了項目結構和業務結構都足夠清晰,同時可以避免單文件過長的問題。

HTTP請求二次封裝

發送http我使用的是非常流行的 axios ,我在其基礎上,稍微進行簡單的封裝,然后暴露 request 對象供調用。二次封裝主要是為了解決以下幾個問題

  1. 簡化參數,把一些常用參數都賦默認值,簡化外部的使用,使得更加通用和利于排查問題。
  2. 返回報文統一處理,我們通常需要對些高頻的場景做相同的處理,如錯誤碼、未登錄等場景,可以在它提供的返回響應攔截器中,統一處理。
  3. 防止重復提交,因為網絡、后端處理的因素,有時接口響應會較慢,那么用戶可能會在非常短的時間內,反復點擊按鈕,在第一次請求未返回的情況下,會再次發起新的請求,那么我們可以在axios提供的前置攔截器中搞點事情。關于防止重復請求這東東,我在以前的一篇文章有寫過, 前端防止用戶重復提交-js 感興趣的小伙伴可以看看。

根據以上幾點,下面是我封裝的request文件,思路都比較簡單,就不多說啦

import axios from 'axios';import qs from 'qs';const Axios = axios.create({ baseURL: '/', timeout: 10000, responseType: 'json', withCredentials: true, headers: {  'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8' }});const CancelToken = axios.CancelToken;const requestMap = new Map();// 請求前置攔截器Axios.interceptors.request.use( config => {  // 防重復提交  const keyString = qs.stringify(Object.assign({}, { url: config.url, method: config.method }, config.data));  if (requestMap.get(keyString)) {   // 取消當前請求   config.cancelToken = new CancelToken((cancel) => {    cancel('Please slow down a little');   });  }  requestMap.set(keyString, true);  Object.assign(config, { _keyString: keyString });  if (config.method === 'post' || config.method === 'put' || config.method === 'delete') {   // 序列化   config.data = qs.stringify(config.data);  }  return config; }, error => {  return Promise.reject(error); });// 返回響應攔截器Axios.interceptors.response.use( res => {  // 重置requestMap  const config: any = res.config;  requestMap.set(config._keyString, false);  if (res.status === 200) {   return res.data;  }  // todo 彈窗提示等  console.log(`request error:${res}`); }, error => {  return {   code: -1  }; });/** * @description * 請求 * @param url * @param data * @param method */const request = (url: string, data = {}, method = 'post') => { return Axios({  method,  url,  data,  params: method.toUpperCase() === 'GET' && data });};export { request };

vuex狀態管理

這里我根據業務模塊來劃分文件結構,如下圖

分為首頁模塊和用戶模塊,每個模塊都有自己獨立的 state mutations 等,在 store.ts 中,引入各模塊的文件,如下

import Vue from 'vue';import Vuex from 'vuex';import index from './indexModule/index';import user from './userModule/user';Vue.use(Vuex);export default new Vuex.Store({ modules: {  user,  index }});

大家注意到這里有個 store_types.ts 文件,這個文件主要是為了搭配ts使用的,文件內容如下

export enum UserType { /**  * 模塊名稱  */ 'MODULE_NAME' = 'user', /**  * 增加次數  */ 'ADD_COUNT' = 'addCount', /**  * 計算屬性-獲取十倍的值  */ 'GET_TEM_COUNT' = 'getTenCount'}

在看下組件中的使用方式:

<script lang="ts">import { UserType } from '@/store/store_types';import { Component, Prop, Vue, Watch,Emit } from 'vue-property-decorator';import { Action, Getter, Mutation, namespace, State} from 'vuex-class';@Componentexport default class Test extends Vue { @State(state => state[UserType.MODULE_NAME].count) public fff!: number; @Getter(`${UserType.MODULE_NAME}/${UserType.GET_TEM_COUNT}`) public tenCount!: number; @Mutation(`${UserType.MODULE_NAME}/${UserType.ADD_COUNT}`) public addCount!: any;}</script>

雖然這么寫的確有點繞,但有個好處,我們可以通過注釋清晰知道方法和屬性的說明

小結

以上是我根據自己工作中常見的場景來設計的,希望能對小伙伴能有幫助,其中設計不當的地方,歡迎小伙伴們在留言區一起探討哈~也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 象山县| 岳普湖县| 阿拉善右旗| 禹城市| 丘北县| 和硕县| 雅安市| 肇东市| 思茅市| 大竹县| 汝南县| 泰安市| 南召县| 贵溪市| 土默特左旗| 宁蒗| 昌平区| 左云县| 美姑县| 东丰县| 平安县| 兴国县| 新龙县| 福海县| 淮安市| 博罗县| 韩城市| 泾源县| 河西区| 临武县| 滕州市| 常宁市| 盘锦市| 天长市| 视频| 四会市| 贵港市| 偃师市| 留坝县| 长顺县| 夏河县|