mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-06 03:57:59 +08:00
add GoodsAction component
This commit is contained in:
parent
415af2b40b
commit
8986da5ba6
88
docs/examples-docs/goods-action.md
Normal file
88
docs/examples-docs/goods-action.md
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
<script>
|
||||||
|
import { Toast } from 'packages';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
methods: {
|
||||||
|
onClickMiniBtn() {
|
||||||
|
Toast('点击图标');
|
||||||
|
},
|
||||||
|
onClickBigBtn() {
|
||||||
|
Toast('点击按钮');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.demo-goods-action {
|
||||||
|
.van-goods-action {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
## GoodsAction 商品操作组件
|
||||||
|
|
||||||
|
### 使用指南
|
||||||
|
``` javascript
|
||||||
|
import {
|
||||||
|
GoodsAction,
|
||||||
|
GoodsActionBigBtn,
|
||||||
|
GoodsActionMiniBtn
|
||||||
|
} from 'vant';
|
||||||
|
|
||||||
|
Vue.component(GoodsAction.name, GoodsAction);
|
||||||
|
Vue.component(GoodsActionBigBtn.name, GoodsActionBigBtn);
|
||||||
|
Vue.component(GoodsActionMiniBtn.name, GoodsActionMiniBtn);
|
||||||
|
```
|
||||||
|
|
||||||
|
### 代码演示
|
||||||
|
|
||||||
|
:::demo
|
||||||
|
```html
|
||||||
|
<van-goods-action>
|
||||||
|
<van-goods-action-mini-btn icon="chat" @click="onClickMiniBtn">
|
||||||
|
客服
|
||||||
|
</van-goods-action-mini-btn>
|
||||||
|
<van-goods-action-mini-btn icon="cart" @click="onClickMiniBtn">
|
||||||
|
购物车
|
||||||
|
</van-goods-action-mini-btn>
|
||||||
|
<van-goods-action-big-btn @click="onClickBigBtn">
|
||||||
|
加入购物车
|
||||||
|
</van-goods-action-big-btn>
|
||||||
|
<van-goods-action-big-btn @click="onClickBigBtn" primary>
|
||||||
|
立即购买
|
||||||
|
</van-goods-action-big-btn>
|
||||||
|
</van-goods-action>
|
||||||
|
```
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
export default {
|
||||||
|
methods: {
|
||||||
|
onClickMiniBtn() {
|
||||||
|
Toast('点击图标');
|
||||||
|
},
|
||||||
|
onClickBigBtn() {
|
||||||
|
Toast('点击按钮');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
### API
|
||||||
|
|
||||||
|
#### GoodsActionMiniBtn
|
||||||
|
|
||||||
|
| 参数 | 说明 | 类型 | 默认值 | 可选值 |
|
||||||
|
|-----------|-----------|-----------|-------------|-------------|
|
||||||
|
| icon | 图标 | `String` | - | Icon 组件支持的所有图标 |
|
||||||
|
| iconClass | 图标额外类名 | `String` | `''` | - |
|
||||||
|
| url | 跳转链接 | `String` | `javascript:;` | - |
|
||||||
|
|
||||||
|
#### GoodsActionBigBtn
|
||||||
|
|
||||||
|
| 参数 | 说明 | 类型 | 默认值 | 可选值 |
|
||||||
|
|-----------|-----------|-----------|-------------|-------------|
|
||||||
|
| url | 跳转链接 | `String` | `javascript:;` | - |
|
||||||
|
| primary | 是否主行动按钮,主行动按钮默认为红色 | `Boolean` | `false` | - |
|
@ -189,6 +189,10 @@ module.exports = {
|
|||||||
"path": "/express-way",
|
"path": "/express-way",
|
||||||
"title": "ExpressWay 配送方式"
|
"title": "ExpressWay 配送方式"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "/goods-action",
|
||||||
|
"title": "GoodsAction 商品操作"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "/invalid-goods",
|
"path": "/invalid-goods",
|
||||||
"title": "InvalidGoods 不可用商品列表"
|
"title": "InvalidGoods 不可用商品列表"
|
||||||
|
32
packages/goods-action-big-btn/index.vue
Normal file
32
packages/goods-action-big-btn/index.vue
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<template>
|
||||||
|
<van-button
|
||||||
|
tag="a"
|
||||||
|
:href="url"
|
||||||
|
class="van-goods-action__big-btn"
|
||||||
|
:type="primary ? 'primary' : 'default'"
|
||||||
|
@click="$emit('click', $event)"
|
||||||
|
bottomAction
|
||||||
|
>
|
||||||
|
<slot></slot>
|
||||||
|
</van-button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Button from '../button';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'van-goods-action-big-btn',
|
||||||
|
|
||||||
|
components: {
|
||||||
|
[Button.name]: Button
|
||||||
|
},
|
||||||
|
|
||||||
|
props: {
|
||||||
|
primary: Boolean,
|
||||||
|
url: {
|
||||||
|
type: String,
|
||||||
|
default: 'javascript:;'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
30
packages/goods-action-mini-btn/index.vue
Normal file
30
packages/goods-action-mini-btn/index.vue
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<template>
|
||||||
|
<a :href="url" class="van-goods-action__mini-btn" @click="$emit('click', $event);">
|
||||||
|
<van-icon :class="['van-goods-action__mini-btn-icon', iconClass]" :name="icon" />
|
||||||
|
<slot></slot>
|
||||||
|
</a>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Icon from '../icon';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'van-goods-action-mini-btn',
|
||||||
|
|
||||||
|
components: {
|
||||||
|
[Icon.name]: Icon
|
||||||
|
},
|
||||||
|
|
||||||
|
props: {
|
||||||
|
icon: String,
|
||||||
|
iconClass: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
url: {
|
||||||
|
type: String,
|
||||||
|
default: 'javascript:;'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
11
packages/goods-action/index.vue
Normal file
11
packages/goods-action/index.vue
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<template>
|
||||||
|
<div class="van-goods-action">
|
||||||
|
<slot></slot>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'van-goods-action'
|
||||||
|
};
|
||||||
|
</script>
|
@ -13,6 +13,9 @@ import DatetimePicker from './datetime-picker';
|
|||||||
import Dialog from './dialog';
|
import Dialog from './dialog';
|
||||||
import ExpressWay from './express-way';
|
import ExpressWay from './express-way';
|
||||||
import Field from './field';
|
import Field from './field';
|
||||||
|
import GoodsAction from './goods-action';
|
||||||
|
import GoodsActionBigBtn from './goods-action-big-btn';
|
||||||
|
import GoodsActionMiniBtn from './goods-action-mini-btn';
|
||||||
import Icon from './icon';
|
import Icon from './icon';
|
||||||
import ImagePreview from './image-preview';
|
import ImagePreview from './image-preview';
|
||||||
import InvalidGoods from './invalid-goods';
|
import InvalidGoods from './invalid-goods';
|
||||||
@ -59,6 +62,9 @@ const components = [
|
|||||||
DatetimePicker,
|
DatetimePicker,
|
||||||
ExpressWay,
|
ExpressWay,
|
||||||
Field,
|
Field,
|
||||||
|
GoodsAction,
|
||||||
|
GoodsActionBigBtn,
|
||||||
|
GoodsActionMiniBtn,
|
||||||
Icon,
|
Icon,
|
||||||
InvalidGoods,
|
InvalidGoods,
|
||||||
Loading,
|
Loading,
|
||||||
@ -117,6 +123,9 @@ export {
|
|||||||
Dialog,
|
Dialog,
|
||||||
ExpressWay,
|
ExpressWay,
|
||||||
Field,
|
Field,
|
||||||
|
GoodsAction,
|
||||||
|
GoodsActionBigBtn,
|
||||||
|
GoodsActionMiniBtn,
|
||||||
Icon,
|
Icon,
|
||||||
ImagePreview,
|
ImagePreview,
|
||||||
InvalidGoods,
|
InvalidGoods,
|
||||||
|
@ -103,6 +103,7 @@
|
|||||||
line-height: 50px;
|
line-height: 50px;
|
||||||
border: 0;
|
border: 0;
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
|
font-size: 16px;
|
||||||
color: $bottom-action-button-default-color;
|
color: $bottom-action-button-default-color;
|
||||||
background-color: $bottom-action-button-default-background-color;
|
background-color: $bottom-action-button-default-background-color;
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ $c-yellow-light: #fcff00;
|
|||||||
$c-orange: #f60;
|
$c-orange: #f60;
|
||||||
$c-orange-dark: #f15a0c;
|
$c-orange-dark: #f15a0c;
|
||||||
$c-blue: #38f;
|
$c-blue: #38f;
|
||||||
|
$c-active: #e8e8e8;
|
||||||
|
|
||||||
$c-background: #f8f8f8;
|
$c-background: #f8f8f8;
|
||||||
|
|
||||||
|
40
packages/vant-css/src/goods-action.css
Normal file
40
packages/vant-css/src/goods-action.css
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
@import './common/var.css';
|
||||||
|
|
||||||
|
.van-goods-action {
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
display: flex;
|
||||||
|
position: fixed;
|
||||||
|
|
||||||
|
&__mini-btn {
|
||||||
|
color: #666;
|
||||||
|
display: flex;
|
||||||
|
height: 50px;
|
||||||
|
font-size: 10px;
|
||||||
|
min-width: 15%;
|
||||||
|
text-align: center;
|
||||||
|
background-color: #fff;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
@mixin border-retina (top, right), #cacaca;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
&::after {
|
||||||
|
border-right-width: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
background-color: $c-active;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__mini-btn-icon {
|
||||||
|
font-size: 20px;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
}
|
@ -36,3 +36,4 @@
|
|||||||
@import './pay-order.css';
|
@import './pay-order.css';
|
||||||
@import './order-goods.css';
|
@import './order-goods.css';
|
||||||
@import './invalid-goods.css';
|
@import './invalid-goods.css';
|
||||||
|
@import './goods-action.css';
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
@import "./mixins/ellipsis";
|
@import "./mixins/ellipsis.css";
|
||||||
|
|
||||||
$van-invalid-goods-photo-size: 90px;
|
$van-invalid-goods-photo-size: 90px;
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
@import "./mixins/border_retina";
|
@import "./mixins/border_retina.css";
|
||||||
|
|
||||||
.van-order-goods {
|
.van-order-goods {
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
|
37
test/unit/components/goods-action.vue
Normal file
37
test/unit/components/goods-action.vue
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
<template>
|
||||||
|
<van-goods-action>
|
||||||
|
<van-goods-action-mini-btn icon="chat" @click="onClickMiniBtn">
|
||||||
|
客服
|
||||||
|
</van-goods-action-mini-btn>
|
||||||
|
<van-goods-action-mini-btn icon="cart" url="http://www.youzan.com" @click="onClickMiniBtn">
|
||||||
|
购物车
|
||||||
|
</van-goods-action-mini-btn>
|
||||||
|
<van-goods-action-big-btn @click="onClickBigBtn">
|
||||||
|
加入购物车
|
||||||
|
</van-goods-action-big-btn>
|
||||||
|
<van-goods-action-big-btn @click="onClickBigBtn" primary url="http://www.youzan.com">
|
||||||
|
立即购买
|
||||||
|
</van-goods-action-big-btn>
|
||||||
|
</van-goods-action>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import GoodsAction from 'packages/goods-action';
|
||||||
|
import GoodsActionBigBtn from 'packages/goods-action-big-btn';
|
||||||
|
import GoodsActionMiniBtn from 'packages/goods-action-mini-btn';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
[GoodsAction.name]: GoodsAction,
|
||||||
|
[GoodsActionBigBtn.name]: GoodsActionBigBtn,
|
||||||
|
[GoodsActionMiniBtn.name]: GoodsActionMiniBtn
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
onClickMiniBtn() {
|
||||||
|
},
|
||||||
|
onClickBigBtn() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
47
test/unit/specs/goods-action.spec.js
Normal file
47
test/unit/specs/goods-action.spec.js
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
import GoodsAction from '../components/goods-action';
|
||||||
|
import GoodsActionBigBtn from 'packages/goods-action-big-btn';
|
||||||
|
import GoodsActionMiniBtn from 'packages/goods-action-mini-btn';
|
||||||
|
import { mount } from 'avoriaz';
|
||||||
|
import { DOMChecker } from '../utils';
|
||||||
|
|
||||||
|
describe('GoodsAction', () => {
|
||||||
|
let wrapper;
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
wrapper && wrapper.destroy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('create a GoodsAction', () => {
|
||||||
|
wrapper = mount(GoodsAction, {});
|
||||||
|
|
||||||
|
DOMChecker(wrapper, {
|
||||||
|
count: {
|
||||||
|
'.van-goods-action__mini-btn': 2,
|
||||||
|
'.van-goods-action__big-btn': 2,
|
||||||
|
'.van-icon-chat': 1
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('click GoodsActionBigBtn', () => {
|
||||||
|
wrapper = mount(GoodsActionBigBtn, {});
|
||||||
|
|
||||||
|
const submitSpyFunc = sinon.spy();
|
||||||
|
wrapper.vm.$on('click', submitSpyFunc);
|
||||||
|
wrapper.trigger('click');
|
||||||
|
expect(submitSpyFunc.calledOnce).to.be.true;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('click GoodsActionMiniBtn', () => {
|
||||||
|
wrapper = mount(GoodsActionMiniBtn, {
|
||||||
|
propsData: {
|
||||||
|
icon: 'card'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const submitSpyFunc = sinon.spy();
|
||||||
|
wrapper.vm.$on('click', submitSpyFunc);
|
||||||
|
wrapper.trigger('click');
|
||||||
|
expect(submitSpyFunc.calledOnce).to.be.true;
|
||||||
|
});
|
||||||
|
});
|
Loading…
x
Reference in New Issue
Block a user