add Select Component
add Select Component
This commit is contained in:
parent
c13471b5fb
commit
e355dd49d3
21 changed files with 1137 additions and 99 deletions
|
@ -4,7 +4,7 @@
|
|||
<Icon type="arrow-right-b"></Icon>
|
||||
<slot></slot>
|
||||
</div>
|
||||
<div :class="concentClasses" v-show="isActive" transition="height">
|
||||
<div :class="concentClasses" v-show="isActive">
|
||||
<div :class="boxClasses"><slot name="content"></slot></div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<template>
|
||||
<div v-if="showSizer || showElevator" :class="optsClasses">
|
||||
<div v-if="showSizer" :class="sizerClasses">
|
||||
<select v-model="pageSize" @change="changeSize">
|
||||
<option :value="item" v-for="item in pageSizeOpts">{{ item }} 条/页</option>
|
||||
</select>
|
||||
<i-select :model.sync="pageSize" @on-change="changeSize">
|
||||
<i-option v-for="item in pageSizeOpts" :value="item" style="text-align:center;">{{ item }} 条/页</i-option>
|
||||
</i-select>
|
||||
</div>
|
||||
<div v-if="showElevator" :class="ElevatorClasses">
|
||||
跳至
|
||||
|
@ -13,6 +13,9 @@
|
|||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import iSelect from '../../components/select/select.vue';
|
||||
import iOption from '../../components/select/option.vue';
|
||||
|
||||
const prefixCls = 'ivu-page';
|
||||
|
||||
function isValueNumber (value) {
|
||||
|
@ -20,6 +23,7 @@
|
|||
}
|
||||
|
||||
export default {
|
||||
components: { iSelect, iOption },
|
||||
props: {
|
||||
pageSizeOpts: Array,
|
||||
showSizer: Boolean,
|
||||
|
|
59
components/select/dropdown.vue
Normal file
59
components/select/dropdown.vue
Normal file
|
@ -0,0 +1,59 @@
|
|||
<template>
|
||||
<div class="ivu-select-dropdown"><slot></slot></div>
|
||||
</template>
|
||||
<script>
|
||||
import Popper from 'popper.js';
|
||||
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
popper: null
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
update () {
|
||||
if (this.popper) {
|
||||
this.$nextTick(() => {
|
||||
this.popper.update();
|
||||
});
|
||||
} else {
|
||||
this.$nextTick(() => {
|
||||
this.popper = new Popper(this.$parent.$els.reference, this.$el, {
|
||||
gpuAcceleration: false,
|
||||
placement: 'bottom-start',
|
||||
boundariesPadding: 0,
|
||||
forceAbsolute: true
|
||||
});
|
||||
this.popper.onCreate(popper => {
|
||||
this.resetTransformOrigin(popper);
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
destroy () {
|
||||
if (this.popper) {
|
||||
this.resetTransformOrigin(this.popper);
|
||||
setTimeout(() => {
|
||||
this.popper.destroy();
|
||||
this.popper = null;
|
||||
}, 300);
|
||||
}
|
||||
},
|
||||
resetTransformOrigin(popper) {
|
||||
let placementMap = {top: 'bottom', bottom: 'top'};
|
||||
let placement = popper._popper.getAttribute('x-placement').split('-')[0];
|
||||
let origin = placementMap[placement];
|
||||
popper._popper.style.transformOrigin = `center ${ origin }`;
|
||||
}
|
||||
},
|
||||
ready () {
|
||||
this.$on('on-update-popper', this.update);
|
||||
this.$on('on-destroy-popper', this.destroy);
|
||||
},
|
||||
beforeDestroy () {
|
||||
if (this.popper) {
|
||||
this.popper.destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
5
components/select/index.js
Normal file
5
components/select/index.js
Normal file
|
@ -0,0 +1,5 @@
|
|||
import Select from './select.vue';
|
||||
import Option from './option.vue';
|
||||
import OptionGroup from './option-group.vue';
|
||||
|
||||
export { Select, Option, OptionGroup };
|
25
components/select/option-group.vue
Normal file
25
components/select/option-group.vue
Normal file
|
@ -0,0 +1,25 @@
|
|||
<template>
|
||||
<li :class="[`${prefixCls}-wrap`]">
|
||||
<div :class="[`${prefixCls}-title`]">{{ label }}</div>
|
||||
<ul>
|
||||
<li :class="[`${prefixCls}`]"><slot></slot></li>
|
||||
</ul>
|
||||
</li>
|
||||
</template>
|
||||
<script>
|
||||
const prefixCls = 'ivu-select-group';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
label: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
prefixCls: prefixCls
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
65
components/select/option.vue
Normal file
65
components/select/option.vue
Normal file
|
@ -0,0 +1,65 @@
|
|||
<template>
|
||||
<li :class="classes" @click.stop="select" @mouseout.stop="blur"><slot>{{ showLabel }}</slot></li>
|
||||
</template>
|
||||
<script>
|
||||
const prefixCls = 'ivu-select-item';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
value: {
|
||||
type: [String, Number],
|
||||
required: true
|
||||
},
|
||||
label: {
|
||||
type: [String, Number]
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
componentName: 'select-item',
|
||||
data () {
|
||||
return {
|
||||
selected: false,
|
||||
index: 0, // for up and down to focus
|
||||
isFocus: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
classes () {
|
||||
return [
|
||||
`${prefixCls}`,
|
||||
{
|
||||
[`${prefixCls}-disabled`]: this.disabled,
|
||||
[`${prefixCls}-selected`]: this.selected,
|
||||
[`${prefixCls}-focus`]: this.isFocus
|
||||
}
|
||||
]
|
||||
},
|
||||
showLabel () {
|
||||
return (!!this.label) ? this.label : this.value;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
select () {
|
||||
if (this.disabled) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.$dispatch('on-select-selected', this.value);
|
||||
},
|
||||
blur () {
|
||||
this.isFocus = false;
|
||||
}
|
||||
},
|
||||
ready () {
|
||||
|
||||
},
|
||||
events: {
|
||||
'on-select-close' () {
|
||||
this.isFocus = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
421
components/select/select.vue
Normal file
421
components/select/select.vue
Normal file
|
@ -0,0 +1,421 @@
|
|||
<template>
|
||||
<div :class="classes" v-clickoutside="handleClose">
|
||||
<div
|
||||
:class="[`${prefixCls}-selection`]"
|
||||
v-el:reference
|
||||
@click="toggleMenu">
|
||||
<div class="ivu-tag" v-if="multiple" v-for="item in selectedMultiple">
|
||||
<span class="ivu-tag-text">{{ item.label }}</span>
|
||||
<Icon type="ios-close-empty" @click.stop="removeTag($index)"></Icon>
|
||||
</div>
|
||||
<span :class="[`${prefixCls}-placeholder`]" v-show="showPlaceholder && !filterable">{{ placeholder }}</span>
|
||||
<span :class="[`${prefixCls}-selected-value`]" v-show="!showPlaceholder && !multiple && !filterable">{{ selectedSingle }}</span>
|
||||
<input
|
||||
type="text"
|
||||
:class="[`${prefixCls}-input`]"
|
||||
v-if="filterable"
|
||||
v-model="query"
|
||||
:placeholder="placeholder"
|
||||
:style="inputStyle">
|
||||
<Icon type="ios-close" :class="[`${prefixCls}-arrow`]" v-show="showCloseIcon" @click.stop="clearSingleSelect"></Icon>
|
||||
<Icon type="arrow-down-b" :class="[`${prefixCls}-arrow`]"></Icon>
|
||||
</div>
|
||||
<Dropdown v-show="visible" transition="slide-up" v-ref:dropdown>
|
||||
<ul :class="[`${prefixCls}-dropdown-list`]"><slot></slot></ul>
|
||||
</Dropdown>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import Icon from '../icon';
|
||||
import Dropdown from './dropdown.vue';
|
||||
import clickoutside from '../../directives/clickoutside';
|
||||
import { oneOf } from '../../utils/assist';
|
||||
|
||||
const prefixCls = 'ivu-select';
|
||||
|
||||
export default {
|
||||
components: { Icon, Dropdown },
|
||||
directives: { clickoutside },
|
||||
props: {
|
||||
model: {
|
||||
type: [String, Number, Array],
|
||||
default: ''
|
||||
},
|
||||
multiple: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
clearable: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: '请选择'
|
||||
},
|
||||
filterable: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
filterMethod: {
|
||||
type: Function
|
||||
},
|
||||
size: {
|
||||
validator (value) {
|
||||
return oneOf(value, ['small', 'large']);
|
||||
}
|
||||
},
|
||||
labelInValue: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
prefixCls: prefixCls,
|
||||
visible: false,
|
||||
options: [],
|
||||
optionInstances: [],
|
||||
selectedSingle: '', // label
|
||||
selectedMultiple: [],
|
||||
focusIndex: 0,
|
||||
query: '',
|
||||
inputLength: 20
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
classes () {
|
||||
return [
|
||||
`${prefixCls}`,
|
||||
{
|
||||
[`${prefixCls}-visible`]: this.visible,
|
||||
[`${prefixCls}-disabled`]: this.disabled,
|
||||
[`${prefixCls}-multiple`]: this.multiple,
|
||||
[`${prefixCls}-single`]: !this.multiple,
|
||||
[`${prefixCls}-show-clear`]: this.showCloseIcon,
|
||||
[`${prefixCls}-${this.size}`]: !!this.size
|
||||
}
|
||||
]
|
||||
},
|
||||
showPlaceholder () {
|
||||
let status = false;
|
||||
|
||||
if ((typeof this.model) === 'string') {
|
||||
if (this.model === '') {
|
||||
status = true;
|
||||
}
|
||||
} else if (Array.isArray(this.model)) {
|
||||
if (!this.model.length) {
|
||||
status = true;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
},
|
||||
showCloseIcon () {
|
||||
return !this.multiple && this.clearable && !this.showPlaceholder;
|
||||
},
|
||||
inputStyle () {
|
||||
let style = {};
|
||||
|
||||
if (this.multiple) {
|
||||
style.width = `${this.inputLength}px`;
|
||||
}
|
||||
|
||||
return style;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
toggleMenu () {
|
||||
if (this.disabled) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.visible = !this.visible;
|
||||
},
|
||||
hideMenu () {
|
||||
this.visible = false;
|
||||
this.focusIndex = 0;
|
||||
this.$broadcast('on-select-close');
|
||||
},
|
||||
// find option component
|
||||
findChild (cb) {
|
||||
const find = function (child) {
|
||||
const name = child.$options.componentName;
|
||||
|
||||
if (name) {
|
||||
cb(child);
|
||||
} else if (child.$children.length) {
|
||||
child.$children.forEach((innerChild) => {
|
||||
find(innerChild, cb);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
if (this.optionInstances.length) {
|
||||
this.optionInstances.forEach((child) => {
|
||||
find(child);
|
||||
})
|
||||
} else {
|
||||
this.$children.forEach((child) => {
|
||||
find(child);
|
||||
});
|
||||
}
|
||||
},
|
||||
updateOptions (init) {
|
||||
let options = [];
|
||||
let index = 1;
|
||||
|
||||
this.findChild((child) => {
|
||||
options.push({
|
||||
value: child.value,
|
||||
label: (child.label === undefined) ? child.$el.innerHTML : child.label
|
||||
});
|
||||
child.index = index++;
|
||||
|
||||
if (init) {
|
||||
this.optionInstances.push(child);
|
||||
}
|
||||
});
|
||||
|
||||
this.options = options;
|
||||
|
||||
if (init) {
|
||||
this.updateSingleSelected(true);
|
||||
this.updateMultipleSelected(true);
|
||||
}
|
||||
},
|
||||
updateSingleSelected (init = false) {
|
||||
const type = typeof this.model;
|
||||
|
||||
if (type === 'string' || type === 'number') {
|
||||
for (let i = 0; i < this.options.length; i++) {
|
||||
if (this.model === this.options[i].value) {
|
||||
this.selectedSingle = this.options[i].label;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.toggleSingleSelected(this.model, init);
|
||||
},
|
||||
clearSingleSelect () {
|
||||
if (this.showCloseIcon) {
|
||||
this.findChild((child) => {
|
||||
child.selected = false;
|
||||
});
|
||||
this.model = '';
|
||||
}
|
||||
},
|
||||
updateMultipleSelected (init = false) {
|
||||
if (this.multiple && Array.isArray(this.model)) {
|
||||
let selected = [];
|
||||
|
||||
for (let i = 0; i < this.model.length; i++) {
|
||||
const model = this.model[i];
|
||||
|
||||
for (let j = 0; j < this.options.length; j++) {
|
||||
const option = this.options[j];
|
||||
|
||||
if (model === option.value) {
|
||||
selected.push({
|
||||
value: option.value,
|
||||
label: option.label
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.selectedMultiple = selected;
|
||||
}
|
||||
|
||||
this.toggleMultipleSelected(this.model, init);
|
||||
},
|
||||
removeTag (index) {
|
||||
if (this.disabled) {
|
||||
return false;
|
||||
}
|
||||
this.model.splice(index, 1);
|
||||
},
|
||||
// to select option for single
|
||||
toggleSingleSelected (value, init = false) {
|
||||
if (!this.multiple) {
|
||||
let label = '';
|
||||
|
||||
this.findChild((child) => {
|
||||
if (child.value === value) {
|
||||
child.selected = true;
|
||||
label = (child.label === undefined) ? child.$el.innerHTML : child.label;
|
||||
} else {
|
||||
child.selected = false;
|
||||
}
|
||||
});
|
||||
|
||||
this.hideMenu();
|
||||
|
||||
if (!init) {
|
||||
if (this.labelInValue) {
|
||||
this.$emit('on-change', {
|
||||
value: value,
|
||||
label: label
|
||||
});
|
||||
} else {
|
||||
this.$emit('on-change', value);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
// to select option for multiple
|
||||
toggleMultipleSelected (value, init = false) {
|
||||
if (this.multiple) {
|
||||
let hybridValue = [];
|
||||
for (let i = 0; i < value.length; i++) {
|
||||
hybridValue.push({
|
||||
value: value[i]
|
||||
});
|
||||
}
|
||||
|
||||
this.findChild((child) => {
|
||||
const index = value.indexOf(child.value);
|
||||
|
||||
if (index >= 0) {
|
||||
child.selected = true;
|
||||
hybridValue[index].label = (child.label === undefined) ? child.$el.innerHTML : child.label;
|
||||
} else {
|
||||
child.selected = false;
|
||||
}
|
||||
});
|
||||
|
||||
if (!init) {
|
||||
if (this.labelInValue) {
|
||||
this.$emit('on-change', hybridValue);
|
||||
} else {
|
||||
this.$emit('on-change', value);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
handleClose () {
|
||||
this.hideMenu();
|
||||
},
|
||||
handleKeydown (e) {
|
||||
if (this.visible) {
|
||||
const keyCode = e.keyCode;
|
||||
// Esc slide-up
|
||||
if (keyCode === 27) {
|
||||
e.preventDefault();
|
||||
this.hideMenu();
|
||||
}
|
||||
// next
|
||||
if (keyCode === 40) {
|
||||
e.preventDefault();
|
||||
this.navigateOptions('next');
|
||||
}
|
||||
// prev
|
||||
if (keyCode === 38) {
|
||||
e.preventDefault();
|
||||
this.navigateOptions('prev');
|
||||
}
|
||||
// enter
|
||||
if (keyCode === 13) {
|
||||
e.preventDefault();
|
||||
|
||||
this.findChild((child) => {
|
||||
if (child.isFocus) {
|
||||
child.select();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
navigateOptions (direction) {
|
||||
if (direction === 'next') {
|
||||
const next = this.focusIndex + 1;
|
||||
this.focusIndex = (this.focusIndex === this.options.length) ? 1 : next;
|
||||
} else if (direction === 'prev') {
|
||||
const prev = this.focusIndex - 1;
|
||||
this.focusIndex = (this.focusIndex <= 1) ? this.options.length : prev;
|
||||
}
|
||||
|
||||
let child_status = {
|
||||
disabled: false
|
||||
};
|
||||
|
||||
this.findChild((child) => {
|
||||
if (child.index === this.focusIndex) {
|
||||
child_status.disabled = child.disabled;
|
||||
|
||||
if (!child.disabled) {
|
||||
child.isFocus = true;
|
||||
}
|
||||
} else {
|
||||
child.isFocus = false;
|
||||
}
|
||||
});
|
||||
|
||||
this.resetScrollTop();
|
||||
|
||||
if (child_status.disabled) {
|
||||
this.navigateOptions(direction);
|
||||
}
|
||||
},
|
||||
resetScrollTop () {
|
||||
const index = this.focusIndex - 1;
|
||||
let bottomOverflowDistance = this.optionInstances[index].$el.getBoundingClientRect().bottom - this.$refs.dropdown.$el.getBoundingClientRect().bottom;
|
||||
let topOverflowDistance = this.optionInstances[index].$el.getBoundingClientRect().top - this.$refs.dropdown.$el.getBoundingClientRect().top;
|
||||
|
||||
if (bottomOverflowDistance > 0) {
|
||||
this.$refs.dropdown.$el.scrollTop += bottomOverflowDistance;
|
||||
}
|
||||
if (topOverflowDistance < 0) {
|
||||
this.$refs.dropdown.$el.scrollTop += topOverflowDistance;
|
||||
}
|
||||
}
|
||||
},
|
||||
ready () {
|
||||
this.updateOptions(true);
|
||||
document.addEventListener('keydown', this.handleKeydown);
|
||||
},
|
||||
beforeDestroy () {
|
||||
document.removeEventListener('keydown', this.handleKeydown);
|
||||
},
|
||||
watch: {
|
||||
model () {
|
||||
if (this.multiple) {
|
||||
this.updateMultipleSelected();
|
||||
} else {
|
||||
this.updateSingleSelected();
|
||||
}
|
||||
},
|
||||
visible (val) {
|
||||
if (val) {
|
||||
this.$broadcast('on-update-popper');
|
||||
} else {
|
||||
|
||||
}
|
||||
}
|
||||
},
|
||||
events: {
|
||||
'on-select-selected' (value) {
|
||||
if (this.model === value) {
|
||||
this.hideMenu();
|
||||
} else {
|
||||
if (this.multiple) {
|
||||
const index = this.model.indexOf(value);
|
||||
if (index >= 0) {
|
||||
this.removeTag(index);
|
||||
} else {
|
||||
this.model.push(value);
|
||||
}
|
||||
} else {
|
||||
this.model = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
19
directives/clickoutside.js
Normal file
19
directives/clickoutside.js
Normal file
|
@ -0,0 +1,19 @@
|
|||
export default {
|
||||
bind () {
|
||||
this.documentHandler = (e) => {
|
||||
if (this.el.contains(e.target)) {
|
||||
return false;
|
||||
}
|
||||
if (this.expression) {
|
||||
this.vm[this.expression]();
|
||||
}
|
||||
};
|
||||
document.addEventListener('click', this.documentHandler);
|
||||
},
|
||||
update () {
|
||||
|
||||
},
|
||||
unbind () {
|
||||
document.removeEventListener('click', this.documentHandler);
|
||||
}
|
||||
}
|
6
index.js
6
index.js
|
@ -24,6 +24,7 @@ import Message from './components/message';
|
|||
import Notice from './components/notice';
|
||||
import LoadingBar from './components/loading-bar';
|
||||
import Modal from './components/modal';
|
||||
import { Select, Option, OptionGroup } from './components/select';
|
||||
|
||||
const iview = {
|
||||
Button,
|
||||
|
@ -52,7 +53,10 @@ const iview = {
|
|||
Message,
|
||||
Notice,
|
||||
LoadingBar,
|
||||
Modal
|
||||
Modal,
|
||||
iSelect: Select,
|
||||
iOption: Option,
|
||||
iOptionGroup: OptionGroup
|
||||
};
|
||||
|
||||
module.exports = iview;
|
|
@ -60,6 +60,11 @@ router.map({
|
|||
component: function (resolve) {
|
||||
require(['./routers/tag.vue'], resolve);
|
||||
}
|
||||
},
|
||||
'/select': {
|
||||
component: function (resolve) {
|
||||
require(['./routers/select.vue'], resolve);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -2,14 +2,7 @@
|
|||
|
||||
</style>
|
||||
<template>
|
||||
<Button @click="info">info</Button>
|
||||
<Button @click="success">success</Button>
|
||||
<Button @click="warning">warning</Button>
|
||||
<Button @click="error">error</Button>
|
||||
<Button @click="confirm">confirm</Button>
|
||||
<Page :total="11" :page-size="11"></Page>
|
||||
<Page :total="11" size="small"></Page>
|
||||
<Page :current="1" :total="0" simple></Page>
|
||||
<Page :total="100" show-sizer></Page>
|
||||
</template>
|
||||
<script>
|
||||
import { Modal, Button, Message, Page } from 'iview';
|
||||
|
|
99
local/routers/select.vue
Normal file
99
local/routers/select.vue
Normal file
|
@ -0,0 +1,99 @@
|
|||
<template>
|
||||
<div>
|
||||
<!--<br><br><br><br><br><br><br><br><br><br><br>-->
|
||||
{{ city | json }}<br>
|
||||
<Button @click="city = 'hangzhou'">切换城市</Button>
|
||||
<br>
|
||||
<i-select :model.sync="city" style="width:200px" @on-change="change">
|
||||
<i-option-group label="热门城市">
|
||||
<i-option value="beijing">北京市</i-option>
|
||||
<i-option value="shanghai" disabled label="上海市">上海市2</i-option>
|
||||
<i-option value="shenzhen">深圳市</i-option>
|
||||
</i-option-group>
|
||||
<i-option-group label="二线城市">
|
||||
<i-option value="nanjing">南京市</i-option>
|
||||
<i-option value="hangzhou">杭州市</i-option>
|
||||
</i-option-group>
|
||||
<i-option value="heilongjiang" disabled>黑龙江市</i-option>
|
||||
<i-option-group label="热门城市">
|
||||
<i-option value="beijing">北京市</i-option>
|
||||
<i-option value="shanghai" disabled label="上海市">上海市2</i-option>
|
||||
<i-option value="shenzhen">深圳市</i-option>
|
||||
</i-option-group>
|
||||
<i-option-group label="二线城市">
|
||||
<i-option value="nanjing">南京市</i-option>
|
||||
<i-option value="hangzhou">杭州市</i-option>
|
||||
</i-option-group>
|
||||
<i-option value="heilongjiang" disabled>黑龙江市</i-option>
|
||||
<i-option-group label="热门城市">
|
||||
<i-option value="beijing">北京市</i-option>
|
||||
<i-option value="shanghai" disabled label="上海市">上海市2</i-option>
|
||||
<i-option value="shenzhen">深圳市</i-option>
|
||||
</i-option-group>
|
||||
<i-option-group label="二线城市">
|
||||
<i-option value="nanjing">南京市</i-option>
|
||||
<i-option value="hangzhou">杭州市</i-option>
|
||||
</i-option-group>
|
||||
<i-option value="heilongjiang" disabled>黑龙江市</i-option>
|
||||
</i-select>
|
||||
|
||||
<i-select :model.sync="focus" style="width:200px" @on-change="change" clearable filterable label-in-value>
|
||||
<i-option value="beijing">北京市</i-option>
|
||||
<i-option value="shanghai" label="上海市">上海市</i-option>
|
||||
<i-option value="shenzhen" disabled>深圳市</i-option>
|
||||
<i-option value="guangzhou" label="广州市">广州市2</i-option>
|
||||
<i-option value="shijiazhuang" disabled>石家庄市</i-option>
|
||||
<i-option value="a">a市</i-option>
|
||||
<i-option value="b">b市</i-option>
|
||||
<i-option value="c">c市</i-option>
|
||||
<i-option value="d">d市</i-option>
|
||||
<i-option value="e">e市</i-option>
|
||||
</i-select>
|
||||
|
||||
<i-select :model.sync="focus2" style="width:300px" @on-change="change" clearable multiple>
|
||||
<i-option value="beijing">北京市</i-option>
|
||||
<i-option value="shanghai">上海市</i-option>
|
||||
<i-option value="shenzhen" disabled>深圳市</i-option>
|
||||
<i-option value="guangzhou">广州市</i-option>
|
||||
<i-option value="shijiazhuang">石家庄市</i-option>
|
||||
<i-option value="a">a市</i-option>
|
||||
<i-option value="b">b市</i-option>
|
||||
<i-option value="c">c市</i-option>
|
||||
<i-option value="d">d市</i-option>
|
||||
<i-option value="e">e市</i-option>
|
||||
</i-select>
|
||||
|
||||
<br><br><br><br><br><br><br><br><br><br><br><br>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { iSelect, iOption, iOptionGroup, Button } from 'iview';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
iSelect,
|
||||
iOption,
|
||||
iOptionGroup,
|
||||
Button
|
||||
},
|
||||
props: {
|
||||
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
city: '',
|
||||
focus: '',
|
||||
focus2: ['beijing', 'guangzhou', 'b']
|
||||
// focus2: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
||||
},
|
||||
methods: {
|
||||
change (data) {
|
||||
console.log(data)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -1,79 +1,30 @@
|
|||
<template>
|
||||
<div>
|
||||
<Button @click="start">start</Button>
|
||||
<Button @click="destroy">destroy</Button>
|
||||
<Button @click="finish">finish</Button>
|
||||
<Button @click="error">error</Button>
|
||||
<Button @click="update">update</Button>
|
||||
<br><br>
|
||||
<Page :total="100"></Page>
|
||||
<Page :total="100" show-sizer></Page>
|
||||
<Page :total="100" show-elevator></Page>
|
||||
<Page :total="100" show-total></Page>
|
||||
<br><br>
|
||||
<Page :current="2" :total="50" simple></Page>
|
||||
<br>
|
||||
<Page :total="400" size="small"></Page>
|
||||
<br>
|
||||
<Page :total="400" size="small" show-elevator show-sizer></Page>
|
||||
<br>
|
||||
<Page :total="400" size="small" show-total></Page>
|
||||
</div>
|
||||
<Collapse active-key="1">
|
||||
<Panel key="1">
|
||||
史蒂夫·乔布斯
|
||||
<p slot="content">史蒂夫·乔布斯(Steve Jobs),1955年2月24日生于美国加利福尼亚州旧金山,美国发明家、企业家、美国苹果公司联合创办人。</p>
|
||||
</Panel>
|
||||
<Panel key="2">
|
||||
斯蒂夫·盖瑞·沃兹尼亚克
|
||||
<p slot="content">斯蒂夫·盖瑞·沃兹尼亚克(Stephen Gary Wozniak),美国电脑工程师,曾与史蒂夫·乔布斯合伙创立苹果电脑(今之苹果公司)。斯蒂夫·盖瑞·沃兹尼亚克曾就读于美国科罗拉多大学,后转学入美国著名高等学府加州大学伯克利分校(UC Berkeley)并获得电机工程及计算机(EECS)本科学位(1987年)。</p>
|
||||
</Panel>
|
||||
<Panel key="3">
|
||||
乔纳森·伊夫
|
||||
<p slot="content">乔纳森·伊夫是一位工业设计师,现任Apple公司设计师兼资深副总裁,英国爵士。他曾参与设计了iPod,iMac,iPhone,iPad等众多苹果产品。除了乔布斯,他是对苹果那些著名的产品最有影响力的人。</p>
|
||||
</Panel>
|
||||
</Collapse>
|
||||
<Input-number :max="10" :min="1" :value="1" @on-change="change"></Input-number>
|
||||
<Input-number :max="10" :min="1" :step="1.2" :value="1"></Input-number>
|
||||
</template>
|
||||
<script>
|
||||
import { Tag, LoadingBar, Button, Progress, Icon, Timeline, Page } from 'iview';
|
||||
const ButtonGroup = Button.Group;
|
||||
const TimelineItem = Timeline.Item;
|
||||
import { Collapse, InputNumber } from 'iview';
|
||||
const Panel = Collapse.Panel;
|
||||
export default {
|
||||
components: {
|
||||
Tag,
|
||||
Button,
|
||||
Progress,
|
||||
ButtonGroup,
|
||||
Timeline,
|
||||
TimelineItem,
|
||||
Icon,
|
||||
Page
|
||||
},
|
||||
props: {
|
||||
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
percent: 0
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
||||
},
|
||||
components: { Collapse, Panel, InputNumber },
|
||||
methods: {
|
||||
start () {
|
||||
LoadingBar.start();
|
||||
},
|
||||
destroy () {
|
||||
LoadingBar.destroy();
|
||||
},
|
||||
finish () {
|
||||
LoadingBar.finish();
|
||||
},
|
||||
error () {
|
||||
LoadingBar.error();
|
||||
},
|
||||
update () {
|
||||
LoadingBar.update(50);
|
||||
},
|
||||
add () {
|
||||
if (this.percent >= 100) {
|
||||
return false;
|
||||
}
|
||||
this.percent += 10;
|
||||
},
|
||||
minus () {
|
||||
if (this.percent <= 0) {
|
||||
return false;
|
||||
}
|
||||
this.percent -= 10;
|
||||
change (data) {
|
||||
console.log(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</script>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "iview",
|
||||
"version": "0.9.3",
|
||||
"version": "0.9.4",
|
||||
"title": "iView",
|
||||
"description": "A high quality UI components Library with Vue.js",
|
||||
"homepage": "http://www.iviewui.com",
|
||||
|
@ -29,6 +29,7 @@
|
|||
"url": "https://github.com/iview/iview/issues"
|
||||
},
|
||||
"dependencies": {
|
||||
"popper.js": "^0.6.4",
|
||||
"vue": "^1.0.26"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
@ -24,4 +24,5 @@
|
|||
|
||||
@import "fade";
|
||||
@import "move";
|
||||
@import "ease";
|
||||
@import "ease";
|
||||
@import "slide";
|
119
styles/animation/slide.less
Normal file
119
styles/animation/slide.less
Normal file
|
@ -0,0 +1,119 @@
|
|||
.slide-motion(@className, @keyframeName) {
|
||||
.make-motion(@className, @keyframeName);
|
||||
.@{className}-enter, .@{className}-appear {
|
||||
opacity: 0;
|
||||
animation-timing-function: @ease-in-out;
|
||||
}
|
||||
.@{className}-leave {
|
||||
animation-timing-function: @ease-in-out;
|
||||
}
|
||||
}
|
||||
|
||||
.slide-motion(slide-up, ivuSlideUp);
|
||||
.slide-motion(slide-down, ivuSlideDown);
|
||||
.slide-motion(slide-left, ivuSlideLeft);
|
||||
.slide-motion(slide-right, ivuSlideRight);
|
||||
|
||||
@keyframes ivuSlideUpIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform-origin: 0% 0%;
|
||||
transform: scaleY(.8);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform-origin: 0% 0%;
|
||||
transform: scaleY(1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes ivuSlideUpOut {
|
||||
0% {
|
||||
opacity: 1;
|
||||
transform-origin: 0% 0%;
|
||||
transform: scaleY(1);
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
transform-origin: 0% 0%;
|
||||
transform: scaleY(.8);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes ivuSlideDownIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform-origin: 100% 100%;
|
||||
transform: scaleY(.8);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform-origin: 100% 100%;
|
||||
transform: scaleY(1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes ivuSlideDownOut {
|
||||
0% {
|
||||
opacity: 1;
|
||||
transform-origin: 100% 100%;
|
||||
transform: scaleY(1);
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
transform-origin: 100% 100%;
|
||||
transform: scaleY(.8);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes ivuSlideLeftIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform-origin: 0% 0%;
|
||||
transform: scaleX(.8);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform-origin: 0% 0%;
|
||||
transform: scaleX(1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes ivuSlideLeftOut {
|
||||
0% {
|
||||
opacity: 1;
|
||||
transform-origin: 0% 0%;
|
||||
transform: scaleX(1);
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
transform-origin: 0% 0%;
|
||||
transform: scaleX(.8);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes ivuSlideRightIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform-origin: 100% 0%;
|
||||
transform: scaleX(.8);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform-origin: 100% 0%;
|
||||
transform: scaleX(1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes ivuSlideRightOut {
|
||||
0% {
|
||||
opacity: 1;
|
||||
transform-origin: 100% 0%;
|
||||
transform: scaleX(1);
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
transform-origin: 100% 0%;
|
||||
transform: scaleX(.8);
|
||||
}
|
||||
}
|
|
@ -12,16 +12,20 @@
|
|||
font-style: normal;
|
||||
}
|
||||
|
||||
.ivu-icon() {
|
||||
display: inline-block;
|
||||
font-family: @ionicons-font-family;
|
||||
speak: none;
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
font-variant: normal;
|
||||
text-transform: none;
|
||||
text-rendering: auto;
|
||||
line-height: 1;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.ivu-icon {
|
||||
display: inline-block;
|
||||
font-family: @ionicons-font-family;
|
||||
speak: none;
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
font-variant: normal;
|
||||
text-transform: none;
|
||||
text-rendering: auto;
|
||||
line-height: 1;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
.ivu-icon();
|
||||
}
|
|
@ -19,4 +19,6 @@
|
|||
@import "timeline";
|
||||
@import "page";
|
||||
@import "steps";
|
||||
@import "modal";
|
||||
@import "modal";
|
||||
@import "select";
|
||||
@import "select-dropdown";
|
16
styles/components/select-dropdown.less
Normal file
16
styles/components/select-dropdown.less
Normal file
|
@ -0,0 +1,16 @@
|
|||
@select-dropdown-prefix-cls: ~"@{css-prefix}select-dropdown";
|
||||
|
||||
.@{select-dropdown-prefix-cls} {
|
||||
width: 100%;
|
||||
max-height: 200px;
|
||||
overflow: auto;
|
||||
margin: 5px 0;
|
||||
padding: 7px 0;
|
||||
background-color: #fff;
|
||||
box-sizing: border-box;
|
||||
border: 1px solid @border-color-base;
|
||||
border-radius: @btn-border-radius;
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,.2);
|
||||
position: absolute;
|
||||
z-index: @zindex-select;
|
||||
}
|
242
styles/components/select.less
Normal file
242
styles/components/select.less
Normal file
|
@ -0,0 +1,242 @@
|
|||
@select-prefix-cls: ~"@{css-prefix}select";
|
||||
@select-item-prefix-cls: ~"@{css-prefix}select-item";
|
||||
@select-group-prefix-cls: ~"@{css-prefix}select-group";
|
||||
|
||||
.@{select-prefix-cls} {
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
vertical-align: middle;
|
||||
color: @text-color;
|
||||
font-size: @font-size-base;
|
||||
position: relative;
|
||||
|
||||
&-selection {
|
||||
display: block;
|
||||
box-sizing: border-box;
|
||||
outline: none;
|
||||
user-select: none;
|
||||
cursor: pointer;
|
||||
|
||||
background-color: #fff;
|
||||
border-radius: @btn-border-radius;
|
||||
border: 1px solid @border-color-base;
|
||||
.transition(all @transition-time @ease-in-out);
|
||||
|
||||
.@{select-prefix-cls}-arrow:nth-of-type(1) {
|
||||
display: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.hover();
|
||||
.@{select-prefix-cls}-arrow:nth-of-type(1) {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-show-clear &-selection:hover .@{select-prefix-cls}-arrow:nth-of-type(2){
|
||||
display: none;
|
||||
}
|
||||
|
||||
&-arrow {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 8px;
|
||||
line-height: 1;
|
||||
margin-top: -6px;
|
||||
color: @border-color-base;
|
||||
.transition(all @transition-time @ease-in-out);
|
||||
}
|
||||
|
||||
&-visible{
|
||||
.@{select-prefix-cls}-selection{
|
||||
.active();
|
||||
}
|
||||
|
||||
.@{select-prefix-cls}-arrow:nth-of-type(2) {
|
||||
.transform(rotate(180deg));
|
||||
}
|
||||
}
|
||||
|
||||
&-disabled {
|
||||
.@{select-prefix-cls}-selection {
|
||||
.disabled();
|
||||
|
||||
.@{select-prefix-cls}-arrow:nth-of-type(1) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
border-color: @border-color-base;
|
||||
box-shadow: none;
|
||||
|
||||
.@{select-prefix-cls}-arrow:nth-of-type(2) {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-single &-selection{
|
||||
height: 28px;
|
||||
position: relative;
|
||||
|
||||
.@{select-prefix-cls}-placeholder{
|
||||
color: @input-placeholder-color;
|
||||
}
|
||||
|
||||
.@{select-prefix-cls}-placeholder, .@{select-prefix-cls}-selected-value{
|
||||
display: block;
|
||||
height: 26px;
|
||||
line-height: 26px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
padding-left: 8px;
|
||||
padding-right: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
&-large&-single &-selection{
|
||||
height: 32px;
|
||||
|
||||
.@{select-prefix-cls}-placeholder, .@{select-prefix-cls}-selected-value{
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
}
|
||||
}
|
||||
|
||||
&-small&-single &-selection{
|
||||
height: 22px;
|
||||
border-radius: @btn-border-radius-small;
|
||||
|
||||
.@{select-prefix-cls}-placeholder, .@{select-prefix-cls}-selected-value{
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
&-multiple &-selection{
|
||||
padding: 0 24px 0 2px;
|
||||
min-height: 28px;
|
||||
|
||||
.@{select-prefix-cls}-placeholder{
|
||||
display: block;
|
||||
height: 26px;
|
||||
line-height: 26px;
|
||||
color: @input-placeholder-color;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
padding-left: 8px;
|
||||
padding-right: 22px;
|
||||
}
|
||||
}
|
||||
|
||||
// input
|
||||
&-input{
|
||||
display: inline-block;
|
||||
height: @input-height-base;
|
||||
line-height: @input-height-base;
|
||||
padding: 0 24px 0 8px;
|
||||
font-size: @font-size-base;
|
||||
outline: none;
|
||||
border: none;
|
||||
box-sizing: border-box;
|
||||
color: @input-color;
|
||||
background-color: transparent;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
.placeholder();
|
||||
}
|
||||
|
||||
&-single &-input{
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
&-large &-input{
|
||||
height: @input-height-large;
|
||||
}
|
||||
|
||||
&-small &-input{
|
||||
height: @input-height-small;
|
||||
}
|
||||
}
|
||||
|
||||
.@{select-item-prefix-cls} {
|
||||
margin: 0;
|
||||
padding: 7px 15px;
|
||||
clear: both;
|
||||
color: @text-color;
|
||||
//border-radius: @btn-border-radius-small;
|
||||
white-space: nowrap;
|
||||
cursor: pointer;
|
||||
.transition(background @transition-time @ease-in-out);
|
||||
|
||||
&:hover{
|
||||
background: @background-color-select-hover;
|
||||
}
|
||||
|
||||
&-focus {
|
||||
background: @background-color-select-hover;
|
||||
}
|
||||
|
||||
&-disabled {
|
||||
color: @btn-disable-color;
|
||||
cursor: @cursor-disabled;
|
||||
|
||||
&:hover {
|
||||
color: @btn-disable-color;
|
||||
background-color: #fff;
|
||||
cursor: @cursor-disabled;
|
||||
}
|
||||
}
|
||||
|
||||
&-selected ,&-selected:hover{
|
||||
color: #fff;
|
||||
background: @selected-color;
|
||||
}
|
||||
|
||||
&-selected&-focus {
|
||||
background: shade(@selected-color, 10%);
|
||||
}
|
||||
}
|
||||
|
||||
.@{select-prefix-cls}-multiple .@{select-item-prefix-cls} {
|
||||
&-selected{
|
||||
color: @selected-color;
|
||||
background: #fff;
|
||||
}
|
||||
&-focus,&-selected:hover{
|
||||
background: @background-color-select-hover;
|
||||
}
|
||||
|
||||
&-selected&-focus {
|
||||
color: shade(@selected-color, 10%);
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
&-selected:after{
|
||||
.ivu-icon();
|
||||
float: right;
|
||||
font-size: 24px;
|
||||
content: '\F3FD';
|
||||
color: @selected-color;
|
||||
}
|
||||
}
|
||||
|
||||
.@{select-group-prefix-cls} {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
&-title {
|
||||
padding-left: 10px;
|
||||
font-size: 12px;
|
||||
color: @legend-color;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
}
|
||||
}
|
|
@ -10,6 +10,7 @@
|
|||
@link-color : #0099e5;
|
||||
@link-hover-color : tint(@link-color, 20%);
|
||||
@link-active-color : shade(@link-color, 5%);
|
||||
@selected-color : fade(@primary-color, 90%);
|
||||
|
||||
// Base
|
||||
@body-background : #fff;
|
||||
|
@ -28,7 +29,8 @@
|
|||
@border-color-split : #e9e9e9; // inside
|
||||
|
||||
// Background color
|
||||
@background-color-base : #f7f7f7; // base
|
||||
@background-color-base : #f7f7f7; // base
|
||||
@background-color-select-hover: @input-disabled-bg;
|
||||
|
||||
// Shadow
|
||||
@shadow-color : rgba(100, 100, 100, .2);
|
||||
|
@ -102,6 +104,7 @@
|
|||
@zindex-spin : 8;
|
||||
@zindex-affix : 10;
|
||||
@zindex-back-top : 10;
|
||||
@zindex-select : 900;
|
||||
@zindex-modal : 1000;
|
||||
@zindex-message : 1010;
|
||||
@zindex-notification : 1010;
|
||||
|
|
Loading…
Add table
Reference in a new issue