Merge pull request #94 from chenjiahan/dev

add NoticeBar && test cases
This commit is contained in:
neverland 2017-08-28 15:25:17 +08:00 committed by GitHub
commit af768e25a8
19 changed files with 343 additions and 62 deletions

View File

@ -34,8 +34,7 @@ export {
}; };
export default { export default {
install, install,
version, version
{{list}}
}; };
`; `;

View File

@ -36,5 +36,6 @@
"uploader": "./packages/uploader/index.js", "uploader": "./packages/uploader/index.js",
"swipe": "./packages/swipe/index.js", "swipe": "./packages/swipe/index.js",
"swipe-item": "./packages/swipe-item/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"
} }

View 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 | 点击事件回调 | - |

View File

@ -7,7 +7,6 @@
</template> </template>
<script> <script>
import 'highlight.js/styles/color-brewer.css';
import docConfig from './doc.config'; import docConfig from './doc.config';
export default { export default {

View File

@ -125,6 +125,10 @@ module.exports = {
{ {
"path": "/lazyload", "path": "/lazyload",
"title": "Lazyload 图片懒加载" "title": "Lazyload 图片懒加载"
},
{
"path": "/notice-bar",
"title": "NoticeBar 通告栏"
} }
] ]
}, },

View File

@ -2,16 +2,16 @@ import Vue from 'vue';
import VueRouter from 'vue-router'; import VueRouter from 'vue-router';
import App from './ExamplesApp'; import App from './ExamplesApp';
import routes from './router.config'; import routes from './router.config';
import ZanUI from 'packages/index'; import Vant, { Lazyload } from 'packages/index';
import ZanDoc from 'zan-doc'; import ZanDoc from 'zan-doc';
import 'packages/vant-css/src/index.css'; import 'packages/vant-css/src/index.css';
import 'zan-doc/src/helper/touch-simulator'; import 'zan-doc/src/helper/touch-simulator';
import DemoList from './components/demo-list.vue'; import DemoList from './components/demo-list.vue';
Vue.use(ZanUI); Vue.use(Vant);
Vue.use(ZanDoc); Vue.use(ZanDoc);
Vue.use(ZanUI.Lazyload, { Vue.use(Lazyload, {
lazyComponent: true lazyComponent: true
}); });
Vue.use(VueRouter); Vue.use(VueRouter);

View File

@ -4,7 +4,7 @@ import App from './ExamplesDocsApp';
import routes from './router.config'; import routes from './router.config';
import ZanDoc from 'zan-doc'; import ZanDoc from 'zan-doc';
import DemoBlock from './components/demo-block'; import DemoBlock from './components/demo-block';
import 'packages/vant-css/src/index.css'; import 'packages/vant-css/src/reset.css';
const isMobile = (function() { const isMobile = (function() {
var platform = navigator.userAgent.toLowerCase(); var platform = navigator.userAgent.toLowerCase();

View File

@ -90,11 +90,11 @@
"karma-sourcemap-loader": "^0.3.7", "karma-sourcemap-loader": "^0.3.7",
"karma-spec-reporter": "^0.0.31", "karma-spec-reporter": "^0.0.31",
"karma-webpack": "^2.0.4", "karma-webpack": "^2.0.4",
"markdown-it": "^8.3.2", "markdown-it": "^8.4.0",
"markdown-it-container": "^2.0.0", "markdown-it-container": "^2.0.0",
"mocha": "^3.4.2", "mocha": "^3.4.2",
"optimize-css-assets-webpack-plugin": "^3.1.1", "optimize-css-assets-webpack-plugin": "^3.1.1",
"postcss": "^6.0.8", "postcss": "^6.0.10",
"postcss-easy-import": "^2.1.0", "postcss-easy-import": "^2.1.0",
"postcss-loader": "^2.0.6", "postcss-loader": "^2.0.6",
"precss": "^2.0.0", "precss": "^2.0.0",
@ -117,6 +117,6 @@
"webpack": "^3.5.5", "webpack": "^3.5.5",
"webpack-dev-server": "^2.7.1", "webpack-dev-server": "^2.7.1",
"webpack-merge": "^4.1.0", "webpack-merge": "^4.1.0",
"zan-doc": "^0.2.2" "zan-doc": "^0.2.5"
} }
} }

View File

@ -36,6 +36,7 @@ import Uploader from './uploader';
import Swipe from './swipe'; import Swipe from './swipe';
import SwipeItem from './swipe-item'; import SwipeItem from './swipe-item';
import DatetimePicker from './datetime-picker'; import DatetimePicker from './datetime-picker';
import NoticeBar from './notice-bar';
const version = '0.8.6'; const version = '0.8.6';
const components = [ const components = [
@ -71,7 +72,8 @@ const components = [
Uploader, Uploader,
Swipe, Swipe,
SwipeItem, SwipeItem,
DatetimePicker DatetimePicker,
NoticeBar
]; ];
const install = function(Vue) { const install = function(Vue) {
@ -127,47 +129,10 @@ export {
Uploader, Uploader,
Swipe, Swipe,
SwipeItem, SwipeItem,
DatetimePicker DatetimePicker,
NoticeBar
}; };
export default { export default {
install, install,
version, 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
}; };

View 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>

View File

@ -30,3 +30,4 @@
@import './toast.css'; @import './toast.css';
@import './uploader.css'; @import './uploader.css';
@import './swipe.css'; @import './swipe.css';
@import './notice-bar.css';

View 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;
}
}

View 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>

View File

@ -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: [ use: [
{ {
loader: 'vue-loader', loader: 'vue-loader',

View File

@ -14,7 +14,8 @@ module.exports = function(config) {
reporters: ['spec', 'coverage'], reporters: ['spec', 'coverage'],
files: ['./index.js'], files: ['./index.js'],
preprocessors: { preprocessors: {
'./index.js': ['webpack', 'sourcemap'] './index.js': ['webpack', 'sourcemap'],
'test/unit/!(components)/**/*.vue': ['coverage']
}, },
webpack: getWebpackConfig(getTestFileName()), webpack: getWebpackConfig(getTestFileName()),
webpackMiddleware: { webpackMiddleware: {

View File

@ -7,7 +7,7 @@ const defaultProps = {
leftWidth: 100, leftWidth: 100,
rightWidth: 100 rightWidth: 100
} }
} };
describe('CellSwipe', () => { describe('CellSwipe', () => {
let wrapper; let wrapper;

View 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);
});
});

View File

@ -4819,6 +4819,16 @@ markdown-it@^8.3.2:
mdurl "^1.0.1" mdurl "^1.0.1"
uc.micro "^1.0.3" 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: math-expression-evaluator@^1.2.14:
version "1.2.17" version "1.2.17"
resolved "https://registry.yarnpkg.com/math-expression-evaluator/-/math-expression-evaluator-1.2.17.tgz#de819fdbcd84dccd8fae59c6aeb79615b9d266ac" 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" source-map "^0.5.6"
supports-color "^3.2.3" 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" version "6.0.9"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.9.tgz#54819766784a51c65b1ec4d54c2f93765438c35a" resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.9.tgz#54819766784a51c65b1ec4d54c2f93765438c35a"
dependencies: 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" source-map "^0.5.6"
supports-color "^4.2.1" 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: precss@^2.0.0:
version "2.0.0" version "2.0.0"
resolved "https://registry.yarnpkg.com/precss/-/precss-2.0.0.tgz#7f567e3318e06d44c8fdbf9e58452e8358bf4b71" resolved "https://registry.yarnpkg.com/precss/-/precss-2.0.0.tgz#7f567e3318e06d44c8fdbf9e58452e8358bf4b71"
@ -6848,6 +6866,10 @@ source-map@^0.1.41:
dependencies: dependencies:
amdefine ">=0.0.4" 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: source-map@~0.2.0:
version "0.2.0" version "0.2.0"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.2.0.tgz#dab73fbcfc2ba819b4de03bd6f6eaa48164b3f9d" 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" version "0.1.2"
resolved "https://registry.yarnpkg.com/yeast/-/yeast-0.1.2.tgz#008e06d8094320c372dbc2f8ed76a0ca6c8ac419" resolved "https://registry.yarnpkg.com/yeast/-/yeast-0.1.2.tgz#008e06d8094320c372dbc2f8ed76a0ca6c8ac419"
zan-doc@^0.2.2: zan-doc@^0.2.5:
version "0.2.2" version "0.2.5"
resolved "https://registry.npmjs.org/zan-doc/-/zan-doc-0.2.2.tgz#ebf8ffda5bd3cf9277cc3e59c48476a3fbf84d9f" resolved "https://registry.npmjs.org/zan-doc/-/zan-doc-0.2.5.tgz#4f82e1b75db1a348b57436cd1d4ffb607bc18562"
dependencies: dependencies:
cheerio "0.22.0" cheerio "0.22.0"
decamelize "^1.2.0" decamelize "^1.2.0"