Vue-Cli 3.0從0 開始搭建專案(篇1)

南藍發表於2019-05-04
從0開始搭建專案,相信更多人都做過,但是你真的獨立搭建整個專案了嗎,有沒有考慮周全,是否從UI的框架的選型、許可權、圖示、路由、登陸攔截、第三方工具庫、效能優化等多方面搭建出適合本公司專案的人員和環境。本文總結的是Vue-Cli3.0構建專案
搭建專案
根據實際情況而定。 值得注意的Vue-Cli 初始化專案的命令是`vue create 專案名稱`,而不是之前的`Vue init webpack 專案名稱` 我這邊大致選了history路由、Vuex、less、eslint、unit test等

Vue-Cli 3.0從0 開始搭建專案(篇1)
Vue-Cli官方地址

webpack、babel、vue.config.js的配置
vue.config.js的相關配置
// vue.config.js
const path = require('path')

const resolve = dir => {
  return path.join(__dirname, dir)
}

// 線上打包路徑,請根據專案實際線上情況
const BASE_URL = process.env.NODE_ENV === 'production' ? '/' : '/'

module.exports = {
  publicPath: BASE_URL,
  outputDir: 'dist', // 打包生成的生產環境構建檔案的目錄
  assetsDir: '', // 放置生成的靜態資源路徑,預設在outputDir
  indexPath: 'index.html', // 指定生成的 index.html 輸入路徑,預設outputDir
  pages: undefined, // 構建多頁
  productionSourceMap: false, // 開啟 生產環境的 source map?
  configureWebpack: {   // webpack 的配置
    plugins: [
      new MyAwesomeWebpackPlugin()
    ]
  },
  chainWebpack: config => { // webpack的配置(鏈式操作)
    // 配置路徑別名
    // config.resolve.alias
    //   .set('@', resolve('src'))
    //   .set('_c', resolve('src/components'))
  },
  css: {
    modules: false, // 啟用 CSS modules
    extract: true, // 是否使用css分離外掛
    sourceMap: false, // 開啟 CSS source maps?
    loaderOptions: {
      less: {
          modifyVars: {   // 定製主題
                 'primary-color': '#1DA57A',
                 'link-color': '#1DA57A',
                 'border-radius-base': '2px',
                  },
          javascriptEnabled: true,

      }
  }
  },
  devServer: {
    port: 8080, // 埠
    proxy: '' // 設定代理
  }
}
複製程式碼

Vue.config.js官方地址

babel.config.js

使用babel-plugin-import(按需載入元件程式碼和央視的babel外掛),下面的配置使用該外掛引入 vue-antd-design

// babel.config.js
module.exports = {
  presets: ["@vue/app"],
   plugins: [
     [
       "import",
     { libraryName: "ant-design-vue", libraryDirectory: "es", style: true }
    ]
  ]
};
複製程式碼
UI框架(Ant-design-vue)
全域性引入

不多說。想說的是全域性引入有13MB,50多個元件,全部引入有點大。其實在我以前做過的專案當中基本上都是全域性引入,不知大佬們寫程式碼會不會有“潔癖”,區域性引入或是自己寫,哈哈

Vue-Cli 3.0從0 開始搭建專案(篇1)

區域性引入
// main.js
import { Button } from "ant-design-vue"
import "ant-design-vue/dist/antd.less"
// 或者是
import "ant-design-vue/lib/button.less"
Vue.use(Button)
複製程式碼
使用babel-plugin-import(高階配置)

vue-and-design官方地址 配置就在上方的babel.config.js中。 我們下面看看main.js是怎麼使用的

// main.js
 import { Button,Menu,Drawer,Radio,Layout,Icon} from 'ant-design-vue';
 
 Vue.use(Drawer)
 Vue.use(Button)
 Vue.use(Menu)
 Vue.use(Radio)
 Vue.use(Layout)
 Vue.use(Icon)
複製程式碼

哎呀,貌似篇幅很長,不過載入的檔案大小確實小了很多

Vue-Cli 3.0從0 開始搭建專案(篇1)

路由配置

一定要配置路由,就得想好檔案目錄怎麼設定。這裡參考了唐老師的搭建專案的目錄

Vue-Cli 3.0從0 開始搭建專案(篇1)
路由配置,篇幅有限。我只選出一部分

// router.js
import Vue from "vue";
import Router from "vue-router";
import { notification } from "ant-design-vue";
import NotFound from "./views/404";
import Forbidden from "./views/403";
Vue.use(Router);

const router = new Router({
  mode: "history",
  base: process.env.BASE_URL,
  routes: [
    {
      path: "/user",
      hideInMenu: true,
      component: () =>
        import( "./layouts/UserLayout"),
      children: [
        {
          path: "/user",
          redirect: "/user/login"
        },
        {
          path: "/user/login",
          name: "login",
          component: () =>
            import( "./views/User/Login")
        }
      ]
    },
    {
      path: "/",
      meta: { authority: ["user", "admin"] },  // 用來做許可權管理
      component: () =>
        import( "./layouts/BasicLayout"),
      children: [
        // dashboard
        {
          path: "/",
          redirect: "/dashboard/analysis"
        },
        {
          path: "/dashboard",
          name: "dashboard",
          meta: { icon: "dashboard", title: "儀表盤" },
          component: { render: h => h("router-view") },
          children: [
            {
              path: "/dashboard/analysis",
              name: "analysis",
              meta: { title: "分析頁" },
              component: () =>
                import( "./views/Dashboard/Analysis")
            }
          ]
        },
        // form
        {
          path: "/form",
          name: "form",
          component: { render: h => h("router-view") },
          meta: { icon: "form", title: "表單", authority: ["admin"] },
          children: [
            {
              path: "/form/basic-form",
              name: "basicform",
              meta: { title: "基礎表單" },
              component: () =>
                import("./views/Forms/BasicForm")
            },
            {
              path: "/form/step-form",
              name: "stepform",
              hideChildrenInMenu: true,
              meta: { title: "分佈表單" },
              component: () =>
                import( "./views/Forms/StepForm"),
              children: [
                {
                  path: "/form/step-form",
                  redirect: "/form/step-form/info"
                },
                {
                  path: "/form/step-form/info",
                  name: "info",
                  component: () =>
                    import( "./views/Forms/StepForm/Step1")
                }
              ]
            }
          ]
        }
      ]
    },
    {
      path: "/403",
      name: "403",
      hideInMenu: true,
      component: Forbidden
    },
    {
      path: "*",
      name: "404",
      hideInMenu: true,
      component: NotFound
    }
  ]
});

export default router;
複製程式碼

總結下分為三部分:使用者模組、主要內容、403/404頁面。 使用者下面有子模組login,主要內容(一般是導航選單的內容)有儀表盤dashboard和表單form,儀表盤下面有分析頁anlysis,表單下面有基礎表單basicForm

// App.vue
  <div id="app">
        <router-view />
  </div>
複製程式碼

BasicForm.vue

Vue-Cli 3.0從0 開始搭建專案(篇1)

路由大概到這裡 這個寫法覺得很巧妙

Vue-Cli 3.0從0 開始搭建專案(篇1)

路由守衛

如果沒有許可權跳到登陸頁面, 登陸成功之後沒有許可權進入403頁面,更多路由守衛知識點選

router.beforeEach((to, from, next) => {
 
   // to 即將要進入的目標 路由物件
   // from 當前導航正要離開的路由
   // next 
  if (to.path !== from.path) {
    NProgress.start();
  }
  const record = findLast(to.matched, record => record.meta.authority);
  if (record && !check(record.meta.authority)) {
    if (!isLogin() && to.path !== "/user/login") {
      next({
        path: "/user/login"
      });
    } else if (to.path !== "/403") {
      notification.error({
        message: "403",
        description: "你沒有許可權訪問,請聯絡管理員諮詢。"
      });
      next({
        path: "/403"
      });
    }
    NProgress.done();
  }

  next();
});
// 全域性後置鉤子
router.afterEach(() => {
  NProgress.done();
});
複製程式碼
許可權管理
選單路由

在路由配置那裡有個後設資料資訊,那裡設定了哪些使用者具有選單許可權。 在真實的環境中是後端返回這個使用者的選單,有的話就渲染出來

// 檢查 使用者的許可權
export function check(authority){
    const current = getCurrentAuthority();
    return current.some(item => authority.includes(item));
}
複製程式碼
按鈕許可權

這裡是自定義指令的方式做的,更多自定義指令的引數點選

Vue-Cli 3.0從0 開始搭建專案(篇1)

import { check } from "../utils/auth";

function install(Vue, options = {}) {
  Vue.directive(options.name || "auth", {
    inserted(el, binding) {
      if (!check(binding.value)) {
        el.parentNode && el.parentNode.removeChild(el);
      }
    }
  });
}

export default { install };
複製程式碼

然後在main.js中使用

// main.js
import Auth from './directives/auth';
Vue.use(Auth);
複製程式碼
其它相關
Nprogress 過渡元件
yarn add nprogress
npm install --save-dev nprogress
複製程式碼

Vue-Cli 3.0從0 開始搭建專案(篇1)

Vue-Cli 3.0從0 開始搭建專案(篇1)

函式式元件

更多點選

之前建立的錨點標題元件是比較簡單,沒有管理任何狀態,也沒有監聽任何傳遞給它的狀態,也沒有生命週期方法。實際上,它只是一個接受一些 prop 的函式。 在這樣的場景下,我們可以將元件標記為 functional,這意味它無狀態 (沒有響應式資料),也沒有例項 (沒有 this 上下文)。

<script>
import { check } from '../utils/auth'
export default {
    functional: true,
    props: {
        authority: {
            type: Array,
            required: true
        }
    },
    render(h, context){
        const { props,scopedSlots } = context;
        return check(props.authority) ? scopedSlots.default(): null
    }

}
</script>
複製程式碼

Vue-Cli 3.0從0 開始搭建專案(篇1)

render()函式還是一個挺有意思的存在

loash庫

resize-detector

不知道在哪裡看過一句話,碼而不思則殆,思而不碼還是殆

相關文章