Repository: Tencent/tdesign-mobile-vue
Pull request #379 (2022-09-30 05:14:14)

test(Button): improve unit test coverage
<!--
首先，感谢你的贡献！😄
请阅读并遵循 [TDesign 贡献指南](https://github.com/Tencent/tdesign/blob/main/docs/contributing.md)，填写以下 pull request 的信息。
PR 在维护者审核通过后会合并，谢谢！
-->

### 🤔 这个 PR 的性质是？
- [x] 测试用例


### 📝 更新日志

<!--
从用户角度描述具体变化，以及可能的 breaking change 和其他风险。
-->

- test(Button): 提升测试覆盖率

- [x] 本条 PR 不需要纳入 Changelog



github-actions[bot]: [<img height="96" alt="失败" src="https://user-images.githubusercontent.com/5378891/75333447-1e63a280-58c1-11ea-975d-235367fd1522.png">](https://github.com/Tencent/tdesign-mobile-vue/actions/runs/3156476766)
<!-- AUTO_PREVIEW_HOOK -->
github-actions[bot]: **Size Change:** 0 B 

**Total Size:** 255 kB



<details><summary>ℹ️ <strong>View Unchanged</strong></summary>

| Filename | Size |
| :--- | :---: |
| `./dist/tdesign.css` | 24 kB |
| `./dist/tdesign.js` | 130 kB |
| `./dist/tdesign.min.css` | 22.2 kB |
| `./dist/tdesign.min.js` | 79 kB |

</details>


github-actions[bot]: **Size Change:** 0 B 

**Total Size:** 255 kB



<details><summary>ℹ️ <strong>View Unchanged</strong></summary>

| Filename | Size |
| :--- | :---: |
| `./dist/tdesign.css` | 24 kB |
| `./dist/tdesign.js` | 130 kB |
| `./dist/tdesign.min.css` | 22.2 kB |
| `./dist/tdesign.min.js` | 79 kB |

</details>



Patch:
diff --git a/src/divider/demos/align.vue b/src/divider/demos/align.vue
index 9a342bd3..af68bd40 100644
--- a/src/divider/demos/align.vue
+++ b/src/divider/demos/align.vue
@@ -1,12 +1,19 @@
 <template>
-  <div class="demo-6">
-    <span>正直</span>
-    <t-divider align="left">TDesign</t-divider>
-    <span>进取</span>
-    <t-divider>TDesign</t-divider>
-    <span>合作</span>
-    <t-divider align="right">TDesign</t-divider>
-    <span>创新</span>
+  <div>
+    <h3>文字+直线</h3>
+    <t-divider class="demo-5"> 文字信息 </t-divider>
+
+    <h3>纯文字</h3>
+    <t-divider line-color="transparent"> 没有更多了~ </t-divider>
   </div>
 </template>
-<script lang="ts" setup></script>
+
+<style lang="less" scoped>
+h3 {
+  font-size: 12px;
+  font-weight: 400;
+  font-family: 'PingFang SC';
+  color: #a9a9a9;
+  padding: 16px;
+}
+</style>
diff --git a/src/divider/demos/base.vue b/src/divider/demos/base.vue
index 8467d814..6c22dfd8 100644
--- a/src/divider/demos/base.vue
+++ b/src/divider/demos/base.vue
@@ -1,8 +1,31 @@
 <template>
-  <div class="demo-6">
+  <div>
     <h3>直线拉通</h3>
     <t-divider></t-divider>
-    <h3>直线拉通</h3>
+
+    <h3>虚线拉通</h3>
+    <t-divider dashed></t-divider>
   </div>
 </template>
-<script lang="ts" setup></script>
+
+<style lang="less" scoped>
+h3 {
+  font-size: 12px;
+  font-weight: 400;
+  font-family: 'PingFang SC';
+  color: #a9a9a9;
+  padding: 16px;
+}
+
+.demo-2 {
+  margin: 0 16px;
+}
+
+.demo-3 {
+  margin-left: 16px;
+}
+
+.demo-4 {
+  margin-left: 76px;
+}
+</style>
diff --git a/src/divider/demos/horizontal.vue b/src/divider/demos/horizontal.vue
index 0d51bdbd..b7581fe0 100644
--- a/src/divider/demos/horizontal.vue
+++ b/src/divider/demos/horizontal.vue
@@ -1,12 +1,34 @@
 <template>
-  <div class="demo-6">
-    <span>正直</span>
-    <t-divider></t-divider>
-    <span>进取</span>
-    <t-divider></t-divider>
-    <span>合作</span>
-    <t-divider></t-divider>
-    <span>创新</span>
+  <div>
+    <h3>左右间距</h3>
+    <t-divider class="demo-2"></t-divider>
+
+    <h3>右侧拉通</h3>
+    <t-divider class="demo-3"></t-divider>
+
+    <h3>自定义左侧间距</h3>
+    <t-divider class="demo-4"></t-divider>
   </div>
 </template>
-<script lang="ts" setup></script>
+
+<style lang="less" scoped>
+h3 {
+  font-size: 12px;
+  font-weight: 400;
+  font-family: 'PingFang SC';
+  color: #a9a9a9;
+  padding: 16px;
+}
+
+.demo-2 {
+  margin: 0 16px;
+}
+
+.demo-3 {
+  margin-left: 16px;
+}
+
+.demo-4 {
+  margin-left: 76px;
+}
+</style>
diff --git a/src/divider/demos/mobile.vue b/src/divider/demos/mobile.vue
index c0c012d0..d98b5a52 100644
--- a/src/divider/demos/mobile.vue
+++ b/src/divider/demos/mobile.vue
@@ -6,74 +6,17 @@
     </p>
     <tdesign-demo-block title="01 类型" summary="分割符主要是由直线和文字组成">
       <div style="background: #fff">
-        <h3>直线拉通</h3>
-        <t-divider></t-divider>
-
-        <h3>虚线拉通</h3>
-        <t-divider dashed></t-divider>
-
-        <h3>左右间距</h3>
-        <t-divider class="demo-2"></t-divider>
-
-        <h3>右侧拉通</h3>
-        <t-divider class="demo-3"></t-divider>
-
-        <h3>自定义左侧间距</h3>
-        <t-divider class="demo-4"></t-divider>
-
-        <h3>文字+直线</h3>
-        <t-divider class="demo-5"> 文字信息 </t-divider>
-
-        <h3>纯文字</h3>
-        <t-divider line-color="transparent"> 没有更多了~ </t-divider>
-
-        <h3>垂直分割</h3>
-        <div class="demo-6">
-          <span>文字信息</span>
-          <t-divider layout="vertical"></t-divider>
-          <span>文字信息</span>
-          <t-divider layout="vertical"></t-divider>
-          <span>文字信息</span>
-        </div>
+        <baseDemo />
+        <horizontalDemo />
+        <alignDemo />
+        <verticalDemo />
       </div>
     </tdesign-demo-block>
   </div>
 </template>
-<script lang="ts" setup></script>
-<style lang="less" scoped>
-h3 {
-  font-size: 12px;
-  font-weight: 400;
-  font-family: 'PingFang SC';
-  color: #a9a9a9;
-  padding: 16px;
-}
-
-.demo-2 {
-  margin: 0 16px;
-}
-
-.demo-3 {
-  margin-left: 16px;
-}
-
-.demo-4 {
-  margin-left: 76px;
-}
-
-.demo-5 {
-  margin: 0 16px;
-}
-
-.demo-6 {
-  display: flex;
-  height: 20px;
-  line-height: 20px;
-  align-items: center;
-  margin: 0 16px;
-  font-size: 12px;
-  .t-divider {
-    height: 12px;
-  }
-}
-</style>
+<script lang="ts" setup>
+import baseDemo from './base.vue';
+import alignDemo from './align.vue';
+import horizontalDemo from './horizontal.vue';
+import verticalDemo from './vertical.vue';
+</script>
diff --git a/src/divider/demos/vertical.vue b/src/divider/demos/vertical.vue
index e432df11..f5ddb31b 100644
--- a/src/divider/demos/vertical.vue
+++ b/src/divider/demos/vertical.vue
@@ -1,16 +1,25 @@
 <template>
-  <div class="demo-6">
-    <span>正直信息</span>
-    <t-divider layout="vertical"></t-divider>
-    <span>进取</span>
-    <t-divider layout="vertical"></t-divider>
-    <span>合作</span>
-    <t-divider layout="vertical"></t-divider>
-    <span>创新</span>
+  <div>
+    <h3>垂直分割</h3>
+    <div class="demo-6">
+      <span>文字信息</span>
+      <t-divider layout="vertical"></t-divider>
+      <span>文字信息</span>
+      <t-divider layout="vertical"></t-divider>
+      <span>文字信息</span>
+    </div>
   </div>
 </template>
-<script lang="ts" setup></script>
+
 <style lang="less" scoped>
+h3 {
+  font-size: 12px;
+  font-weight: 400;
+  font-family: 'PingFang SC';
+  color: #a9a9a9;
+  padding: 16px;
+}
+
 .demo-6 {
   display: flex;
   height: 20px;
diff --git a/src/grid/demos/badge.vue b/src/grid/demos/badge.vue
index 93cdd08e..7d8e3a06 100644
--- a/src/grid/demos/badge.vue
+++ b/src/grid/demos/badge.vue
@@ -1,22 +1,23 @@
 <template>
-  <div>
+  <div class="grid-demo">
     <t-grid>
       <t-grid-item text="标题文字" :image="imgUrl" :badge-props="{ dot: true }" />
       <t-grid-item text="标题文字" :image="imgUrl" :badge-props="{ count: 3 }" />
       <t-grid-item text="标题五字内" :image="imgUrl" :badge-props="{ count: 'NEW' }" />
-      <t-grid-item text="标题五字内" :image="imgUrl" :badge-props="{ count: '...' }" />
+      <t-grid-item text="标题五字内" :image="imgUrl" :badge-props="{ count: '···' }" />
     </t-grid>
   </div>
 </template>
 
-<script lang="ts">
-import { defineComponent } from 'vue';
-
-export default defineComponent({
-  setup() {
-    return {
-      imgUrl: 'https://tdesign.gtimg.com/mobile/%E5%9B%BE%E7%89%87.png',
-    };
-  },
-});
+<script lang="ts" setup>
+const imgUrl = 'https://tdesign.gtimg.com/mobile/%E5%9B%BE%E7%89%87.png';
 </script>
+<style scoped lang="less">
+.grid-demo {
+  margin: 0 16px 8px;
+
+  &.short-width {
+    margin: 0 26px 8px;
+  }
+}
+</style>
diff --git a/src/grid/demos/base.vue b/src/grid/demos/base.vue
index 0865a0db..f0deada1 100644
--- a/src/grid/demos/base.vue
+++ b/src/grid/demos/base.vue
@@ -4,7 +4,7 @@
       <t-grid-item text="标题文字" :image="imgUrl" />
       <t-grid-item text="标题文字" :image="imgUrl" />
       <t-grid-item text="标题文字" :image="imgUrl" />
-      <t-grid-item text="最多四字" :image="imgUrl" />
+      <t-grid-item text="标题五字内" :image="imgUrl" />
     </t-grid>
   </div>
   <div class="grid-demo">
@@ -34,16 +34,8 @@
   </div>
 </template>
 
-<script lang="ts">
-import { defineComponent } from 'vue';
-
-export default defineComponent({
-  setup() {
-    return {
-      imgUrl: 'https://tdesign.gtimg.com/mobile/%E5%9B%BE%E7%89%87.png',
-    };
-  },
-});
+<script lang="ts" setup>
+const imgUrl = 'https://tdesign.gtimg.com/mobile/%E5%9B%BE%E7%89%87.png';
 </script>
 <style scoped lang="less">
 .grid-demo {
diff --git a/src/grid/demos/desc.vue b/src/grid/demos/desc.vue
index 258df487..33dc430d 100644
--- a/src/grid/demos/desc.vue
+++ b/src/grid/demos/desc.vue
@@ -1,21 +1,27 @@
 <template>
-  <div>
+  <div class="grid-demo">
     <t-grid :column="3">
       <t-grid-item text="标题文字" :image="imgUrl" description="说明文字" />
       <t-grid-item text="标题文字" :image="imgUrl" description="说明文字" />
       <t-grid-item text="标题最多六字" :image="imgUrl" description="说明最多六字" />
     </t-grid>
   </div>
+  <div class="grid-demo">
+    <t-grid :column="2">
+      <t-grid-item text="标题文字" layout="horizontal" :image="imgUrl" description="说明文字" />
+      <t-grid-item text="标题文字" layout="horizontal" :image="imgUrl" description="说明文字" />
+    </t-grid>
+  </div>
 </template>
-
-<script lang="ts">
-import { defineComponent } from 'vue';
-
-export default defineComponent({
-  setup() {
-    return {
-      imgUrl: 'https://tdesign.gtimg.com/mobile/%E5%9B%BE%E7%89%87.png',
-    };
-  },
-});
+<script lang="ts" setup>
+const imgUrl = 'https://tdesign.gtimg.com/mobile/%E5%9B%BE%E7%89%87.png';
 </script>
+<style scoped lang="less">
+.grid-demo {
+  margin: 0 16px 8px;
+
+  &.short-width {
+    margin: 0 26px 8px;
+  }
+}
+</style>
diff --git a/src/grid/demos/mobile.vue b/src/grid/demos/mobile.vue
index efc28104..d2ac418c 100644
--- a/src/grid/demos/mobile.vue
+++ b/src/grid/demos/mobile.vue
@@ -3,85 +3,19 @@
     <h1 class="title">Grid 宫格</h1>
     <p class="summary">用于功能入口布局，将页面或特定区域切分成若干等大的区块，形成若干功能入口。</p>
     <tdesign-demo-block title="01 基础宫格" summary=" ">
-      <div class="grid-demo">
-        <t-grid>
-          <t-grid-item text="标题文字" :image="imgUrl" />
-          <t-grid-item text="标题文字" :image="imgUrl" />
-          <t-grid-item text="标题文字" :image="imgUrl" />
-          <t-grid-item text="标题五字内" :image="imgUrl" />
-        </t-grid>
-      </div>
-      <div class="grid-demo">
-        <t-grid :column="5">
-          <t-grid-item text="标题文字" :image="imgUrl" />
-          <t-grid-item text="标题文字" :image="imgUrl" />
-          <t-grid-item text="标题文字" :image="imgUrl" />
-          <t-grid-item text="标题文字" :image="imgUrl" />
-          <t-grid-item text="最多四字" :image="imgUrl" />
-        </t-grid>
-      </div>
-      <div class="grid-demo">
-        <t-grid :column="3">
-          <t-grid-item text="标题文字" :image="imgUrl" />
-          <t-grid-item text="标题文字" :image="imgUrl" />
-          <t-grid-item text="标题最多六字" :image="imgUrl" />
-        </t-grid>
-      </div>
-      <div class="grid-demo short-width">
-        <t-grid :column="5">
-          <t-grid-item text="标题文字" :image="imgUrl" />
-          <t-grid-item text="标题文字" :image="imgUrl" />
-          <t-grid-item text="标题文字" :image="imgUrl" />
-          <t-grid-item text="标题文字" :image="imgUrl" />
-          <t-grid-item text="标题文字" :image="imgUrl" />
-        </t-grid>
-      </div>
+      <baseDemo />
     </tdesign-demo-block>
     <tdesign-demo-block title="02 带说明宫格" summary=" ">
-      <div class="grid-demo">
-        <t-grid :column="3">
-          <t-grid-item text="标题文字" :image="imgUrl" description="说明文字" />
-          <t-grid-item text="标题文字" :image="imgUrl" description="说明文字" />
-          <t-grid-item text="标题最多六字" :image="imgUrl" description="说明最多六字" />
-        </t-grid>
-      </div>
-      <div class="grid-demo">
-        <t-grid :column="2">
-          <t-grid-item text="标题文字" layout="horizontal" :image="imgUrl" description="说明文字" />
-          <t-grid-item text="标题文字" layout="horizontal" :image="imgUrl" description="说明文字" />
-        </t-grid>
-      </div>
+      <descDemo />
     </tdesign-demo-block>
     <tdesign-demo-block title="03 带徽标宫格" summary=" ">
-      <div class="grid-demo">
-        <t-grid>
-          <t-grid-item text="标题文字" :image="imgUrl" :badge-props="{ dot: true }" />
-          <t-grid-item text="标题文字" :image="imgUrl" :badge-props="{ count: 3 }" />
-          <t-grid-item text="标题五字内" :image="imgUrl" :badge-props="{ count: 'NEW' }" />
-          <t-grid-item text="标题五字内" :image="imgUrl" :badge-props="{ count: '···' }" />
-        </t-grid>
-      </div>
+      <badgeDemo />
     </tdesign-demo-block>
   </div>
 </template>
 
-<script lang="ts">
-import { defineComponent } from 'vue';
-
-export default defineComponent({
-  setup() {
-    return {
-      imgUrl: 'https://tdesign.gtimg.com/mobile/%E5%9B%BE%E7%89%87.png',
-    };
-  },
-});
+<script lang="ts" setup>
+import baseDemo from './base.vue';
+import descDemo from './desc.vue';
+import badgeDemo from './badge.vue';
 </script>
-<style scoped lang="less">
-.grid-demo {
-  margin: 0 16px 8px;
-
-  &.short-width {
-    margin: 0 26px 8px;
-  }
-}
-</style>
diff --git a/src/grid/grid-item.vue b/src/grid/grid-item.vue
index a1214ffc..22c555f6 100644
--- a/src/grid/grid-item.vue
+++ b/src/grid/grid-item.vue
@@ -62,7 +62,7 @@ export default defineComponent({
       const borderStyle = {};
       if (border.value) {
         if (typeof border.value !== 'boolean') {
-          const { color, width, style } = border;
+          const { color, width, style } = border.value;
           return {
             borderColor: color,
             borderWidth: width,
@@ -74,8 +74,8 @@ export default defineComponent({
       const style = {
         flexBasis: percent,
         flexDirection: isHorz ? ('row' as const) : ('column' as const),
-        paddingLeft: gutter.value ? `${gutter}px` : 0,
-        paddingRight: gutter.value ? `${gutter}px` : 0,
+        paddingLeft: gutter.value ? `${gutter.value}px` : 0,
+        paddingRight: gutter.value ? `${gutter.value}px` : 0,
         alignItems: 'center',
         justifyContent: 'center',
         textAlign: ['center', 'left'].includes(align.value) ? align.value : 'center',


Test patch:
diff --git a/src/button/__test__/__snapshots__/index.test.jsx.snap b/src/button/__test__/__snapshots__/index.test.jsx.snap
new file mode 100644
index 00000000..31a42d12
--- /dev/null
+++ b/src/button/__test__/__snapshots__/index.test.jsx.snap
@@ -0,0 +1,34 @@
+// Vitest Snapshot v1
+
+exports[`button > button-group > button group render 1`] = `
+<div
+  class="t-button-group t-button-group--default"
+>
+  
+  <button
+    aria-disabled="false"
+    class="t-button t-size-m t-button--base t-button--default t-button--shape-rectangle"
+    role="button"
+  >
+    <!---->
+    <span
+      class="t-button__text"
+    >
+      tdesign-mobile-vue
+    </span>
+  </button>
+  <button
+    aria-disabled="false"
+    class="t-button t-size-m t-button--base t-button--default t-button--shape-rectangle"
+    role="button"
+  >
+    <!---->
+    <span
+      class="t-button__text"
+    >
+      tdesign-mobile-vue
+    </span>
+  </button>
+  
+</div>
+`;
diff --git a/src/button/__test__/index.test.jsx b/src/button/__test__/index.test.jsx
index 6a57509f..6c617fff 100644
--- a/src/button/__test__/index.test.jsx
+++ b/src/button/__test__/index.test.jsx
@@ -1,142 +1,252 @@
-import { h } from 'vue';
+import { h, ref } from 'vue';
 import { mount } from '@vue/test-utils';
-import { describe, it, expect } from 'vitest';
+import { describe, it, expect, vi } from 'vitest';
 import { AppIcon as TIconApp, LoadingIcon } from 'tdesign-icons-vue-next';
 import Button from '../button.vue';
 import ButtonGroup from '../../button-group/button-group.vue';
-import { vi } from 'vitest';
 
+const prefix = 't'
+const name = `${prefix}-button`;
+const SIZE_CLASSNAMES = {
+  small: `${prefix}-size-s`,
+  medium: `${prefix}-size-m`,
+  large: `${prefix}-size-l`,
+};
 const TEXT = 'tdesign-mobile-vue';
 const iconFunc = () => h(TIconApp);
 
-describe('Button.vue', () => {
-  it('create render', async () => {
-    const wrapper = mount(() => <Button>{TEXT}</Button>);
-    expect(wrapper.classes()).toContain('t-button');
-    expect(wrapper.text()).toBe(TEXT);
-  });
-
-  it('content render', async () => {
-    const wrapper = mount(() => <Button content={TEXT}></Button>);
-    expect(wrapper.classes()).toContain('t-button');
-    expect(wrapper.text()).toBe(TEXT);
-  });
-
-  it('theme render', async () => {
-    const wrapper1 = mount(() => <Button theme="default">{TEXT}</Button>);
-    expect(wrapper1.classes()).toContain(`t-button--default`);
-    const wrapper2 = mount(() => <Button theme="primary">{TEXT}</Button>);
-    expect(wrapper2.classes()).toContain(`t-button--primary`);
-    const wrapper3 = mount(() => <Button theme="danger">{TEXT}</Button>);
-    expect(wrapper3.classes()).toContain(`t-button--danger`);
-  });
-
-  it('shape render', async () => {
-    const wrapper1 = mount(() => <Button shape="rectangle">{TEXT}</Button>);
-    expect(wrapper1.classes()).toContain(`t-button--shape-rectangle`);
-    const wrapper2 = mount(() => <Button shape="square">{TEXT}</Button>);
-    expect(wrapper2.classes()).toContain(`t-button--shape-square`);
-    const wrapper3 = mount(() => <Button shape="round">{TEXT}</Button>);
-    expect(wrapper3.classes()).toContain(`t-button--shape-round`);
-    const wrapper4 = mount(() => <Button shape="circle">{TEXT}</Button>);
-    expect(wrapper4.classes()).toContain(`t-button--shape-circle`);
-  });
-
-  it('size render', async () => {
-    const wrapper1 = mount(() => <Button size="small">{TEXT}</Button>);
-    expect(wrapper1.classes()).toContain(`t-size-s`);
-    const wrapper2 = mount(() => <Button size="medium">{TEXT}</Button>);
-    expect(wrapper2.classes()).toContain(`t-size-m`);
-    const wrapper3 = mount(() => <Button size="large">{TEXT}</Button>);
-    expect(wrapper3.classes()).toContain(`t-size-l`);
-  });
-
-  it('variant render', async () => {
-    const wrapper1 = mount(() => <Button variant="base">{TEXT}</Button>);
-    expect(wrapper1.classes()).toContain(`t-button--base`);
-    const wrapper2 = mount(() => <Button variant="outline">{TEXT}</Button>);
-    expect(wrapper2.classes()).toContain(`t-button--outline`);
-    const wrapper3 = mount(() => <Button variant="text">{TEXT}</Button>);
-    expect(wrapper3.classes()).toContain(`t-button--text`);
-  });
-
-  it('disabled render', async () => {
-    const wrapper = mount(() => <Button disabled>{TEXT}</Button>);
-    expect(wrapper.classes()).toContain('t-is-disabled');
-  });
-
-  it('loading render', async () => {
-    const wrapper = mount(() => <Button loading>{TEXT}</Button>);
-    expect(wrapper.classes()).toContain('t-is-loading');
-    expect(wrapper.findComponent(LoadingIcon).exists()).toBeTruthy();
-  });
-
-  it('loading icon render', async () => {
-    const wrapper = mount(() => (
-      <Button icon={iconFunc} loading>
-        {TEXT}
-      </Button>
-    ));
-    expect(wrapper.classes()).toContain('t-is-loading');
-    expect(wrapper.findComponent(LoadingIcon).exists()).toBeTruthy();
-    expect(wrapper.findComponent(TIconApp).exists()).toBeFalsy();
-  });
-
-  it('ghost render', async () => {
-    const wrapper = mount(() => <Button ghost>{TEXT}</Button>);
-    expect(wrapper.classes()).toContain('t-button--ghost');
-  });
-
-  it('icon render', async () => {
-    const wrapper = mount(() => <Button icon={iconFunc}>{TEXT}</Button>);
-    expect(wrapper.findComponent(TIconApp).exists()).toBeTruthy();
-  });
-
-  it('block render', async () => {
-    const wrapper = mount(() => <Button block>{TEXT}</Button>);
-    expect(wrapper.classes()).toContain('t-is-block');
-  });
-
-  it('click emit', async () => {
-    const onClick = vi.fn();
-    const wrapper = mount(() => <Button onClick={onClick}>{TEXT}</Button>);
-    const button = wrapper.find('button');
-    await button.trigger('click');
-    expect(onClick).toBeCalled();
-  });
-
-  it('loading click', async () => {
-    const onClick = vi.fn();
-    const wrapper = mount(() => (
-      <Button loading onClick={onClick}>
-        {TEXT}
-      </Button>
-    ));
-    const button = wrapper.find('button');
-    await button.trigger('click');
-    expect(onClick).not.toBeCalled();
-  });
-
-  it('disabled click', async () => {
-    const onClick = vi.fn();
-    const wrapper = mount(() => (
-      <Button disabled onClick={onClick}>
-        {TEXT}
-      </Button>
-    ));
-    const button = wrapper.find('button');
-    await button.trigger('click');
-    expect(onClick).not.toBeCalled();
-  });
-
-  it('button group render', async () => {
-    const wrapper = mount(() => (
-      <ButtonGroup>
-        <Button>{TEXT}</Button>
-        <Button>{TEXT}</Button>
-      </ButtonGroup>
-    ));
-    expect(wrapper.classes()).toContain('t-button-group');
-    expect(wrapper.findAllComponents(Button).length).toBe(2);
+describe('button', () => {
+  describe('props', () => {
+    it(': theme', async () => {
+      const wrapper = mount(Button, {
+        props: {
+          theme: '',
+          content: TEXT
+        }
+      })
+      // theme = ''
+      const $button = wrapper.findComponent(Button);
+      ['default', 'primary', 'danger'].map(item => {
+        expect($button.classes().includes(`${name}--${item}`)).toBeFalsy();
+      })
+      expect(wrapper.text()).toBe(TEXT);
+      const theme = 'danger';
+      await wrapper.setProps({
+        theme,
+      });
+      // theme = 'danger'
+      expect($button.classes()).toContain(`${name}--${theme}`);
+    });
+
+    it(': content', async () => {
+      const wrapper = mount(Button, {
+        props: {
+          content: TEXT
+        }
+      })
+      const $button = wrapper.findComponent(Button);
+      expect($button.text()).toBe(TEXT);
+
+      const newContent = 'new content';
+      await wrapper.setProps({
+        content: newContent
+      });
+      expect($button.text()).toBe(newContent);
+    });
+
+    it(': shape', async () => {
+      const wrapper = mount(Button, {
+        props: {
+          shape: '',
+          content: TEXT
+        }
+      })
+      // shape = ''
+      const $button = wrapper.findComponent(Button);
+      ['rectangle', 'square', 'round', 'circle'].map(item => {
+        expect($button.classes().includes(`${name}--shape-${item}`)).toBeFalsy();
+      })
+      expect(wrapper.text()).toBe(TEXT);
+      const shape = 'square';
+      await wrapper.setProps({
+        shape,
+      });
+      // shape = 'square'
+      expect($button.classes()).toContain(`${name}--shape-${shape}`);
+    });
+
+    it(': size', async () => {
+      const wrapper = mount(Button, {
+        props: {
+          size: '',
+          content: TEXT
+        }
+      })
+      // size = ''
+      const $button = wrapper.findComponent(Button);
+      ['small', 'medium', 'large'].map(item => {
+        expect($button.classes().includes(`${SIZE_CLASSNAMES[item]}`)).toBeFalsy();
+      });
+      expect(wrapper.text()).toBe(TEXT);
+      const size = 'small';
+      await wrapper.setProps({
+        size,
+      });
+      // size = 'small'
+      expect($button.classes()).toContain(`${SIZE_CLASSNAMES[size]}`);
+    });
+
+    it(': variant', async () => {
+      const wrapper = mount(Button, {
+        props: {
+          variant: '',
+          content: TEXT
+        }
+      })
+      // variant = ''
+      const $button = wrapper.findComponent(Button);
+      ['base', 'outline', 'text'].map(item => {
+        expect($button.classes().includes(`${name}--${item}`)).toBeFalsy();
+      })
+      expect(wrapper.text()).toBe(TEXT);
+      const variant = 'outline';
+      await wrapper.setProps({
+        variant,
+      });
+      // variant = 'outline'
+      expect($button.classes()).toContain(`${name}--${variant}`);
+    });
+
+    it(': disabled', async () => {
+      const onClick = vi.fn();
+      const disabled = true;
+      const wrapper = mount(Button, {
+        props: {
+          disabled,
+          content: TEXT,
+          onClick,
+        },
+      })
+      const $button = wrapper.findComponent(Button);
+      // disabled = true, 不会触发 click
+      expect($button.classes()).toContain('t-is-disabled');
+      await $button.trigger('click');
+      expect(onClick).not.toBeCalled();
+
+      // disabled = false, 可以触发 click
+      await wrapper.setProps({
+        disabled: false,
+      });
+      await $button.trigger('click');
+      expect(onClick).toBeCalled();
+    });
+
+    it(': loading', async () => {
+      const loading = true;
+      const onClick = vi.fn();
+      const wrapper = mount(Button, {
+        props: {
+          loading,
+          content: TEXT,
+          onClick,
+        },
+      })
+      const $button = wrapper.findComponent(Button);
+
+      // loading = true，不触发 click
+      expect($button.classes()).toContain('t-is-loading');
+      expect($button.findComponent(LoadingIcon).exists()).toBeTruthy();
+      await $button.trigger('click');
+      expect(onClick).not.toBeCalled();
+      // loading = false
+      await wrapper.setProps({
+        loading: false,
+      });
+      expect($button.findComponent(LoadingIcon).exists()).toBeFalsy();
+      await $button.trigger('click');
+      expect(onClick).toBeCalled();
+    });
+
+    it(': icon', async () => {
+      const wrapper = mount(Button, {
+        props: {
+          loading: true,
+          icon: iconFunc,
+          content: TEXT,
+        },
+      })
+      const $button = wrapper.findComponent(Button);
+      expect($button.classes()).toContain('t-is-loading');
+      expect($button.findComponent(LoadingIcon).exists()).toBeTruthy();
+      expect($button.findComponent(TIconApp).exists()).toBeFalsy();
+    });
+
+    it(': ghost', async () => {
+      const ghost = true;
+      const wrapper = mount(Button, {
+        props: {
+          ghost,
+          content: TEXT,
+        },
+      })
+      const $button = wrapper.findComponent(Button);
+
+      // ghost = true
+      expect($button.classes().includes(`${name}--ghost`)).toBeTruthy();
+      // ghost = false
+      await wrapper.setProps({
+        ghost: false,
+      });
+      expect($button.classes().includes(`${name}--ghost`)).toBeFalsy();
+    });
+
+    it(': block', async () => {
+      const block = true;
+      const wrapper = mount(Button, {
+        props: {
+          block,
+          content: TEXT,
+        },
+      })
+      const $button = wrapper.findComponent(Button);
+
+      // block = true
+      expect($button.classes().includes(`${prefix}-is-block`)).toBeTruthy();
+      // block = false
+      await wrapper.setProps({
+        block: false,
+      });
+      expect($button.classes().includes(`${prefix}-is-block`)).toBeFalsy();
+    });
+  });
+
+  describe('button-group', () => {
+    it('button group render', async () => {
+      const items = [
+        {
+          content: TEXT,
+        },
+        {
+          content: TEXT,
+        },
+      ]
+      const wrapper = mount({
+        setup() {
+          return () => (
+            <ButtonGroup>
+              {{
+                default: items.map((item, index) => {
+                  return <Button content={item.content} />
+                })
+              }}
+            </ButtonGroup>
+          )
+        }
+      });
+      expect(wrapper.element).toMatchSnapshot();
+      const $buttonGroup = wrapper.findComponent(ButtonGroup)
+      expect($buttonGroup.exists()).toBeTruthy();
+      expect(wrapper.findAllComponents(Button).length).toEqual(items.length);
+    });
   });
 });
diff --git a/src/divider/__test__/__snapshots__/demo.test.jsx.snap b/src/divider/__test__/__snapshots__/demo.test.jsx.snap
index ed4a2dbe..a12cedba 100644
--- a/src/divider/__test__/__snapshots__/demo.test.jsx.snap
+++ b/src/divider/__test__/__snapshots__/demo.test.jsx.snap
@@ -2,123 +2,130 @@
 
 exports[`Divider > Divider alignVue demo works fine 1`] = `
 <div
-  class="demo-6"
+  data-v-7ac68ae7=""
 >
-  <span>
-    正直
-  </span>
-  <div
-    class="t-divider t-divider--hairline t-divider--content-left"
-    role="separator"
+  <h3
+    data-v-7ac68ae7=""
   >
-    
-    TDesign
-    
-  </div>
-  <span>
-    进取
-  </span>
+    文字+直线
+  </h3>
   <div
-    class="t-divider t-divider--hairline t-divider--content-center"
+    class="t-divider t-divider--hairline t-divider--content-center demo-5"
+    data-v-7ac68ae7=""
     role="separator"
   >
     
-    TDesign
+     文字信息 
     
   </div>
-  <span>
-    合作
-  </span>
+  <h3
+    data-v-7ac68ae7=""
+  >
+    纯文字
+  </h3>
   <div
-    class="t-divider t-divider--hairline t-divider--content-right"
+    class="t-divider t-divider--hairline t-divider--content-center"
+    data-v-7ac68ae7=""
     role="separator"
+    style="border-color: transparent;"
   >
     
-    TDesign
+     没有更多了~ 
     
   </div>
-  <span>
-    创新
-  </span>
 </div>
 `;
 
 exports[`Divider > Divider baseVue demo works fine 1`] = `
 <div
-  class="demo-6"
+  data-v-589c0842=""
 >
-  <h3>
+  <h3
+    data-v-589c0842=""
+  >
     直线拉通
   </h3>
   <div
     class="t-divider t-divider--hairline"
+    data-v-589c0842=""
     role="separator"
   >
     <!---->
   </div>
-  <h3>
-    直线拉通
+  <h3
+    data-v-589c0842=""
+  >
+    虚线拉通
   </h3>
+  <div
+    class="t-divider t-divider--hairline t-divider--dashed"
+    data-v-589c0842=""
+    role="separator"
+  >
+    <!---->
+  </div>
 </div>
 `;
 
 exports[`Divider > Divider horizontalVue demo works fine 1`] = `
 <div
-  class="demo-6"
+  data-v-63a80f32=""
 >
-  <span>
-    正直
-  </span>
+  <h3
+    data-v-63a80f32=""
+  >
+    左右间距
+  </h3>
   <div
-    class="t-divider t-divider--hairline"
+    class="t-divider t-divider--hairline demo-2"
+    data-v-63a80f32=""
     role="separator"
   >
     <!---->
   </div>
-  <span>
-    进取
-  </span>
+  <h3
+    data-v-63a80f32=""
+  >
+    右侧拉通
+  </h3>
   <div
-    class="t-divider t-divider--hairline"
+    class="t-divider t-divider--hairline demo-3"
+    data-v-63a80f32=""
     role="separator"
   >
     <!---->
   </div>
-  <span>
-    合作
-  </span>
+  <h3
+    data-v-63a80f32=""
+  >
+    自定义左侧间距
+  </h3>
   <div
-    class="t-divider t-divider--hairline"
+    class="t-divider t-divider--hairline demo-4"
+    data-v-63a80f32=""
     role="separator"
   >
     <!---->
   </div>
-  <span>
-    创新
-  </span>
 </div>
 `;
 
 exports[`Divider > Divider mobileVue demo works fine 1`] = `
 <div
   class="tdesign-mobile-demo"
-  data-v-bf2b60a0=""
 >
   <h1
     class="title"
-    data-v-bf2b60a0=""
   >
     Divider 分割符
   </h1>
   <p
     class="summary"
-    data-v-bf2b60a0=""
   >
      分割线是一个呈线状的轻量化组件，起到分割、组织、细化的作用，用于有逻辑的组织元素内容和页面结构。 
   </p>
   <div
     class="tdesign-mobile-demo-block"
-    data-v-bf2b60a0=""
   >
     <h2
       class="tdesign-mobile-demo-block__title"
@@ -132,136 +139,151 @@ exports[`Divider > Divider mobileVue demo works fine 1`] = `
     </p>
     
     <div
-      data-v-bf2b60a0=""
       style="background: rgb(255, 255, 255);"
     >
-      <h3
-        data-v-bf2b60a0=""
-      >
-        直线拉通
-      </h3>
       <div
-        class="t-divider t-divider--hairline"
-        data-v-bf2b60a0=""
-        role="separator"
-      >
-        <!---->
-      </div>
-      <h3
-        data-v-bf2b60a0=""
+        data-v-589c0842=""
       >
-        虚线拉通
-      </h3>
-      <div
-        class="t-divider t-divider--hairline t-divider--dashed"
-        data-v-bf2b60a0=""
-        role="separator"
-      >
-        <!---->
-      </div>
-      <h3
-        data-v-bf2b60a0=""
-      >
-        左右间距
-      </h3>
-      <div
-        class="t-divider t-divider--hairline demo-2"
-        data-v-bf2b60a0=""
-        role="separator"
-      >
-        <!---->
-      </div>
-      <h3
-        data-v-bf2b60a0=""
-      >
-        右侧拉通
-      </h3>
-      <div
-        class="t-divider t-divider--hairline demo-3"
-        data-v-bf2b60a0=""
-        role="separator"
-      >
-        <!---->
-      </div>
-      <h3
-        data-v-bf2b60a0=""
-      >
-        自定义左侧间距
-      </h3>
-      <div
-        class="t-divider t-divider--hairline demo-4"
-        data-v-bf2b60a0=""
-        role="separator"
-      >
-        <!---->
-      </div>
-      <h3
-        data-v-bf2b60a0=""
-      >
-        文字+直线
-      </h3>
-      <div
-        class="t-divider t-divider--hairline t-divider--content-center demo-5"
-        data-v-bf2b60a0=""
-        role="separator"
-      >
-        
-         文字信息 
-        
+        <h3
+          data-v-589c0842=""
+        >
+          直线拉通
+        </h3>
+        <div
+          class="t-divider t-divider--hairline"
+          data-v-589c0842=""
+          role="separator"
+        >
+          <!---->
+        </div>
+        <h3
+          data-v-589c0842=""
+        >
+          虚线拉通
+        </h3>
+        <div
+          class="t-divider t-divider--hairline t-divider--dashed"
+          data-v-589c0842=""
+          role="separator"
+        >
+          <!---->
+        </div>
       </div>
-      <h3
-        data-v-bf2b60a0=""
-      >
-        纯文字
-      </h3>
       <div
-        class="t-divider t-divider--hairline t-divider--content-center"
-        data-v-bf2b60a0=""
-        role="separator"
-        style="border-color: transparent;"
+        data-v-63a80f32=""
       >
-        
-         没有更多了~ 
-        
+        <h3
+          data-v-63a80f32=""
+        >
+          左右间距
+        </h3>
+        <div
+          class="t-divider t-divider--hairline demo-2"
+          data-v-63a80f32=""
+          role="separator"
+        >
+          <!---->
+        </div>
+        <h3
+          data-v-63a80f32=""
+        >
+          右侧拉通
+        </h3>
+        <div
+          class="t-divider t-divider--hairline demo-3"
+          data-v-63a80f32=""
+          role="separator"
+        >
+          <!---->
+        </div>
+        <h3
+          data-v-63a80f32=""
+        >
+          自定义左侧间距
+        </h3>
+        <div
+          class="t-divider t-divider--hairline demo-4"
+          data-v-63a80f32=""
+          role="separator"
+        >
+          <!---->
+        </div>
       </div>
-      <h3
-        data-v-bf2b60a0=""
-      >
-        垂直分割
-      </h3>
       <div
-        class="demo-6"
-        data-v-bf2b60a0=""
+        data-v-7ac68ae7=""
       >
-        <span
-          data-v-bf2b60a0=""
+        <h3
+          data-v-7ac68ae7=""
         >
-          文字信息
-        </span>
+          文字+直线
+        </h3>
         <div
-          class="t-divider t-divider--hairline t-divider-vertical"
-          data-v-bf2b60a0=""
+          class="t-divider t-divider--hairline t-divider--content-center demo-5"
+          data-v-7ac68ae7=""
           role="separator"
         >
-          <!---->
+          
+           文字信息 
+          
         </div>
-        <span
-          data-v-bf2b60a0=""
+        <h3
+          data-v-7ac68ae7=""
         >
-          文字信息
-        </span>
+          纯文字
+        </h3>
         <div
-          class="t-divider t-divider--hairline t-divider-vertical"
-          data-v-bf2b60a0=""
+          class="t-divider t-divider--hairline t-divider--content-center"
+          data-v-7ac68ae7=""
           role="separator"
+          style="border-color: transparent;"
         >
-          <!---->
+          
+           没有更多了~ 
+          
         </div>
-        <span
-          data-v-bf2b60a0=""
+      </div>
+      <div
+        data-v-0851d1f8=""
+      >
+        <h3
+          data-v-0851d1f8=""
         >
-          文字信息
-        </span>
+          垂直分割
+        </h3>
+        <div
+          class="demo-6"
+          data-v-0851d1f8=""
+        >
+          <span
+            data-v-0851d1f8=""
+          >
+            文字信息
+          </span>
+          <div
+            class="t-divider t-divider--hairline t-divider-vertical"
+            data-v-0851d1f8=""
+            role="separator"
+          >
+            <!---->
+          </div>
+          <span
+            data-v-0851d1f8=""
+          >
+            文字信息
+          </span>
+          <div
+            class="t-divider t-divider--hairline t-divider-vertical"
+            data-v-0851d1f8=""
+            role="separator"
+          >
+            <!---->
+          </div>
+          <span
+            data-v-0851d1f8=""
+          >
+            文字信息
+          </span>
+        </div>
       </div>
     </div>
     
@@ -271,49 +293,46 @@ exports[`Divider > Divider mobileVue demo works fine 1`] = `
 
 exports[`Divider > Divider verticalVue demo works fine 1`] = `
 <div
-  class="demo-6"
   data-v-0851d1f8=""
 >
-  <span
+  <h3
     data-v-0851d1f8=""
   >
-    正直信息
-  </span>
-  <div
-    class="t-divider t-divider--hairline t-divider-vertical"
-    data-v-0851d1f8=""
-    role="separator"
-  >
-    <!---->
-  </div>
-  <span
-    data-v-0851d1f8=""
-  >
-    进取
-  </span>
-  <div
-    class="t-divider t-divider--hairline t-divider-vertical"
-    data-v-0851d1f8=""
-    role="separator"
-  >
-    <!---->
-  </div>
-  <span
-    data-v-0851d1f8=""
-  >
-    合作
-  </span>
+    垂直分割
+  </h3>
   <div
-    class="t-divider t-divider--hairline t-divider-vertical"
+    class="demo-6"
     data-v-0851d1f8=""
-    role="separator"
   >
-    <!---->
+    <span
+      data-v-0851d1f8=""
+    >
+      文字信息
+    </span>
+    <div
+      class="t-divider t-divider--hairline t-divider-vertical"
+      data-v-0851d1f8=""
+      role="separator"
+    >
+      <!---->
+    </div>
+    <span
+      data-v-0851d1f8=""
+    >
+      文字信息
+    </span>
+    <div
+      class="t-divider t-divider--hairline t-divider-vertical"
+      data-v-0851d1f8=""
+      role="separator"
+    >
+      <!---->
+    </div>
+    <span
+      data-v-0851d1f8=""
+    >
+      文字信息
+    </span>
   </div>
-  <span
-    data-v-0851d1f8=""
-  >
-    创新
-  </span>
 </div>
 `;
diff --git a/src/divider/__test__/index.test.jsx b/src/divider/__test__/index.test.jsx
index cf9154ac..004270b5 100644
--- a/src/divider/__test__/index.test.jsx
+++ b/src/divider/__test__/index.test.jsx
@@ -2,48 +2,104 @@ import { mount } from '@vue/test-utils';
 import { describe, it, expect } from 'vitest';
 import Divider from '../divider.vue';
 
+const prefix = 't'
+const name = `${prefix}-divider`;
 const TEXT = 'tdesign-mobile-vue';
 
 describe('divider.vue', async () => {
-  it('create', async () => {
-    const wrapper = mount(Divider);
-    expect(wrapper.classes()).toContain('t-divider');
-  });
+  describe('props', async () => {
+    it(': default', async () => {
+      const wrapper = mount(() => <Divider default={TEXT}></Divider>);
+      expect(wrapper.text()).toBe(TEXT);
+    });
 
-  it('text render', async () => {
-    const wrapper = mount(() => <Divider>{TEXT}</Divider>);
-    expect(wrapper.text()).toBe(TEXT);
-  });
+    it(': dashed', async () => {
+      const wrapper = mount(() => <Divider dashed />);
+      expect(wrapper.classes()).toContain(`${name}--dashed`);
+    });
 
-  it('content render', async () => {
-    const wrapper = mount(() => <Divider content={TEXT}></Divider>);
-    expect(wrapper.text()).toBe(TEXT);
-  });
+    it(': align', async () => {
+      const wrapper = mount(Divider, {
+        props: {
+          align: '',
+          content: TEXT
+        }
+      })
+      const $divider = wrapper.findComponent(Divider);
+      expect($divider.text()).toEqual(TEXT);
 
-  it('default render', async () => {
-    const wrapper = mount(() => <Divider default={TEXT}></Divider>);
-    expect(wrapper.text()).toBe(TEXT);
-  });
+      // align = ''
+      ['left', 'right', 'center'].map(item => {
+        expect($divider.classes().includes(`${name}--content-${item}`)).toBeFalsy();
+      })
 
-  it('dashed render', async () => {
-    const wrapper = mount(() => <Divider dashed />);
-    expect(wrapper.classes()).toContain('t-divider--dashed');
-  });
+      const align = 'left';
+      await wrapper.setProps({
+        align,
+      });
+      // align = 'left'
+      expect($divider.classes()).toContain(`${name}--content-${align}`);
+    });
 
-  it('align render', async () => {
-    const wrapper1 = mount(() => <Divider align="center">{TEXT}</Divider>);
-    expect(wrapper1.classes()).toContain(`t-divider--content-center`);
-    const wrapper2 = mount(() => <Divider align="right">{TEXT}</Divider>);
-    expect(wrapper2.classes()).toContain(`t-divider--content-right`);
-  });
+    it(': layout', async () => {
+      const wrapper = mount(Divider, {
+        props: {
+          layout: '',
+          content: TEXT
+        }
+      })
+      const $divider = wrapper.findComponent(Divider);
+      expect($divider.text()).toEqual(TEXT);
+
+      // layout = ''
+      ['horizontal', 'vertical'].map(item => {
+        expect($divider.classes().includes(`${name}-${item}`)).toBeFalsy();
+      })
+
+      const layout = 'vertical';
+      await wrapper.setProps({
+        layout,
+      });
+      // layout = 'vertical'
+      expect($divider.classes()).toContain(`${name}-${layout}`);
+    });
 
-  it('vertical render', async () => {
-    const wrapper = mount(() => <Divider layout="vertical" />);
-    expect(wrapper.classes()).toContain('t-divider-vertical');
+    it(': lineColor', async () => {
+      const wrapper = mount(() => <Divider lineColor="red" />);
+      expect(getComputedStyle(wrapper.element, null).borderColor).toBe('red');
+    });
   });
+  describe('slot', async () => {
+    it(': content', async () => {
+      const wrapper = mount({
+        setup() {
+          return () => (
+            <Divider>
+              {{
+                content: TEXT
+              }}
+            </Divider>
+          )
+        }
+      });
+      const $divider = wrapper.findComponent(Divider);
+      expect($divider.text()).toEqual(TEXT);
+    })
 
-  it('lineColor render', async () => {
-    const wrapper = mount(() => <Divider lineColor="red" />);
-    expect(getComputedStyle(wrapper.element, null).borderColor).toBe('red');
+    it(': default', async () => {
+      const wrapper = mount({
+        setup() {
+          return () => (
+            <Divider>
+              {{
+                default: TEXT
+              }}
+            </Divider>
+          )
+        }
+      });
+      const $divider = wrapper.findComponent(Divider);
+      expect($divider.text()).toEqual(TEXT);
+    })
   });
 });
diff --git a/src/grid/__test__/__snapshots__/demo.test.jsx.snap b/src/grid/__test__/__snapshots__/demo.test.jsx.snap
index 17bd8acd..bcdfabe9 100644
--- a/src/grid/__test__/__snapshots__/demo.test.jsx.snap
+++ b/src/grid/__test__/__snapshots__/demo.test.jsx.snap
@@ -1,13 +1,18 @@
 // Vitest Snapshot v1
 
 exports[`Grid > Grid badgeVue demo works fine 1`] = `
-<div>
+<div
+  class="grid-demo"
+  data-v-26858cd4=""
+>
   <div
     class="t-grid"
+    data-v-26858cd4=""
   >
     
     <div
       class="t-grid-item"
+      data-v-26858cd4=""
       style="flex-basis: 25%; flex-direction: column; padding-left: 0px; padding-right: 0px; align-items: center; justify-content: center; text-align: center;"
     >
       <div
@@ -51,6 +56,7 @@ exports[`Grid > Grid badgeVue demo works fine 1`] = `
     </div>
     <div
       class="t-grid-item"
+      data-v-26858cd4=""
       style="flex-basis: 25%; flex-direction: column; padding-left: 0px; padding-right: 0px; align-items: center; justify-content: center; text-align: center;"
     >
       <div
@@ -94,6 +100,7 @@ exports[`Grid > Grid badgeVue demo works fine 1`] = `
     </div>
     <div
       class="t-grid-item"
+      data-v-26858cd4=""
       style="flex-basis: 25%; flex-direction: column; padding-left: 0px; padding-right: 0px; align-items: center; justify-content: center; text-align: center;"
     >
       <div
@@ -137,6 +144,7 @@ exports[`Grid > Grid badgeVue demo works fine 1`] = `
     </div>
     <div
       class="t-grid-item"
+      data-v-26858cd4=""
       style="flex-basis: 25%; flex-direction: column; padding-left: 0px; padding-right: 0px; align-items: center; justify-content: center; text-align: center;"
     >
       <div
@@ -148,7 +156,7 @@ exports[`Grid > Grid badgeVue demo works fine 1`] = `
           <div
             class="t-badge__inner t-badge--has-children t-badge--medium t-badge--circle"
           >
-            ...
+            ···
           </div>
           
           
@@ -320,7 +328,7 @@ exports[`Grid > Grid baseVue demo works fine 1`] = `
             class="t-grid-item__title"
             style="padding-top: 8px; margin-bottom: 4px;"
           >
-            最多四字
+            标题五字内
           </div>
           <div
             class="t-grid-item__description"
@@ -802,132 +810,219 @@ exports[`Grid > Grid baseVue demo works fine 1`] = `
 `;
 
 exports[`Grid > Grid descVue demo works fine 1`] = `
-<div>
+<div
+  data-v-app=""
+>
+  
   <div
-    class="t-grid"
+    class="grid-demo"
+    data-v-f7d95d20=""
   >
-    
     <div
-      class="t-grid-item"
-      style="flex-basis: 33.333333333333336%; flex-direction: column; padding-left: 0px; padding-right: 0px; align-items: center; justify-content: center; text-align: center;"
+      class="t-grid"
+      data-v-f7d95d20=""
     >
+      
       <div
-        class="t-grid-item__image-box"
-      >
-        
-        <img
-          class="t-grid-item__image"
-          src="https://tdesign.gtimg.com/mobile/%E5%9B%BE%E7%89%87.png"
-          style="width: 48px; height: 48px;"
-        />
-        
-      </div>
-      <div
-        class="t-grid-item__text"
-        style="padding-left: 0px;"
+        class="t-grid-item"
+        data-v-f7d95d20=""
+        style="flex-basis: 33.333333333333336%; flex-direction: column; padding-left: 0px; padding-right: 0px; align-items: center; justify-content: center; text-align: center;"
       >
         <div
-          class="t-grid-item__title"
-          style="padding-top: 8px; margin-bottom: 4px;"
+          class="t-grid-item__image-box"
         >
-          标题文字
+          
+          <img
+            class="t-grid-item__image"
+            src="https://tdesign.gtimg.com/mobile/%E5%9B%BE%E7%89%87.png"
+            style="width: 48px; height: 48px;"
+          />
+          
         </div>
         <div
-          class="t-grid-item__description"
+          class="t-grid-item__text"
+          style="padding-left: 0px;"
         >
-          说明文字
+          <div
+            class="t-grid-item__title"
+            style="padding-top: 8px; margin-bottom: 4px;"
+          >
+            标题文字
+          </div>
+          <div
+            class="t-grid-item__description"
+          >
+            说明文字
+          </div>
         </div>
       </div>
-    </div>
-    <div
-      class="t-grid-item"
-      style="flex-basis: 33.333333333333336%; flex-direction: column; padding-left: 0px; padding-right: 0px; align-items: center; justify-content: center; text-align: center;"
-    >
       <div
-        class="t-grid-item__image-box"
+        class="t-grid-item"
+        data-v-f7d95d20=""
+        style="flex-basis: 33.333333333333336%; flex-direction: column; padding-left: 0px; padding-right: 0px; align-items: center; justify-content: center; text-align: center;"
       >
-        
-        <img
-          class="t-grid-item__image"
-          src="https://tdesign.gtimg.com/mobile/%E5%9B%BE%E7%89%87.png"
-          style="width: 48px; height: 48px;"
-        />
-        
+        <div
+          class="t-grid-item__image-box"
+        >
+          
+          <img
+            class="t-grid-item__image"
+            src="https://tdesign.gtimg.com/mobile/%E5%9B%BE%E7%89%87.png"
+            style="width: 48px; height: 48px;"
+          />
+          
+        </div>
+        <div
+          class="t-grid-item__text"
+          style="padding-left: 0px;"
+        >
+          <div
+            class="t-grid-item__title"
+            style="padding-top: 8px; margin-bottom: 4px;"
+          >
+            标题文字
+          </div>
+          <div
+            class="t-grid-item__description"
+          >
+            说明文字
+          </div>
+        </div>
       </div>
       <div
-        class="t-grid-item__text"
-        style="padding-left: 0px;"
+        class="t-grid-item"
+        data-v-f7d95d20=""
+        style="flex-basis: 33.333333333333336%; flex-direction: column; padding-left: 0px; padding-right: 0px; align-items: center; justify-content: center; text-align: center;"
       >
         <div
-          class="t-grid-item__title"
-          style="padding-top: 8px; margin-bottom: 4px;"
+          class="t-grid-item__image-box"
         >
-          标题文字
+          
+          <img
+            class="t-grid-item__image"
+            src="https://tdesign.gtimg.com/mobile/%E5%9B%BE%E7%89%87.png"
+            style="width: 48px; height: 48px;"
+          />
+          
         </div>
         <div
-          class="t-grid-item__description"
+          class="t-grid-item__text"
+          style="padding-left: 0px;"
         >
-          说明文字
+          <div
+            class="t-grid-item__title"
+            style="padding-top: 8px; margin-bottom: 4px;"
+          >
+            标题最多六字
+          </div>
+          <div
+            class="t-grid-item__description"
+          >
+            说明最多六字
+          </div>
         </div>
       </div>
+      
     </div>
+  </div>
+  <div
+    class="grid-demo"
+    data-v-f7d95d20=""
+  >
     <div
-      class="t-grid-item"
-      style="flex-basis: 33.333333333333336%; flex-direction: column; padding-left: 0px; padding-right: 0px; align-items: center; justify-content: center; text-align: center;"
+      class="t-grid"
+      data-v-f7d95d20=""
     >
+      
       <div
-        class="t-grid-item__image-box"
+        class="t-grid-item"
+        data-v-f7d95d20=""
+        style="flex-basis: 50%; flex-direction: row; padding-left: 0px; padding-right: 0px; align-items: center; justify-content: center; text-align: center;"
       >
-        
-        <img
-          class="t-grid-item__image"
-          src="https://tdesign.gtimg.com/mobile/%E5%9B%BE%E7%89%87.png"
-          style="width: 48px; height: 48px;"
-        />
-        
+        <div
+          class="t-grid-item__image-box"
+        >
+          
+          <img
+            class="t-grid-item__image"
+            src="https://tdesign.gtimg.com/mobile/%E5%9B%BE%E7%89%87.png"
+            style="width: 48px; height: 48px;"
+          />
+          
+        </div>
+        <div
+          class="t-grid-item__text"
+          style="padding-left: 12px;"
+        >
+          <div
+            class="t-grid-item__title"
+            style="padding-top: 0px; margin-bottom: 4px;"
+          >
+            标题文字
+          </div>
+          <div
+            class="t-grid-item__description"
+          >
+            说明文字
+          </div>
+        </div>
       </div>
       <div
-        class="t-grid-item__text"
-        style="padding-left: 0px;"
+        class="t-grid-item"
+        data-v-f7d95d20=""
+        style="flex-basis: 50%; flex-direction: row; padding-left: 0px; padding-right: 0px; align-items: center; justify-content: center; text-align: center;"
       >
         <div
-          class="t-grid-item__title"
-          style="padding-top: 8px; margin-bottom: 4px;"
+          class="t-grid-item__image-box"
         >
-          标题最多六字
+          
+          <img
+            class="t-grid-item__image"
+            src="https://tdesign.gtimg.com/mobile/%E5%9B%BE%E7%89%87.png"
+            style="width: 48px; height: 48px;"
+          />
+          
         </div>
         <div
-          class="t-grid-item__description"
+          class="t-grid-item__text"
+          style="padding-left: 12px;"
         >
-          说明最多六字
+          <div
+            class="t-grid-item__title"
+            style="padding-top: 0px; margin-bottom: 4px;"
+          >
+            标题文字
+          </div>
+          <div
+            class="t-grid-item__description"
+          >
+            说明文字
+          </div>
         </div>
       </div>
+      
     </div>
-    
   </div>
+  
 </div>
 `;
 
 exports[`Grid > Grid mobileVue demo works fine 1`] = `
 <div
   class="tdesign-mobile-demo"
-  data-v-2417457e=""
 >
   <h1
     class="title"
-    data-v-2417457e=""
   >
     Grid 宫格
   </h1>
   <p
     class="summary"
-    data-v-2417457e=""
   >
     用于功能入口布局，将页面或特定区域切分成若干等大的区块，形成若干功能入口。
   </p>
   <div
     class="tdesign-mobile-demo-block"
-    data-v-2417457e=""
   >
     <h2
       class="tdesign-mobile-demo-block__title"
@@ -940,18 +1035,19 @@ exports[`Grid > Grid mobileVue demo works fine 1`] = `
        
     </p>
     
+    
     <div
       class="grid-demo"
-      data-v-2417457e=""
+      data-v-3e578ca0=""
     >
       <div
         class="t-grid"
-        data-v-2417457e=""
+        data-v-3e578ca0=""
       >
         
         <div
           class="t-grid-item"
-          data-v-2417457e=""
+          data-v-3e578ca0=""
           style="flex-basis: 25%; flex-direction: column; padding-left: 0px; padding-right: 0px; align-items: center; justify-content: center; text-align: center;"
         >
           <div
@@ -984,7 +1080,7 @@ exports[`Grid > Grid mobileVue demo works fine 1`] = `
         </div>
         <div
           class="t-grid-item"
-          data-v-2417457e=""
+          data-v-3e578ca0=""
           style="flex-basis: 25%; flex-direction: column; padding-left: 0px; padding-right: 0px; align-items: center; justify-content: center; text-align: center;"
         >
           <div
@@ -1017,7 +1113,7 @@ exports[`Grid > Grid mobileVue demo works fine 1`] = `
         </div>
         <div
           class="t-grid-item"
-          data-v-2417457e=""
+          data-v-3e578ca0=""
           style="flex-basis: 25%; flex-direction: column; padding-left: 0px; padding-right: 0px; align-items: center; justify-content: center; text-align: center;"
         >
           <div
@@ -1050,7 +1146,7 @@ exports[`Grid > Grid mobileVue demo works fine 1`] = `
         </div>
         <div
           class="t-grid-item"
-          data-v-2417457e=""
+          data-v-3e578ca0=""
           style="flex-basis: 25%; flex-direction: column; padding-left: 0px; padding-right: 0px; align-items: center; justify-content: center; text-align: center;"
         >
           <div
@@ -1086,16 +1182,16 @@ exports[`Grid > Grid mobileVue demo works fine 1`] = `
     </div>
     <div
       class="grid-demo"
-      data-v-2417457e=""
+      data-v-3e578ca0=""
     >
       <div
         class="t-grid"
-        data-v-2417457e=""
+        data-v-3e578ca0=""
       >
         
         <div
           class="t-grid-item"
-          data-v-2417457e=""
+          data-v-3e578ca0=""
           style="flex-basis: 20%; flex-direction: column; padding-left: 0px; padding-right: 0px; align-items: center; justify-content: center; text-align: center;"
         >
           <div
@@ -1128,7 +1224,7 @@ exports[`Grid > Grid mobileVue demo works fine 1`] = `
         </div>
         <div
           class="t-grid-item"
-          data-v-2417457e=""
+          data-v-3e578ca0=""
           style="flex-basis: 20%; flex-direction: column; padding-left: 0px; padding-right: 0px; align-items: center; justify-content: center; text-align: center;"
         >
           <div
@@ -1161,7 +1257,7 @@ exports[`Grid > Grid mobileVue demo works fine 1`] = `
         </div>
         <div
           class="t-grid-item"
-          data-v-2417457e=""
+          data-v-3e578ca0=""
           style="flex-basis: 20%; flex-direction: column; padding-left: 0px; padding-right: 0px; align-items: center; justify-content: center; text-align: center;"
         >
           <div
@@ -1194,7 +1290,7 @@ exports[`Grid > Grid mobileVue demo works fine 1`] = `
         </div>
         <div
           class="t-grid-item"
-          data-v-2417457e=""
+          data-v-3e578ca0=""
           style="flex-basis: 20%; flex-direction: column; padding-left: 0px; padding-right: 0px; align-items: center; justify-content: center; text-align: center;"
         >
           <div
@@ -1227,7 +1323,7 @@ exports[`Grid > Grid mobileVue demo works fine 1`] = `
         </div>
         <div
           class="t-grid-item"
-          data-v-2417457e=""
+          data-v-3e578ca0=""
           style="flex-basis: 20%; flex-direction: column; padding-left: 0px; padding-right: 0px; align-items: center; justify-content: center; text-align: center;"
         >
           <div
@@ -1263,16 +1359,16 @@ exports[`Grid > Grid mobileVue demo works fine 1`] = `
     </div>
     <div
       class="grid-demo"
-      data-v-2417457e=""
+      data-v-3e578ca0=""
     >
       <div
         class="t-grid"
-        data-v-2417457e=""
+        data-v-3e578ca0=""
       >
         
         <div
           class="t-grid-item"
-          data-v-2417457e=""
+          data-v-3e578ca0=""
           style="flex-basis: 33.333333333333336%; flex-direction: column; padding-left: 0px; padding-right: 0px; align-items: center; justify-content: center; text-align: center;"
         >
           <div
@@ -1305,7 +1401,7 @@ exports[`Grid > Grid mobileVue demo works fine 1`] = `
         </div>
         <div
           class="t-grid-item"
-          data-v-2417457e=""
+          data-v-3e578ca0=""
           style="flex-basis: 33.333333333333336%; flex-direction: column; padding-left: 0px; padding-right: 0px; align-items: center; justify-content: center; text-align: center;"
         >
           <div
@@ -1338,7 +1434,7 @@ exports[`Grid > Grid mobileVue demo works fine 1`] = `
         </div>
         <div
           class="t-grid-item"
-          data-v-2417457e=""
+          data-v-3e578ca0=""
           style="flex-basis: 33.333333333333336%; flex-direction: column; padding-left: 0px; padding-right: 0px; align-items: center; justify-content: center; text-align: center;"
         >
           <div
@@ -1374,16 +1470,16 @@ exports[`Grid > Grid mobileVue demo works fine 1`] = `
     </div>
     <div
       class="grid-demo short-width"
-      data-v-2417457e=""
+      data-v-3e578ca0=""
     >
       <div
         class="t-grid"
-        data-v-2417457e=""
+        data-v-3e578ca0=""
       >
         
         <div
           class="t-grid-item"
-          data-v-2417457e=""
+          data-v-3e578ca0=""
           style="flex-basis: 20%; flex-direction: column; padding-left: 0px; padding-right: 0px; align-items: center; justify-content: center; text-align: center;"
         >
           <div
@@ -1416,7 +1512,7 @@ exports[`Grid > Grid mobileVue demo works fine 1`] = `
         </div>
         <div
           class="t-grid-item"
-          data-v-2417457e=""
+          data-v-3e578ca0=""
           style="flex-basis: 20%; flex-direction: column; padding-left: 0px; padding-right: 0px; align-items: center; justify-content: center; text-align: center;"
         >
           <div
@@ -1449,7 +1545,7 @@ exports[`Grid > Grid mobileVue demo works fine 1`] = `
         </div>
         <div
           class="t-grid-item"
-          data-v-2417457e=""
+          data-v-3e578ca0=""
           style="flex-basis: 20%; flex-direction: column; padding-left: 0px; padding-right: 0px; align-items: center; justify-content: center; text-align: center;"
         >
           <div
@@ -1482,7 +1578,7 @@ exports[`Grid > Grid mobileVue demo works fine 1`] = `
         </div>
         <div
           class="t-grid-item"
-          data-v-2417457e=""
+          data-v-3e578ca0=""
           style="flex-basis: 20%; flex-direction: column; padding-left: 0px; padding-right: 0px; align-items: center; justify-content: center; text-align: center;"
         >
           <div
@@ -1515,7 +1611,7 @@ exports[`Grid > Grid mobileVue demo works fine 1`] = `
         </div>
         <div
           class="t-grid-item"
-          data-v-2417457e=""
+          data-v-3e578ca0=""
           style="flex-basis: 20%; flex-direction: column; padding-left: 0px; padding-right: 0px; align-items: center; justify-content: center; text-align: center;"
         >
           <div
@@ -1550,10 +1646,10 @@ exports[`Grid > Grid mobileVue demo works fine 1`] = `
       </div>
     </div>
     
+    
   </div>
   <div
     class="tdesign-mobile-demo-block"
-    data-v-2417457e=""
   >
     <h2
       class="tdesign-mobile-demo-block__title"
@@ -1566,18 +1662,19 @@ exports[`Grid > Grid mobileVue demo works fine 1`] = `
        
     </p>
     
+    
     <div
       class="grid-demo"
-      data-v-2417457e=""
+      data-v-f7d95d20=""
     >
       <div
         class="t-grid"
-        data-v-2417457e=""
+        data-v-f7d95d20=""
       >
         
         <div
           class="t-grid-item"
-          data-v-2417457e=""
+          data-v-f7d95d20=""
           style="flex-basis: 33.333333333333336%; flex-direction: column; padding-left: 0px; padding-right: 0px; align-items: center; justify-content: center; text-align: center;"
         >
           <div
@@ -1610,7 +1707,7 @@ exports[`Grid > Grid mobileVue demo works fine 1`] = `
         </div>
         <div
           class="t-grid-item"
-          data-v-2417457e=""
+          data-v-f7d95d20=""
           style="flex-basis: 33.333333333333336%; flex-direction: column; padding-left: 0px; padding-right: 0px; align-items: center; justify-content: center; text-align: center;"
         >
           <div
@@ -1643,7 +1740,7 @@ exports[`Grid > Grid mobileVue demo works fine 1`] = `
         </div>
         <div
           class="t-grid-item"
-          data-v-2417457e=""
+          data-v-f7d95d20=""
           style="flex-basis: 33.333333333333336%; flex-direction: column; padding-left: 0px; padding-right: 0px; align-items: center; justify-content: center; text-align: center;"
         >
           <div
@@ -1679,16 +1776,16 @@ exports[`Grid > Grid mobileVue demo works fine 1`] = `
     </div>
     <div
       class="grid-demo"
-      data-v-2417457e=""
+      data-v-f7d95d20=""
     >
       <div
         class="t-grid"
-        data-v-2417457e=""
+        data-v-f7d95d20=""
       >
         
         <div
           class="t-grid-item"
-          data-v-2417457e=""
+          data-v-f7d95d20=""
           style="flex-basis: 50%; flex-direction: row; padding-left: 0px; padding-right: 0px; align-items: center; justify-content: center; text-align: center;"
         >
           <div
@@ -1721,7 +1818,7 @@ exports[`Grid > Grid mobileVue demo works fine 1`] = `
         </div>
         <div
           class="t-grid-item"
-          data-v-2417457e=""
+          data-v-f7d95d20=""
           style="flex-basis: 50%; flex-direction: row; padding-left: 0px; padding-right: 0px; align-items: center; justify-content: center; text-align: center;"
         >
           <div
@@ -1756,10 +1853,10 @@ exports[`Grid > Grid mobileVue demo works fine 1`] = `
       </div>
     </div>
     
+    
   </div>
   <div
     class="tdesign-mobile-demo-block"
-    data-v-2417457e=""
   >
     <h2
       class="tdesign-mobile-demo-block__title"
@@ -1774,16 +1871,16 @@ exports[`Grid > Grid mobileVue demo works fine 1`] = `
     
     <div
       class="grid-demo"
-      data-v-2417457e=""
+      data-v-26858cd4=""
     >
       <div
         class="t-grid"
-        data-v-2417457e=""
+        data-v-26858cd4=""
       >
         
         <div
           class="t-grid-item"
-          data-v-2417457e=""
+          data-v-26858cd4=""
           style="flex-basis: 25%; flex-direction: column; padding-left: 0px; padding-right: 0px; align-items: center; justify-content: center; text-align: center;"
         >
           <div
@@ -1827,7 +1924,7 @@ exports[`Grid > Grid mobileVue demo works fine 1`] = `
         </div>
         <div
           class="t-grid-item"
-          data-v-2417457e=""
+          data-v-26858cd4=""
           style="flex-basis: 25%; flex-direction: column; padding-left: 0px; padding-right: 0px; align-items: center; justify-content: center; text-align: center;"
         >
           <div
@@ -1871,7 +1968,7 @@ exports[`Grid > Grid mobileVue demo works fine 1`] = `
         </div>
         <div
           class="t-grid-item"
-          data-v-2417457e=""
+          data-v-26858cd4=""
           style="flex-basis: 25%; flex-direction: column; padding-left: 0px; padding-right: 0px; align-items: center; justify-content: center; text-align: center;"
         >
           <div
@@ -1915,7 +2012,7 @@ exports[`Grid > Grid mobileVue demo works fine 1`] = `
         </div>
         <div
           class="t-grid-item"
-          data-v-2417457e=""
+          data-v-26858cd4=""
           style="flex-basis: 25%; flex-direction: column; padding-left: 0px; padding-right: 0px; align-items: center; justify-content: center; text-align: center;"
         >
           <div
diff --git a/src/grid/__test__/index.test.jsx b/src/grid/__test__/index.test.jsx
index 9b7a75d8..4fa96c89 100644
--- a/src/grid/__test__/index.test.jsx
+++ b/src/grid/__test__/index.test.jsx
@@ -4,60 +4,151 @@ import Grid from '../grid.vue';
 import GridItem from '../grid-item.vue';
 import Badge from '../../badge/badge.vue';
 
+const prefix = 't'
+const name = `${prefix}-grid`;
 const imgUrl = 'https://tdesign.gtimg.com/mobile/%E5%9B%BE%E7%89%87.png';
+const items = [
+  {
+    text: "标题",
+    image: imgUrl
+  },
+  {
+    text: "标题",
+    image: imgUrl
+  }
+];
+const items2 = [
+  {
+    text: "标题",
+    description: "内容 description",
+    image: imgUrl
+  },
+  {
+    text: "标题",
+    description: "内容 description",
+    image: imgUrl
+  }
+];
+describe('grid', () => {
+  describe('props', () => {
+    it(': align ', async () => {
+      const align = 'left';
+      const wrapper = mount({
+        setup() {
+          return () => (
+            <Grid align={align}>
+              {{
+                default: items.map((item, index) => {
+                  return <GridItem text={item.text + index} image={item.image} />
+                })
+              }}
+            </Grid>
+          )
+        }
+      });
+      expect(wrapper.findComponent(Grid).exists()).toBeTruthy();
+      expect(wrapper.findAllComponents(GridItem).length).toEqual(items.length);
+      const $grid = wrapper.find(`.${name}`);
+      const $gridItems = wrapper.findAll(`.${name}-item`);
+      // align = 'left (自定义)
+      // border = false, column = 4, gutter = 0 (默认)
+      $gridItems.map(item => {
+        expect(item.attributes('class').includes(`${name}-item--bordered`)).toBeFalsy(); // border
+        expect(item.element.style.textAlign).toBe('left') // align
+        expect(item.element.style.flexBasis).toBe(`${100 / 4}%`); // column
+        expect(item.element.style.paddingLeft).toBe(`${0}px`) // gutter
+        expect(item.element.style.paddingRight).toBe(`${0}px`) // gutter
+      })
+    })
 
-describe('Grid.vue', () => {
-  it('create', async () => {
-    const wrapper = mount(() => (
-      <Grid>
-        <GridItem></GridItem>
-        <GridItem></GridItem>
-        <GridItem></GridItem>
-      </Grid>
-    ));
-    expect(wrapper.classes()).toContain('t-grid');
-    expect(wrapper.findAll('.t-grid-item').length).toBe(3);
-  });
+    it(': border ', async () => {
+      const border = {
+        color: 'red',
+        width: '2px',
+        style: 'dashed'
+      };
+      const wrapper = mount({
+        setup() {
+          return () => (
+            <Grid border={border}>
+              {{
+                default: items.map((item, index) => {
+                  return <GridItem text={item.text + index} image={item.image} />
+                })
+              }}
+            </Grid>
+          )
+        }
+      });
+      const $gridItems = wrapper.findAll(`.${name}-item`);
+      // border: object
+      $gridItems.map(item => {
+        expect(item.attributes('class').includes(`${name}-item--bordered`)).toBeTruthy(); // border
+        expect(item.element.style.borderColor).toBe(border.color)
+        expect(item.element.style.borderWidth).toBe(border.width);
+      })
+    })
 
-  it('align render', async () => {
-    const wrapper = mount(() => (
-      <Grid align="left">
-        <GridItem></GridItem>
-        <GridItem></GridItem>
-        <GridItem></GridItem>
-      </Grid>
-    ));
-    const item = wrapper.find('.t-grid-item');
-    expect(item.element.style.textAlign).toBe('left');
-  });
+    it(': column && gutter ', async () => {
+      const column = 5;
+      const gutter = 10;
+      const wrapper = mount({
+        setup() {
+          return () => (
+            <Grid column={column} gutter={gutter}>
+              {{
+                default: items.map((item, index) => {
+                  return <GridItem text={item.text + index} image={item.image} />
+                })
+              }}
+            </Grid>
+          )
+        }
+      });
+      expect(wrapper.findComponent(Grid).exists()).toBeTruthy();
+      expect(wrapper.findAllComponents(GridItem).length).toEqual(items.length);
+      const $grid = wrapper.find(`.${name}`);
+      const $gridItems = wrapper.findAll(`.${name}-item`);
+      // column = 4, gutter = 10 (自定义)
+      $gridItems.map(item => {
+        expect(item.element.style.textAlign).toBe('center') // align 默认为 center
+        expect(item.element.style.flexBasis).toBe(`${100 / column}%`); // column
+        expect(item.element.style.paddingLeft).toBe(`${gutter}px`) // gutter
+        expect(item.element.style.paddingRight).toBe(`${gutter}px`) // gutter
+      })
+    })
+  })
+});
 
-  it('border render', async () => {
-    const wrapper = mount(() => (
-      <Grid border>
-        <GridItem></GridItem>
-        <GridItem></GridItem>
-        <GridItem></GridItem>
-      </Grid>
-    ));
-    const borderItem = wrapper.findAll('.t-grid-item--bordered');
-    expect(borderItem.length).toBe(3);
-  });
+describe('grid-item', () => {
+  describe('props', () => {
+    it(': text && image && description', async () => {
+      const wrapper = mount({
+        setup() {
+          return () => (
+            <Grid>
+              {{
+                default: items2.map((item, index) => {
+                  return <GridItem text={item.text + index} description={item.description + index} image={item.image} />
+                })
+              }}
+            </Grid>
+          )
+        }
+      });
 
-  it('column render', async () => {
-    const wrapper = mount(() => (
-      <Grid column={1}>
-        <GridItem></GridItem>
-        <GridItem></GridItem>
-        <GridItem></GridItem>
-      </Grid>
-    ));
-    const item = wrapper.find('.t-grid-item');
-    expect(item.element.style.flexBasis).toBe('100%');
-  });
-});
+      const $gridItems = wrapper.findAll(`.${name}-item`);
+      $gridItems.map((item, index) => {
+        expect(item.find(`.${name}-item__title`).text()).toEqual(items2[index].text + index);
+        expect(item.find(`.${name}-item__description`).text()).toEqual(items2[index].description + index);
+        const $img = item.find(`.${name}-item__image-box img`);
+        expect($img.exists()).toBeTruthy();
+        expect($img.attributes('src')).toBe(imgUrl);
+      })
+    })
+  })
 
-describe('GridItem.vue', () => {
-  it('badgeProps render', async () => {
+  it(': badgeProps', async () => {
     const wrapper = mount(() => (
       <Grid>
         <GridItem badgeProps={{ count: 1 }}></GridItem>
@@ -69,43 +160,7 @@ describe('GridItem.vue', () => {
     expect(badge.text()).toBe('1');
   });
 
-  it('text render', async () => {
-    const wrapper = mount(() => (
-      <Grid>
-        <GridItem text="文字信息"></GridItem>
-      </Grid>
-    ));
-    const item = wrapper.find('.t-grid-item');
-    const title = item.find('.t-grid-item__title');
-    expect(title.exists()).toBeTruthy();
-    expect(title.text()).toBe('文字信息');
-  });
-
-  it('description render', async () => {
-    const wrapper = mount(() => (
-      <Grid>
-        <GridItem description="描述信息"></GridItem>
-      </Grid>
-    ));
-    const item = wrapper.find('.t-grid-item');
-    const desc = item.find('.t-grid-item__description');
-    expect(desc.exists()).toBeTruthy();
-    expect(desc.text()).toBe('描述信息');
-  });
-
-  it('image render', async () => {
-    const wrapper = mount(() => (
-      <Grid>
-        <GridItem image={imgUrl}></GridItem>
-      </Grid>
-    ));
-    const item = wrapper.find('.t-grid-item');
-    const img = item.find('.t-grid-item__image-box img');
-    expect(img.exists()).toBeTruthy();
-    expect(img.attributes('src')).toBe(imgUrl);
-  });
-
-  it('layout render', async () => {
+  it(': layout', async () => {
     const wrapper = mount(() => (
       <Grid>
         <GridItem text="标题文字" image={imgUrl} description="描述" layout="horizontal"></GridItem>