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即可

就此,我们就实现了第一步。 

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