mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-06 03:57:59 +08:00
commit
af768e25a8
@ -34,8 +34,7 @@ export {
|
||||
};
|
||||
export default {
|
||||
install,
|
||||
version,
|
||||
{{list}}
|
||||
version
|
||||
};
|
||||
`;
|
||||
|
||||
|
@ -36,5 +36,6 @@
|
||||
"uploader": "./packages/uploader/index.js",
|
||||
"swipe": "./packages/swipe/index.js",
|
||||
"swipe-item": "./packages/swipe-item/index.js",
|
||||
"datetime-picker": "./packages/datetime-picker/index.js"
|
||||
"datetime-picker": "./packages/datetime-picker/index.js",
|
||||
"notice-bar": "./packages/notice-bar/index.js"
|
||||
}
|
||||
|
69
docs/examples-docs/notice-bar.md
Normal file
69
docs/examples-docs/notice-bar.md
Normal file
@ -0,0 +1,69 @@
|
||||
<style>
|
||||
.demo-notice-bar {
|
||||
.van-notice-bar:not(:first-of-type) {
|
||||
margin-top: 15px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
## NoticeBar 通告栏
|
||||
|
||||
### 使用指南
|
||||
``` javascript
|
||||
import { NoticeBar } from 'vant';
|
||||
|
||||
Vue.component(NoticeBar.name, NoticeBar);
|
||||
```
|
||||
|
||||
### 代码演示
|
||||
|
||||
#### 基础用法
|
||||
|
||||
:::demo 基础用法
|
||||
```html
|
||||
<van-notice-bar text="足协杯战线连续第2年上演广州德比战,上赛季半决赛上恒大以两回合5-3的总比分淘汰富力。">
|
||||
```
|
||||
:::
|
||||
|
||||
#### 禁用滚动
|
||||
文字内容多于一行时,可通过`scrollable`参数控制是否开启滚动
|
||||
|
||||
:::demo 禁用滚动
|
||||
```html
|
||||
<van-notice-bar :scrollable="false">
|
||||
足协杯战线连续第2年上演广州德比战,上赛季半决赛上恒大以两回合5-3的总比分淘汰富力。
|
||||
</van-notice-bar>
|
||||
```
|
||||
:::
|
||||
|
||||
#### 通告栏模式
|
||||
默认模式为空,支持`closeable`和`link`。
|
||||
|
||||
:::demo 通告栏模式
|
||||
```html
|
||||
<!-- closeable 模式,在右侧显示关闭按钮 -->
|
||||
<van-notice-bar mode="closeable">
|
||||
足协杯战线连续第2年上演广州德比战,上赛季半决赛上恒大以两回合5-3的总比分淘汰富力。
|
||||
</van-notice-bar>
|
||||
|
||||
<!-- link 模式,在右侧显示链接箭头 -->
|
||||
<van-notice-bar mode="link">
|
||||
足协杯战线连续第2年上演广州德比战,上赛季半决赛上恒大以两回合5-3的总比分淘汰富力。
|
||||
</van-notice-bar>
|
||||
```
|
||||
:::
|
||||
|
||||
### API
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 | 可选值 |
|
||||
|-----------|-----------|-----------|-------------|-------------|
|
||||
| mode | 通告栏模式 | String | `''` | `closeable` `link` |
|
||||
| delay | 动画延迟时间,单位秒 | Number | `1` | |
|
||||
| scrollable | 是否滚动 | Boolean | `true` | |
|
||||
| speed | 滚动速率,单位px | Number | `40` | |
|
||||
|
||||
### Event
|
||||
|
||||
| 事件名 | 说明 | 参数 |
|
||||
|-----------|-----------|-----------|
|
||||
| click | 点击事件回调 | - |
|
@ -7,7 +7,6 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import 'highlight.js/styles/color-brewer.css';
|
||||
import docConfig from './doc.config';
|
||||
|
||||
export default {
|
||||
|
@ -125,6 +125,10 @@ module.exports = {
|
||||
{
|
||||
"path": "/lazyload",
|
||||
"title": "Lazyload 图片懒加载"
|
||||
},
|
||||
{
|
||||
"path": "/notice-bar",
|
||||
"title": "NoticeBar 通告栏"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -2,16 +2,16 @@ import Vue from 'vue';
|
||||
import VueRouter from 'vue-router';
|
||||
import App from './ExamplesApp';
|
||||
import routes from './router.config';
|
||||
import ZanUI from 'packages/index';
|
||||
import Vant, { Lazyload } from 'packages/index';
|
||||
import ZanDoc from 'zan-doc';
|
||||
import 'packages/vant-css/src/index.css';
|
||||
import 'zan-doc/src/helper/touch-simulator';
|
||||
|
||||
import DemoList from './components/demo-list.vue';
|
||||
|
||||
Vue.use(ZanUI);
|
||||
Vue.use(Vant);
|
||||
Vue.use(ZanDoc);
|
||||
Vue.use(ZanUI.Lazyload, {
|
||||
Vue.use(Lazyload, {
|
||||
lazyComponent: true
|
||||
});
|
||||
Vue.use(VueRouter);
|
||||
|
@ -4,7 +4,7 @@ import App from './ExamplesDocsApp';
|
||||
import routes from './router.config';
|
||||
import ZanDoc from 'zan-doc';
|
||||
import DemoBlock from './components/demo-block';
|
||||
import 'packages/vant-css/src/index.css';
|
||||
import 'packages/vant-css/src/reset.css';
|
||||
|
||||
const isMobile = (function() {
|
||||
var platform = navigator.userAgent.toLowerCase();
|
||||
|
@ -90,11 +90,11 @@
|
||||
"karma-sourcemap-loader": "^0.3.7",
|
||||
"karma-spec-reporter": "^0.0.31",
|
||||
"karma-webpack": "^2.0.4",
|
||||
"markdown-it": "^8.3.2",
|
||||
"markdown-it": "^8.4.0",
|
||||
"markdown-it-container": "^2.0.0",
|
||||
"mocha": "^3.4.2",
|
||||
"optimize-css-assets-webpack-plugin": "^3.1.1",
|
||||
"postcss": "^6.0.8",
|
||||
"postcss": "^6.0.10",
|
||||
"postcss-easy-import": "^2.1.0",
|
||||
"postcss-loader": "^2.0.6",
|
||||
"precss": "^2.0.0",
|
||||
@ -117,6 +117,6 @@
|
||||
"webpack": "^3.5.5",
|
||||
"webpack-dev-server": "^2.7.1",
|
||||
"webpack-merge": "^4.1.0",
|
||||
"zan-doc": "^0.2.2"
|
||||
"zan-doc": "^0.2.5"
|
||||
}
|
||||
}
|
||||
|
@ -36,6 +36,7 @@ import Uploader from './uploader';
|
||||
import Swipe from './swipe';
|
||||
import SwipeItem from './swipe-item';
|
||||
import DatetimePicker from './datetime-picker';
|
||||
import NoticeBar from './notice-bar';
|
||||
|
||||
const version = '0.8.6';
|
||||
const components = [
|
||||
@ -71,7 +72,8 @@ const components = [
|
||||
Uploader,
|
||||
Swipe,
|
||||
SwipeItem,
|
||||
DatetimePicker
|
||||
DatetimePicker,
|
||||
NoticeBar
|
||||
];
|
||||
|
||||
const install = function(Vue) {
|
||||
@ -127,47 +129,10 @@ export {
|
||||
Uploader,
|
||||
Swipe,
|
||||
SwipeItem,
|
||||
DatetimePicker
|
||||
DatetimePicker,
|
||||
NoticeBar
|
||||
};
|
||||
export default {
|
||||
install,
|
||||
version,
|
||||
Button,
|
||||
Switch,
|
||||
Field,
|
||||
Radio,
|
||||
Cell,
|
||||
Icon,
|
||||
CellGroup,
|
||||
CellSwipe,
|
||||
Popup,
|
||||
Dialog,
|
||||
Picker,
|
||||
RadioGroup,
|
||||
Waterfall,
|
||||
Loading,
|
||||
Panel,
|
||||
Card,
|
||||
Steps,
|
||||
Tag,
|
||||
Checkbox,
|
||||
CheckboxGroup,
|
||||
BadgeGroup,
|
||||
Badge,
|
||||
Search,
|
||||
Step,
|
||||
Tabs,
|
||||
Tab,
|
||||
Lazyload,
|
||||
ImagePreview,
|
||||
Col,
|
||||
Row,
|
||||
Actionsheet,
|
||||
Quantity,
|
||||
Progress,
|
||||
Toast,
|
||||
Uploader,
|
||||
Swipe,
|
||||
SwipeItem,
|
||||
DatetimePicker
|
||||
version
|
||||
};
|
||||
|
93
packages/notice-bar/index.vue
Normal file
93
packages/notice-bar/index.vue
Normal file
@ -0,0 +1,93 @@
|
||||
<template>
|
||||
<div v-show="showNoticeBar" @click="$emit('click')" :class="['van-notice-bar', { 'van-notice-bar--withicon': mode }]">
|
||||
<div class="van-notice-bar__content-wrap" ref="contentWrap">
|
||||
<div class="van-notice-bar__content" ref="content" :style="contentStyle" @transitionend="onTransitionEnd">
|
||||
<slot>{{ text }}</slot>
|
||||
</div>
|
||||
</div>
|
||||
<van-icon class="van-notice-bar__icon" :name="iconName" v-if="iconName" @click="onClickIcon" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Icon from '../icon';
|
||||
|
||||
const NOTICE_BAR_MODE = ['', 'closeable', 'link'];
|
||||
|
||||
export default {
|
||||
name: 'van-notice-bar',
|
||||
|
||||
components: {
|
||||
[Icon.name]: Icon
|
||||
},
|
||||
|
||||
props: {
|
||||
text: String,
|
||||
mode: {
|
||||
type: String,
|
||||
default: '',
|
||||
validator: val => NOTICE_BAR_MODE.indexOf(val) !== -1
|
||||
},
|
||||
delay: {
|
||||
type: [String, Number],
|
||||
default: 1
|
||||
},
|
||||
scrollable: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
speed: {
|
||||
type: Number,
|
||||
default: 40
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
duration: 0,
|
||||
offsetWidth: 0,
|
||||
showNoticeBar: true,
|
||||
diableTransition: false
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
iconName() {
|
||||
return this.mode === 'closeable' ? 'close' : this.mode === 'link' ? 'arrow' : '';
|
||||
},
|
||||
contentStyle() {
|
||||
return {
|
||||
left: -this.offsetWidth + 'px',
|
||||
transitionDelay: this.delay + 's',
|
||||
transitionDuration: this.duration + 's',
|
||||
transitionProperty: this.diableTransition ? 'none' : 'left'
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
const offsetWidth = this.$refs.content.getBoundingClientRect().width;
|
||||
const wrapWidth = this.$refs.contentWrap.getBoundingClientRect().width;
|
||||
if (this.scrollable && offsetWidth > wrapWidth) {
|
||||
this.offsetWidth = offsetWidth;
|
||||
this.duration = (offsetWidth + wrapWidth) / this.speed;
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
onClickIcon() {
|
||||
this.showNoticeBar = this.mode !== 'closeable';
|
||||
},
|
||||
onTransitionEnd() {
|
||||
const { offsetWidth } = this;
|
||||
this.diableTransition = true;
|
||||
this.offsetWidth = 0;
|
||||
|
||||
setTimeout(() => {
|
||||
this.diableTransition = false;
|
||||
this.offsetWidth = offsetWidth;
|
||||
}, 50);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
@ -30,3 +30,4 @@
|
||||
@import './toast.css';
|
||||
@import './uploader.css';
|
||||
@import './swipe.css';
|
||||
@import './notice-bar.css';
|
||||
|
36
packages/vant-css/src/notice-bar.css
Normal file
36
packages/vant-css/src/notice-bar.css
Normal file
@ -0,0 +1,36 @@
|
||||
@import './common/var.css';
|
||||
|
||||
.van-notice-bar {
|
||||
color: #f60;
|
||||
padding: 9px 10px;
|
||||
font-size: 12px;
|
||||
line-height: 1.5;
|
||||
background-color: #fff7cc;
|
||||
|
||||
&--withicon {
|
||||
position: relative;
|
||||
padding-right: 30px;
|
||||
}
|
||||
|
||||
&__icon {
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
position: absolute;
|
||||
font-size: 15px;
|
||||
line-height: 1;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&__content-wrap {
|
||||
height: 18px;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
&__content {
|
||||
position: absolute;
|
||||
white-space: nowrap;
|
||||
transition-property: left;
|
||||
transition-timing-function: linear;
|
||||
}
|
||||
}
|
16
test/unit/components/notice-bar.vue
Normal file
16
test/unit/components/notice-bar.vue
Normal file
@ -0,0 +1,16 @@
|
||||
<template>
|
||||
<div class="notice-bar-container" style="width: 100px;">
|
||||
<van-notice-bar :speed="speed" :text="text" :mode="mode" :delay="delay" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import NoticeBar from 'packages/notice-bar';
|
||||
export default {
|
||||
components: {
|
||||
[NoticeBar.name]: NoticeBar
|
||||
},
|
||||
props: ['speed', 'text', 'mode', 'delay']
|
||||
};
|
||||
</script>
|
||||
|
@ -75,7 +75,21 @@ function getWebpackConfig(testFileName) {
|
||||
]
|
||||
},
|
||||
{
|
||||
test: /\.vue$/,
|
||||
test: /test\/unit\/components\/.*\.vue$|packages\/swipe\/.*\.vue$/,
|
||||
use: [
|
||||
{
|
||||
loader: 'vue-loader',
|
||||
options: {
|
||||
loaders: {
|
||||
css: ['style-loader', 'css-loader', 'postcss-loader']
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
test: /packages\/.*\.vue$/,
|
||||
exclude: /packages\/swipe\/.*\.vue$/,
|
||||
use: [
|
||||
{
|
||||
loader: 'vue-loader',
|
||||
|
@ -13,4 +13,4 @@ if (process.env.TEST_FILE) {
|
||||
});
|
||||
} else {
|
||||
testsReq.keys().forEach(testsReq);
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,8 @@ module.exports = function(config) {
|
||||
reporters: ['spec', 'coverage'],
|
||||
files: ['./index.js'],
|
||||
preprocessors: {
|
||||
'./index.js': ['webpack', 'sourcemap']
|
||||
'./index.js': ['webpack', 'sourcemap'],
|
||||
'test/unit/!(components)/**/*.vue': ['coverage']
|
||||
},
|
||||
webpack: getWebpackConfig(getTestFileName()),
|
||||
webpackMiddleware: {
|
||||
|
@ -7,14 +7,14 @@ const defaultProps = {
|
||||
leftWidth: 100,
|
||||
rightWidth: 100
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
describe('CellSwipe', () => {
|
||||
let wrapper;
|
||||
afterEach(() => {
|
||||
wrapper && wrapper.destroy();
|
||||
});
|
||||
|
||||
|
||||
it('render left or right part when has width', () => {
|
||||
wrapper = mount(CellSwipe, defaultProps);
|
||||
expect(wrapper.find('.van-cell-swipe__left').length).to.equal(1);
|
||||
@ -97,7 +97,7 @@ describe('CellSwipe', () => {
|
||||
|
||||
triggerTouch(wrapper, 'touchstart', 0, 0);
|
||||
triggerTouch(wrapper, 'touchmove', 1, 0);
|
||||
|
||||
|
||||
wrapper.vm.$nextTick(() => {
|
||||
expect(wrapper.vm.offset).to.equal(0);
|
||||
expect(wrapper.vm.opened).to.be.false;
|
||||
|
61
test/unit/specs/notice-bar.spec.js
Normal file
61
test/unit/specs/notice-bar.spec.js
Normal file
@ -0,0 +1,61 @@
|
||||
import NoticeBar from '../components/notice-bar';
|
||||
import { mount } from 'avoriaz';
|
||||
|
||||
describe('NoticeBar', () => {
|
||||
let wrapper;
|
||||
afterEach(() => {
|
||||
wrapper && wrapper.destroy();
|
||||
});
|
||||
|
||||
it('create a notice-bar', () => {
|
||||
wrapper = mount(NoticeBar, {
|
||||
propsData: {},
|
||||
attachToDocument: true
|
||||
});
|
||||
|
||||
expect(wrapper.find('.van-notice-bar').length).to.equal(1);
|
||||
});
|
||||
|
||||
it('mode closeable', () => {
|
||||
wrapper = mount(NoticeBar, {
|
||||
propsData: {
|
||||
mode: 'closeable'
|
||||
},
|
||||
attachToDocument: true
|
||||
});
|
||||
|
||||
const icon = wrapper.find('.van-icon-close');
|
||||
expect(icon.length).to.equal(1);
|
||||
|
||||
icon[0].trigger('click');
|
||||
expect(wrapper.hasStyle('display', 'none'));
|
||||
});
|
||||
|
||||
it('mode link', () => {
|
||||
wrapper = mount(NoticeBar, {
|
||||
propsData: {
|
||||
mode: 'link'
|
||||
},
|
||||
attachToDocument: true
|
||||
});
|
||||
|
||||
expect(wrapper.find('.van-icon-arrow').length).to.equal(1);
|
||||
});
|
||||
|
||||
it('notice-bar transitionend', (done) => {
|
||||
wrapper = mount(NoticeBar, {
|
||||
propsData: {
|
||||
text: '足协杯战线连续第2年上演广州德比战',
|
||||
speed: 1000,
|
||||
delay: 0
|
||||
},
|
||||
attachToDocument: true
|
||||
});
|
||||
|
||||
const content = wrapper.find('.van-notice-bar__content')[0];
|
||||
setTimeout(() => {
|
||||
expect(content.hasStyle('transition-delay', '0s')).to.be.true;
|
||||
done();
|
||||
}, 500);
|
||||
});
|
||||
});
|
30
yarn.lock
30
yarn.lock
@ -4819,6 +4819,16 @@ markdown-it@^8.3.2:
|
||||
mdurl "^1.0.1"
|
||||
uc.micro "^1.0.3"
|
||||
|
||||
markdown-it@^8.4.0:
|
||||
version "8.4.0"
|
||||
resolved "https://registry.npmjs.org/markdown-it/-/markdown-it-8.4.0.tgz#e2400881bf171f7018ed1bd9da441dac8af6306d"
|
||||
dependencies:
|
||||
argparse "^1.0.7"
|
||||
entities "~1.1.1"
|
||||
linkify-it "^2.0.0"
|
||||
mdurl "^1.0.1"
|
||||
uc.micro "^1.0.3"
|
||||
|
||||
math-expression-evaluator@^1.2.14:
|
||||
version "1.2.17"
|
||||
resolved "https://registry.yarnpkg.com/math-expression-evaluator/-/math-expression-evaluator-1.2.17.tgz#de819fdbcd84dccd8fae59c6aeb79615b9d266ac"
|
||||
@ -6036,7 +6046,7 @@ postcss@^5.0.10, postcss@^5.0.11, postcss@^5.0.12, postcss@^5.0.13, postcss@^5.0
|
||||
source-map "^0.5.6"
|
||||
supports-color "^3.2.3"
|
||||
|
||||
postcss@^6.0.0, postcss@^6.0.1, postcss@^6.0.2, postcss@^6.0.3, postcss@^6.0.6, postcss@^6.0.8, postcss@^6.0.9:
|
||||
postcss@^6.0.0, postcss@^6.0.1, postcss@^6.0.2, postcss@^6.0.3, postcss@^6.0.6, postcss@^6.0.9:
|
||||
version "6.0.9"
|
||||
resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.9.tgz#54819766784a51c65b1ec4d54c2f93765438c35a"
|
||||
dependencies:
|
||||
@ -6044,6 +6054,14 @@ postcss@^6.0.0, postcss@^6.0.1, postcss@^6.0.2, postcss@^6.0.3, postcss@^6.0.6,
|
||||
source-map "^0.5.6"
|
||||
supports-color "^4.2.1"
|
||||
|
||||
postcss@^6.0.10:
|
||||
version "6.0.10"
|
||||
resolved "https://registry.npmjs.org/postcss/-/postcss-6.0.10.tgz#c311b89734483d87a91a56dc9e53f15f4e6e84e4"
|
||||
dependencies:
|
||||
chalk "^2.1.0"
|
||||
source-map "^0.5.7"
|
||||
supports-color "^4.2.1"
|
||||
|
||||
precss@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/precss/-/precss-2.0.0.tgz#7f567e3318e06d44c8fdbf9e58452e8358bf4b71"
|
||||
@ -6848,6 +6866,10 @@ source-map@^0.1.41:
|
||||
dependencies:
|
||||
amdefine ">=0.0.4"
|
||||
|
||||
source-map@^0.5.7:
|
||||
version "0.5.7"
|
||||
resolved "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
|
||||
|
||||
source-map@~0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.2.0.tgz#dab73fbcfc2ba819b4de03bd6f6eaa48164b3f9d"
|
||||
@ -7937,9 +7959,9 @@ yeast@0.1.2:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/yeast/-/yeast-0.1.2.tgz#008e06d8094320c372dbc2f8ed76a0ca6c8ac419"
|
||||
|
||||
zan-doc@^0.2.2:
|
||||
version "0.2.2"
|
||||
resolved "https://registry.npmjs.org/zan-doc/-/zan-doc-0.2.2.tgz#ebf8ffda5bd3cf9277cc3e59c48476a3fbf84d9f"
|
||||
zan-doc@^0.2.5:
|
||||
version "0.2.5"
|
||||
resolved "https://registry.npmjs.org/zan-doc/-/zan-doc-0.2.5.tgz#4f82e1b75db1a348b57436cd1d4ffb607bc18562"
|
||||
dependencies:
|
||||
cheerio "0.22.0"
|
||||
decamelize "^1.2.0"
|
||||
|
Loading…
x
Reference in New Issue
Block a user