Ver Fonte

[新增] PageHeader 组件

WuXinyu há 7 anos atrás
pai
commit
8e1b6f04ad

+ 1 - 1
mock/modules/course/index.js

@@ -32,7 +32,7 @@ router
 
 router.route("/course/:courseId").get((req, res) => {
   res.send({
-    data: courseSerializer()
+    data: courseSerializer(req.params.courseId)
   });
 });
 

+ 2 - 2
mock/serializers/course/CourseSerializer.js

@@ -14,9 +14,9 @@ const userSerializer = require("../user/UserSerializer");
  * @description 生成课程信息
  * @returns {CourseSerializerType}
  */
-module.exports = () => {
+module.exports = (id = makeId()) => {
   return {
-    id: makeId(),
+    id,
     name: "软件工程第二阶段 2018",
     code: "xxxxx",
     teacher: userSerializer("TEACHER")

+ 5 - 0
src/assets/scss/app.scss

@@ -61,3 +61,8 @@ $default-margin-between:1.5rem;
     background-color: rgba(0, 0, 0, 0.18) !important;
   }
 }
+
+.tabs a,
+.tabs ul{
+  border-bottom-color: white;
+}

+ 76 - 1
src/components/PageHeader/index.jsx

@@ -1,11 +1,86 @@
+import { mapState } from "vuex";
+import "./index.scss";
+
 export default {
+  name: "PageHeader",
   props: {
     routes: {
       type: Array,
       default: () => []
+    },
+    tabList: {
+      type: Array,
+      default: () => []
     }
   },
+  computed: {
+    ...mapState({
+      course: state => state.course.currentCourse,
+      profile: state => state.user.profile
+    })
+  },
   render() {
-    return <h1>hello</h1>;
+    const { profile, course = {}, routes = [], tabList = [] } = this;
+    const { role = "" } = profile;
+    const prefix = `/course-${role.toLowerCase()}/${course.id}`;
+    const { logo, title, action, content, extraContent } = this.$slots;
+    const showTabs = tabList && tabList.length > 0;
+    console.log(prefix);
+    return (
+      <div class="page-header">
+        <nav class="breadcrumb" aria-label="breadcrumbs">
+          <ul>
+            <li>
+              <router-link to={{ name: "HOME" }}>所有课程</router-link>
+            </li>
+            <li>
+              <router-link to={`${prefix}/dashboard`}>
+                {course.name}
+              </router-link>
+            </li>
+            {routes.map((route, index) => (
+              <li class={index === routes.length - 1 && "is-active"}>
+                <router-link
+                  to={`${prefix}/${route.path}`}
+                  // active-class="is-active"
+                  // tag="li"
+                >
+                  {route.name}
+                </router-link>
+              </li>
+            ))}
+          </ul>
+        </nav>
+        <div class="detail">
+          {logo && <div class="logo">{logo}</div>}
+          <div class="main">
+            <div class="row">
+              {title && <h1 class="title">{title}</h1>}
+              {action && <div class="action">{action}</div>}
+            </div>
+            <div class="row">
+              {content && <div class="content">{content}</div>}
+              {extraContent && <div class="extra-content">{extraContent}</div>}
+            </div>
+          </div>
+        </div>
+        {showTabs && (
+          <div class="tabs">
+            <ul>
+              {tabList.map(tab => (
+                <router-link
+                  active-class="is-active"
+                  exact={tab.exact ? tab.exact : true}
+                  to={`${prefix}/${tab.path}`}
+                  tag="li"
+                >
+                  <a>{tab.name}</a>
+                </router-link>
+              ))}
+            </ul>
+          </div>
+        )}
+      </div>
+    );
   }
 };

+ 105 - 0
src/components/PageHeader/index.scss

@@ -0,0 +1,105 @@
+@import "../../assets/scss/app";
+
+.page-header {
+  background: white;
+  padding: $default-margin-between $default-margin-between*1.5 0 $default-margin-between*1.5;
+  box-shadow: $default-shadow-lighter;
+  .wide {
+    max-width: 1200px;
+    margin: auto;
+  }
+  .detail {
+    display: flex;
+  }
+
+  .row {
+    display: flex;
+    width: 100%;
+  }
+
+  .breadcrumb {
+    margin-bottom: $default-margin-between;
+  }
+
+  .tabs {
+    margin: 0 0 0 -8px;
+
+    :global {
+      // 1px 可以让选中效果显示完成
+      .ant-tabs-bar {
+        border-bottom: none;
+        margin-bottom: 1px;
+      }
+    }
+  }
+
+  .logo {
+    flex: 0 1 auto;
+    margin-right: 16px;
+    padding-top: 1px;
+    > img {
+      width: 28px;
+      height: 28px;
+      border-radius: $default-radius;
+      display: block;
+    }
+  }
+
+  .title {
+    font-size: 20px;
+    font-weight: 500;
+    //color: $default;
+  }
+
+  .action {
+    margin-left: 56px;
+    min-width: 266px;
+
+    :global {
+      .ant-btn-group:not(:last-child),
+      .ant-btn:not(:last-child) {
+        margin-right: 8px;
+      }
+
+      .ant-btn-group > .ant-btn {
+        margin-right: 0;
+      }
+    }
+  }
+
+  .title,
+  .content {
+    flex: auto;
+  }
+
+  .action,
+  .extra-content,
+  .main {
+    flex: 0 1 auto;
+  }
+
+  .main {
+    width: 100%;
+  }
+
+  .title,
+  .action {
+    margin-bottom: $default-margin-between;
+  }
+
+  .logo,
+  .content,
+  .extra-content {
+    margin-bottom: $default-margin-between;
+  }
+
+  .action,
+  .extraContent {
+    text-align: right;
+  }
+
+  .extraContent {
+    margin-left: 88px;
+    min-width: 242px;
+  }
+}

+ 1 - 2
src/layouts/courseLayouts/LayoutStructure.vue

@@ -81,7 +81,6 @@ $top-section-height: 4.25rem;
 
 .router-section {
   /*padding: 24px;*/
-  flex-grow: 1;
   flex: 1;
   /*max-width: 1000px;*/
 }
@@ -152,6 +151,6 @@ $top-section-height: 4.25rem;
 }
 
 .router-part {
-  padding: $default-margin-between;
+  //padding: $default-margin-between;
 }
 </style>

+ 37 - 1
src/views/teacher/Dashboard/index.vue

@@ -1,3 +1,39 @@
 <template>
-  <div></div>
+  <div>
+    <page-header
+      :routes="[
+        { name: '小白大王', path: 'adsfsa' },
+        { name: '小白大fsa王dasfas', path: 'adsfsa/fdsafdsa' }
+      ]"
+      :tab-list="[
+        { name: '小白大王', path: 'dashboard' },
+        { name: '小白大fsa王dasfas', path: 'adsfsa/fdsafdsa' }
+      ]"
+    >
+      <template slot="title">
+        Here might be a page title
+      </template>
+      <template slot="content">
+        Here might be a page title
+      </template>
+      <template slot="extraContent">
+        Here might be a page title
+      </template>
+      <template slot="logo">
+        Here might
+      </template>
+      <template slot="action">
+        Here might be a page title
+      </template>
+    </page-header>
+  </div>
 </template>
+
+<script>
+import PageHeader from "@/components/PageHeader";
+export default {
+  components: {
+    PageHeader
+  }
+};
+</script>