Vue學習(6) Ant-design-vue-pro手把手搭建(1)

首先創建一個使用ant-designUI框架的項目,創建過程見https://blog.csdn.net/qq_41957257/article/details/105322193,根據這個過程,項目已經包括less處理器、Jest單元測試等功能,還可實現按需加載。下面,我們就在這個的基礎上逐步搭建Vue版的ant-design-pro。

一.可擴展性路由創建

ant-design-pro包括如下模塊:

- Dashboard
  - 分析頁
  - 監控頁
  - 工作臺
- 表單頁
  - 基礎表單頁
  - 分步表單頁
  - 高級表單頁
- 列表頁
  - 查詢表格
  - 標準列表
  - 卡片列表
  - 搜索列表(項目/應用/文章)
- 詳情頁
  - 基礎詳情頁
  - 高級詳情頁
- 結果
  - 成功頁
  - 失敗頁
- 異常
  - 403 無權限
  - 404 找不到
  - 500 服務器出錯
- 個人頁
  - 個人中心
  - 個人設置
- 圖形編輯器
  - 流程圖編輯器
  - 腦圖編輯器
  - 拓撲編輯器
- 帳戶
  - 登錄
  - 註冊
  - 註冊成功

每個模塊在項目中都在Views下有一個文件夾與之相應,我們就實現其中五個模塊,如下所示

相應地,也對應一段路由,如dashboard模塊就對應於/dashboard,用戶模塊就對應於/user,同時爲了邏輯清晰,每個模塊下的各個頁在路由上都作爲模塊的孩子路由,如用戶模塊的路由寫法如下:

        {
          path: "/user",
          component: () =>
            import(/* webpackChunkName: "layout" */ "../layouts/UserLayout"),
          children: [
            {
              path: "/user",
              redirect: "/user/login"
            },
            {
              path: "/user/login",
              name: "login",
              component: () =>
                import(/* webpackChunkName: "user" */ "../views/User/Login")
            },
            {
              path: "/user/register",
              name: "register",
              component: () =>
                import(/* webpackChunkName: "user" */ "../views/User/Register")
            },
            {
              path: "/user/register-result",
              name: "register.result",
              component: () =>
                import(
                  /* webpackChunkName: "user" */ "../views/User/RegisterResult"
                )
            }
          ]

 用戶模塊路由是/user,我們採用用戶佈局(後面實現),其下面的頁l路由都作爲用戶模塊的孩子,如登錄就是/user/login,對應User文件夾下的Login組件,這樣的好處是非常清晰,而且如果你想在用戶模塊下增加新的頁面,路由擴展起來就非常方便,只需將新頁面的路由放到children裏即可。 

這裏還寫了一個重定向,即如果你輸入/user就會重定向到/user/login中。

其他的路由寫法也類似,代碼如下:

import Vue from "vue";
import VueRouter from "vue-router";
import NProgress from "nprogress";
import "nprogress/nprogress.css";
Vue.use(VueRouter);
const router = new VueRouter({
  mode: "history",
  base: process.env.BASE_URL,
  routes: [
    {
      path: "/",
      component: () =>
        import(/* webpackChunkName: "layout" */ "../layouts/BasicLayout"),
      children: [
        // dashboard
        {
          path: "/",
          redirect: "/dashboard/analysis"
        },
        {
          path: "/dashboard",
          name: "dashboard", 
          component: { render: h => h("router-view") },
          children: [
            {
              path: "/dashboard/analysis",
              name: "analysis",
              component: () =>
                import(
                  /* webpackChunkName: "dashboard" */ "../views/Dashboard/Analysis"
                )
            }
          ]
        },
        // form
        {
          path: "/form",
          name: "form",
          component: { render: h => h("router-view") },
          children: [
            {
              path: "/form/basic-form",
              name: "basicForm",
              component: () =>
                import(
                  /* webpackChunkName: "form" */ "../views/Forms/BasicForm"
                )
            },
            {
              path: "/form/step-form",
              name: "stepForm",
              component: () =>
                import(
                  /* webpackChunkName: "form" */ "../views/Forms/StepForm"
                ),
              children: [
                {
                  path: "/form/step-form",
                  redirect: "/form/step-form/info"
                },
                {
                  path: "/form/step-form/info",
                  name: "info",
                  component: () =>
                    import(
                      /* webpackChunkName: "form" */ "../views/Forms/StepForm/Step1"
                    )
                },
                {
                  path: "/form/step-form/confirm",
                  name: "confirm",
                  component: () =>
                    import(
                      /* webpackChunkName: "form" */ "../views/Forms/StepForm/Step2"
                    )
                },
                {
                  path: "/form/step-form/result",
                  name: "result",
                  component: () =>
                    import(
                      /* webpackChunkName: "form" */ "../views/Forms/StepForm/Step3"
                    )
                }
              ]
            }
          ]
        },
        // Exception
        {
          path: "/exception",
          name: "exception",
          component: { render: h => h("router-view") },
          redirect: "/exception/403",
          children: [
            {
              path: "/exception/403",
              name: "exception403",
              component: () =>
                import(
                  /* webpackChunkName: "exception" */ "../views/Exception/403"
                ),
            },
            {
              path: "/exception/404",
              name: "exception404",
              component: () =>
                import(
                  /* webpackChunkName: "exception" */ "../views/Exception/404"
                ),
            },
            {
              path: "/exception/500",
              name: "exception500",
              component: () =>
                import(
                  /* webpackChunkName: "exception" */ "../views/Exception/500"
                ),
            }
          ]
        },
        // Profile
        {
          path: "/profile",
          name: "profile",
          component: { render: h => h("router-view") },
          redirect: "/profile/basic",
          children: [
            {
              path: "/profile/basic",
              name: "basic",
              component: () =>
                import(
                  /* webpackChunkName: "profile" */ "../views/Profile/BasicProfile"
                ),
            },
            {
              path: "/profile/advanced",
              name: "advanced",
              component: () =>
                import(
                  /* webpackChunkName: "profile" */ "../views/Profile/AdvancedProfile"
                ),
              meta: { title: "高級詳情頁" }
            }
          ]
        },
        {
          path: "/user",
          component: () =>
            import(/* webpackChunkName: "layout" */ "../layouts/UserLayout"),
          children: [
            {
              path: "/user",
              redirect: "/user/login"
            },
            {
              path: "/user/login",
              name: "login",
              component: () =>
                import(/* webpackChunkName: "user" */ "../views/User/Login")
            },
            {
              path: "/user/register",
              name: "register",
              component: () =>
                import(/* webpackChunkName: "user" */ "../views/User/Register")
            },
            {
              path: "/user/register-result",
              name: "register.result",
              component: () =>
                import(
                  /* webpackChunkName: "user" */ "../views/User/RegisterResult"
                )
            }
          ]
        }
      ]
    },
    {
      path: "/403",
      name: "403",
      component: () =>
        import(/* webpackChunkName: "exception" */ "../views/Exception/403")
    },
    {
      path: "*",
      name: "404",
      component: () =>
        import(/* webpackChunkName: "exception" */ "../views/Exception/404")
    }
  ]
});
export default router;

這裏我們看到了下面這串代碼,這實際上就是調用了render函數來渲染,如同直接使用包含<router-view></router-view>的組件

{ render: h => h("router-view") }

我們除了正常的模塊,還包括了404,就是訪問地址不存在時就會跳轉到404。

好,我們路由寫好後就按照路由的配置相應去創建各個文件,views文件夾下的截圖如下所示:

我們在路由上還看到好幾個佈局文件,因此我們創建layouts文件夾,裏面放上用到的BasicLayout和UserLayout,由於我們所有的佈局都包括頭部、側邊菜單和尾部,我們需要把他們抽離出來,因此我們在layouts下新增Footer.vue、SiderMenu.Vue和Header.vue文件,layouts文件夾截圖如下所示:

我們把這三個組件在BasicLayout中引入,代碼如下:

<template>
  <div>
    <Header></Header>
    <SiderMenu></SiderMenu>
    <router-view></router-view>
    <Footer></Footer>
  </div>
</template>

<script>
import Header from "./Header";
import Footer from "./Footer";
import SiderMenu from "./SiderMenu";
export default {
  name: "",
  components: {
    Header,
    Footer,
    SiderMenu
  }
};
</script>

<style scoped></style>

我們隨便在這三個組件裏放上文字,如Header組件中放上頭部,SiderMenu組件中放入側邊欄,運行npm run serve,可以看到如下效果

二 引入nprogess來展示路由跳轉效果

1.下載: 運行npm i nprogess

2. 引入  在router/index.js中加上如下代碼進行引入

import NProgress from "nprogress";
import "nprogress/nprogress.css";

3. 添加路由守衛,在路由跳轉前開啓nprogess,路由跳轉結束後停止

//路由跳轉前
router.beforeEach((before, to, next) => {
  NProgress.start();
  next();
});

//路由跳轉後,停止
router.afterEach(() => {
  NProgress.done();
});

4. 測試,我們在App.vue中加入一個路由鏈接,跳轉到分析頁

<router-link to="/dashboard/analysis">分析頁</router-link>

這樣,我們在點擊的時候就會有加載效果了.

三  實現BasicLayout樣式 

下圖是Ant Design Pro of React網站的樣子

 

我們去Ant Design Vue官網(https://www.antdv.com/)的Layout裏去找 類似的樣式,下圖就是相類似的樣式

現在我們複製其代碼到我們的BasicLayout裏,相應的Header、SiderMenu和Footer部分用我們的組件替代,代碼如下

<template>
  <div>
    <a-layout id="components-layout-demo-side" style="min-height: 100vh">
      <a-layout-sider collapsible v-model="collapsed">
        <div class="logo"></div>
        <SiderMenu></SiderMenu>
      </a-layout-sider>
      <a-layout>
        <a-layout-header style="background: #fff; padding: 0" >
          <Header></Header>
        </a-layout-header>
        <a-layout-content style="margin: 0 16px">
          <router-view></router-view>
        </a-layout-content>
        <a-layout-footer style="text-align: center">
          <Footer></Footer>
        </a-layout-footer>
      </a-layout>
    </a-layout>
  </div>
</template>

<script>
import Header from "./Header";
import Footer from "./Footer";
import SiderMenu from "./SiderMenu";
export default {
  name: "",
  components: {
    Header,
    Footer,
    SiderMenu
  },
  data() {
    return {
      collapsed: false,//控制左側菜單伸縮
    };
  },
};
</script>

<style scoped></style>

 現在我們還不能看到效果,因爲我們未引入Layout組件,在main.js裏進行引入

import { Button, Layout } from "ant-design-vue";
Vue.use(Layout);

最後運行npm run serve就可以看到效果如下

我們按下面的"<"就會收縮側邊欄,現在我們想向上面的樣式一樣點擊上面的圖標進行收縮,因此我們先將"<"隱藏,按照官方說明,我們在<a-layout-sider>添加:trigger="null"即可,可以發現"<"不見了,然後在<a-layout-header>裏添加icon圖標

<a-icon @click="collapsed=!collapsed" style="margin-left: 20px" :type="collapsed? 'menu-fold':'menu-unfold'"></a-icon>

最後引入Icon組件,運行npm run serve,可以看到如下效果,可以靠這個圖標控制收縮

至於頭部的東西到下面去了,我們只需加上float:right即可

就此,我們就實現了第一步。 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章