浏览代码

feat: cell

richard1015 5 年之前
父节点
当前提交
95e74fe34e

+ 11 - 2
src/config.ts

@@ -26,12 +26,21 @@ export const nav = [
     name: '基础组件',
     packages: [
       {
-        name: 'uploader',
+        name: 'cell',
         sort: 1,
+        cName: '单元格组件',
+        type: 'component',
+        show: true,
+        desc: '展示列表',
+        author: 'richard1015'
+      },
+      {
+        name: 'uploader',
+        sort: 2,
         cName: '上传组件',
         type: 'component',
         show: true,
-        desc: '',
+        desc: '上传文件、图片',
         author: 'richard1015'
       }
     ]

+ 7 - 7
src/packages/button/demo.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="demo">
-    <div class="title">按钮类型</div>
+    <h2>按钮类型</h2>
     <div class="demo-button-row">
       <nut-button type="primary">主要按钮</nut-button>
       <nut-button type="info">信息按钮</nut-button>
@@ -11,27 +11,27 @@
       <nut-button type="warning">警告按钮</nut-button>
       <nut-button type="success">成功按钮</nut-button>
     </div>
-    <div class="title">朴素按钮</div>
+    <h2>朴素按钮</h2>
     <div class="demo-button-row2">
       <nut-button plain type="primary">朴素按钮</nut-button>
       <nut-button plain type="info">朴素按钮</nut-button>
     </div>
-    <div class="title">禁用状态</div>
+    <h2>禁用状态</h2>
     <div class="demo-button-row2">
       <nut-button disabled type="primary">禁用状态</nut-button>
       <nut-button plain disabled type="info">禁用状态</nut-button>
       <nut-button plain disabled type="primary">禁用状态</nut-button>
     </div>
-    <div class="title">按钮形状</div>
+    <h2>按钮形状</h2>
     <div class="demo-button-row2">
       <nut-button shape="square" type="primary">方形按钮</nut-button>
       <nut-button type="info">圆形按钮</nut-button>
     </div>
-    <div class="title">加载状态</div>
+    <h2>加载状态</h2>
 
-    <div class="title">图标按钮</div>
+    <h2>图标按钮</h2>
 
-    <div class="title">按钮尺寸</div>
+    <h2>按钮尺寸</h2>
     <div class="demo-button-row2">
       <div class="demo-button-row2">
         <nut-button block type="primary">通栏按钮</nut-button>

+ 1 - 1
src/packages/button/index.vue

@@ -64,7 +64,7 @@ export default create({
     const classes = computed(() => {
       const prefixCls = componentName;
       return {
-        [componentName]: true,
+        [prefixCls]: true,
         [`${prefixCls}--${type.value}`]: type.value,
         [`${prefixCls}--${size.value}`]: size.value,
         [`${prefixCls}--${shape.value}`]: shape.value,

+ 32 - 0
src/packages/cell/demo.vue

@@ -0,0 +1,32 @@
+<template>
+  <div class="demo">
+    <h2>基本用法</h2>
+    <nut-cell title="我是标题" desc="描述文字"></nut-cell>
+    <nut-cell title="我是标题" sub-title="副标题描述" desc="描述文字"></nut-cell>
+    <h2>链接</h2>
+    <nut-cell title="链接" is-link></nut-cell>
+    <nut-cell title="URL 跳转" is-link url="https://jd.com"></nut-cell>
+    <nut-cell title="路由跳转 ’/‘ " to="/"></nut-cell>
+    <h2>使用插槽</h2>
+    <nut-cell>
+      <!-- 使用 title 插槽来自定义标题 -->
+      <template #title>
+        <span class="custom-title">单元格</span>
+      </template>
+    </nut-cell>
+  </div>
+</template>
+
+<script lang="ts">
+import Cell from '@/packages/cell/index.vue';
+import { createComponent } from '@/utils/create';
+import { ref } from 'vue';
+const { createDemo } = createComponent('cell');
+export default createDemo({
+  props: {},
+  components: { [Cell.name]: Cell },
+  emits: ['click']
+});
+</script>
+
+<style lang="scss" scoped></style>

+ 3 - 3
src/packages/cell/doc.md

@@ -1,10 +1,10 @@
 # Cell 列表组件
 
-## 介绍
+### 介绍
 
 列表项,可组成列表。
 
-## 安装
+### 安装
 
 ``` javascript
 import { createApp } from 'vue';
@@ -22,7 +22,7 @@ app.use(Cell);
 Cell `to` 有值的时候,跳转路由,`click-cell` 点击 `cell`触发事件
 
 ``` javascript
-
+111
 ```
 
 ### 单元格大小

+ 34 - 0
src/packages/cell/index.scss

@@ -0,0 +1,34 @@
+.nut-cell {
+  display: flex;
+  width: 100%;
+  line-height: 20px;
+  padding: 13px 16px;
+  background: $white;
+  border-radius: 7px;
+  box-shadow: 0px 1px 7px 0px rgba(237, 238, 241, 1);
+  font-size: $cell-title-font;
+  color: $cell-color;
+  margin: 10px 0;
+  &:active::before {
+    opacity: 0.1;
+  }
+  &--clickable {
+    cursor: pointer;
+  }
+
+  &__title {
+    display: flex;
+    flex-direction: column;
+    flex: 1;
+    &-desc {
+      font-size: $cell-title-desc-font;
+    }
+  }
+  &__value {
+    display: inline-block;
+    text-align: right;
+    font-size: $cell-desc-font;
+    color: $cell-desc-color;
+    flex: 1;
+  }
+}

+ 76 - 0
src/packages/cell/index.vue

@@ -0,0 +1,76 @@
+<template>
+  <view :class="classes" @click="handleClick">
+    <view class="nut-cell__title">
+      <template v-if="subTitle">
+        <view class="title">{{ title }}</view>
+        <view class="nut-cell__title-desc">{{ subTitle }}</view>
+      </template>
+      <template v-else>
+        {{ title }}
+      </template>
+    </view>
+    <view class="nut-cell__value">{{ desc }}</view>
+    <nut-icon v-if="isLink || to" name="right"></nut-icon>
+    <slot></slot>
+  </view>
+</template>
+
+<script lang="ts">
+import { toRefs, computed, PropType } from 'vue';
+import { createComponent } from '@/utils/create';
+import { useRouter } from 'vue-router';
+import Icon from '@/packages/icon/index.vue';
+const { componentName, create } = createComponent('cell');
+
+export default create({
+  props: {
+    title: { type: String, default: '' },
+    subTitle: { type: String, default: '' },
+    desc: { type: String, default: '' },
+    isLink: { type: Boolean, default: false },
+    to: { type: String, default: '' },
+    replace: { type: Boolean, default: false },
+    url: { type: String, default: '' }
+  },
+  components: {
+    [Icon.name]: Icon
+  },
+  emits: ['click'],
+  setup(props, { emit, slots }) {
+    const { title, to, desc, subTitle, isLink, url, replace } = toRefs(props);
+    const classes = computed(() => {
+      const prefixCls = componentName;
+      return {
+        [prefixCls]: true,
+        [`${prefixCls}--clickable`]: isLink.value || to
+      };
+    });
+
+    const router = useRouter();
+
+    const handleClick = (event: Event) => {
+      emit('click', event);
+      debugger;
+      if (to.value && router) {
+        router[replace ? 'replace' : 'push'](to.value);
+      } else if (url.value) {
+        replace ? location.replace(url.value) : (location.href = url.value);
+      }
+    };
+
+    return {
+      handleClick,
+      title,
+      to,
+      subTitle,
+      desc,
+      classes,
+      isLink
+    };
+  }
+});
+</script>
+
+<style lang="scss">
+@import 'index.scss';
+</style>

+ 19 - 0
src/packages/icon/demo.vue

@@ -0,0 +1,19 @@
+<template>
+  <div class="demo">
+    icon
+  </div>
+</template>
+
+<script lang="ts">
+import Icon from '@/packages/icon/index.vue';
+import { createComponent } from '@/utils/create';
+import { ref } from 'vue';
+const { createDemo } = createComponent('icon');
+export default createDemo({
+  props: {},
+  components: { [Icon.name]: Icon },
+  emits: ['click']
+});
+</script>
+
+<style lang="scss" scoped></style>

+ 16 - 0
src/packages/icon/doc.md

@@ -0,0 +1,16 @@
+# Icon 列表组件
+
+### 介绍
+
+图标组件
+
+### 安装
+
+``` javascript
+import { createApp } from 'vue';
+import { Icon } from '@nutui/nutui';
+
+const app = createApp();
+app.use(Icon);
+
+```

+ 6 - 0
src/packages/icon/index.scss

@@ -0,0 +1,6 @@
+.nut-icon {
+  width: 20px;
+  height: 20px;
+  line-height: 20px;
+  text-align: right;
+}

+ 43 - 0
src/packages/icon/index.vue

@@ -0,0 +1,43 @@
+<template>
+  <view :class="classes" @click="handleClick">
+    >
+  </view>
+</template>
+
+<script lang="ts">
+import { toRefs, computed } from 'vue';
+import { createComponent } from '@/utils/create';
+const { componentName, create } = createComponent('icon');
+
+export default create({
+  props: {
+    name: { type: String, default: '' }
+  },
+  components: {},
+  emits: ['click'],
+  setup(props, { emit, slots }) {
+    const { name } = toRefs(props);
+    const classes = computed(() => {
+      const prefixCls = componentName;
+      return {
+        [prefixCls]: true
+      };
+    });
+
+    const handleClick = (event: Event) => {
+      emit('click', event);
+    };
+
+    return {
+      handleClick,
+      name,
+
+      classes
+    };
+  }
+});
+</script>
+
+<style lang="scss">
+@import 'index.scss';
+</style>

+ 2 - 33
src/sites/doc/router.ts

@@ -2,7 +2,7 @@
 import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router';
 import Index from './views/Index.vue';
 
-const pagesRouter: any = [];
+const pagesRouter: Array<RouteRecordRaw> = [];
 const files = require.context('@/packages', true, /doc\.md$/);
 files.keys().forEach(component => {
   const componentEntity = files(component).default;
@@ -19,42 +19,11 @@ const routes: Array<RouteRecordRaw> = [
     children: pagesRouter
   }
 ];
-// import { nav } from '@/config';
-// nav.forEach(item => {
-//   item.packages.forEach(_item => {
-//     if (_item.show) {
-//       routes.push({
-//         path: `/${_item.name}`,
-//         name: _item.name,
-//         components: {
-//         	main: () => import(`@/packages/${_item.name.toLocaleLowerCase()}/demo.vue`),
-//         }
-//       })
-//     }
-//   })
-// })
-
-// const files = require.context('@/packages', true, /doc\.md$/);
-// files.keys().forEach(component => {
-//   // console.log(component)
-// });
-
-routes.push({
-  name: 'NotFound',
-  path: '/:path(.*)+',
-  redirect: () => '/'
-});
-
-routes.push({
-  name: 'NotFound',
-  path: '/:path(.*)+',
-  redirect: () => '/'
-});
 
 const router = createRouter({
   history: createWebHashHistory(),
   routes,
-  scrollBehavior(to, from, savedPosition) {
+  scrollBehavior(to) {
     if (to.hash) {
       const id = to.hash.split('#')[1];
       const ele = document.getElementById(id);

+ 3 - 10
src/sites/doc/views/Index.vue

@@ -10,9 +10,8 @@
   <doc-footer></doc-footer>
 </template>
 <script lang="ts">
-import { defineComponent, ref, reactive, watch } from 'vue';
-import { useRoute, useRouter, onBeforeRouteUpdate } from 'vue-router';
-import { nav, versions } from '@/config';
+import { defineComponent, reactive } from 'vue';
+import { onBeforeRouteUpdate } from 'vue-router';
 import Header from '@/sites/doc/components/Header.vue';
 import Nav from '@/sites/doc/components/Nav.vue';
 import Footer from '@/sites/doc/components/Footer.vue';
@@ -26,18 +25,12 @@ export default defineComponent({
     [Footer.name]: Footer,
     [DemoPreview.name]: DemoPreview
   },
-  setup(prop, { emit, slots }) {
+  setup() {
     const data = reactive({
       demoUrl: 'demo.html'
     });
 
-    // 获取当前路由
-    const route = useRoute();
-    // 获取路由实例
-    const router = useRouter();
-
     onBeforeRouteUpdate(to => {
-      // 当当前路由发生变化时,调用回调函数
       const { origin, pathname } = window.location;
       data.demoUrl = `${origin}${pathname.replace('index.html', '')}demo.html#${to.path}`;
     });

+ 25 - 21
src/sites/mobile/App.vue

@@ -1,10 +1,10 @@
 <template>
-  <div id="nav">{{ title }}</div>
+  <div v-if="title != '/'" id="nav">{{ title }}</div>
   <router-view />
 </template>
 <script lang="ts">
-import { defineComponent, ref } from 'vue';
-import { useRoute, useRouter, onBeforeRouteUpdate } from 'vue-router';
+import { defineComponent, ref, watch } from 'vue';
+import { useRoute } from 'vue-router';
 
 import { isMobile } from '@/sites/assets/util';
 export default defineComponent({
@@ -12,24 +12,27 @@ export default defineComponent({
   components: {},
   setup() {
     const title = ref('NutUI');
-
     // 获取当前路由
     const route = useRoute();
-    // 获取路由实例
-    const router = useRouter();
-
-    onBeforeRouteUpdate(() => {
-      // 当当前路由发生变化时,调用回调函数
-      // const { origin, hash, pathname } = window.top.location;
-      // if (!isMobile && to.href != hash) {
-      //   window.top.location.replace(`${origin}${pathname}#/${to.name}`);
-      //   title.value = to.name;
-      // } else {
-      //   title.value = '';
-      // }
-    });
+    // 当当前路由发生变化时,调用回调函数
+    watch(
+      () => route,
+      () => {
+        const { origin, hash, pathname } = window.top.location;
+        if (!isMobile && route.hash != hash) {
+          window.top.location.replace(`${origin}${pathname}#/${route.hash}`);
+          title.value = route.name as string;
+        } else {
+          title.value = route.name as string;
+        }
+      },
+      {
+        immediate: true,
+        deep: true
+      }
+    );
 
-    return title;
+    return { title };
   }
 });
 </script>
@@ -54,10 +57,11 @@ export default defineComponent({
     height: 57px;
     line-height: 57px;
     text-align: center;
-    background: #fff;
-    font-family: PingFangSC-Medium;
+    background: $white;
+    font-weight: bold;
     font-size: 20px;
     color: rgba(51, 51, 51, 1);
+    box-shadow: 0px 4px 10px 0px rgba(0, 0, 0, 0.07);
   }
 
   .demo {
@@ -70,7 +74,7 @@ export default defineComponent({
       width: 0;
       background: transparent;
     }
-    .title {
+    > h2 {
       height: 56px;
       line-height: 56px;
       font-size: 14px;

+ 1 - 2
src/sites/mobile/components/Index1.vue

@@ -12,8 +12,7 @@
         <li>{{ _nav.name }}</li>
         <ul>
           <li v-for="_package in _nav.packages" :key="_package">
-            <router-link :to="_package.name.toLocaleLowerCase()">{{ _package.name }}&nbsp;&nbsp;{{ _package.cName }}
-            </router-link>
+            <router-link :to="_package.name.toLocaleLowerCase()">{{ _package.name }}&nbsp;&nbsp;{{ _package.cName }} </router-link>
           </li>
         </ul>
       </ol>

+ 2 - 2
src/sites/mobile/router.ts

@@ -1,9 +1,9 @@
 import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router';
-import Index from './components/Index1.vue';
+import Index from './components/Index.vue';
 const routes: Array<RouteRecordRaw> = [
   {
     path: '/',
-    name: 'index',
+    name: '/',
     component: Index
   }
 ];

+ 10 - 0
src/styles/variables.scss

@@ -7,6 +7,8 @@ $primary-color-end: #fa6419 !default;
 $help-color: #f5f5f5 !default;
 // 标题常规文字
 $title-color: #1a1a1a !default;
+// 副标题
+$title-color2: #666666 !default;
 // 次内容
 $text-color: #808080 !default;
 // 特殊禁用色
@@ -77,6 +79,14 @@ $button-warning-background-color: linear-gradient(
 $button-plain-background-color: #fff;
 $button-plain-background-color: $white;
 
+// cell
+
+$cell-color: $title-color2;
+$cell-title-font: $font-size-2;
+$cell-title-desc-font: $font-size-1;
+$cell-desc-font: $font-size-2;
+$cell-desc-color: $disable-color;
+
 //markdown-add-style
 $nutui-doc-black: #323233;
 $nutui-doc-blue: #1989fa;