Browse Source

开发dropdown组件

songqibin 7 years ago
parent
commit
9af2ed4000

+ 6 - 0
config.json

@@ -14,6 +14,12 @@
       "desc": "一种对话框,支持按钮交互。"
     },
     {
+      "name": "Dropdown",
+      "chnName": "下拉选择",
+      "type": "component",
+      "desc": "下拉选择组件"
+    },
+    {
       "name": "Toast",
       "chnName": "无焦点提示",
       "type": "method",

+ 27 - 0
src/demo/dropdown.vue

@@ -0,0 +1,27 @@
+<template>
+    <div>
+        <nut-dropdown ></nut-dropdown>
+    </div>
+</template>
+
+<script>
+//import jsonp from 'jsonp';
+
+export default {
+    data(){
+      return {
+       
+      }
+    },
+    methods:{
+        
+    },
+    mounted(){
+
+    }
+}
+</script>
+
+<style>
+
+</style>

+ 7 - 0
src/package/dropdown/index.js

@@ -0,0 +1,7 @@
+import DropDown from './src/dropdown.vue';
+
+DropDown.install = function(Vue) {
+  Vue.component(DropDown.name, DropDown);
+};
+
+export default DropDown

+ 249 - 0
src/package/dropdown/src/dropdown.vue

@@ -0,0 +1,249 @@
+<template>
+	<div id="nut-dropdown" class="nut-dropdown" tabIndex='-1' @blur="handleBlur" ref="dropdown">
+		<div class="default-select" @click="handleToggleShowOptions">
+			<input v-show="inputShow" v-model="searchText" @click.stop="handleInputClick" type="text" placeholder="请输入过滤条件" class="search-input">
+			<span v-show="!inputShow" class="selected">{{showSelected}}</span>
+			<img :class='["arrow", optionsShow ? "up" : ""]' src='./img/arrow.png' @click.stop="handleToggleShowOptions"/>
+		</div>
+		<div v-show="optionsShow" class='select-options'>
+			<div class='option' v-for="(option, index) in showOptions" :key='index' @click="handleItemClick(option)">
+				<i :class="[isSelected(option) ? 'active' : '']"></i>  <span>{{ optionKey ? option[optionKey] :option}}</span>
+			</div>
+		</div>
+	</div>
+</template>
+<script>
+export default {
+	name:'nut-dropdown',
+	props: {
+		// 默认选中的option
+		defaultSelected: {
+			// type: String,
+			// default: '请选择'
+		},
+		// options,必须是数组,必传
+		options: {
+			type: Array,
+			required: true
+		},
+		// option 展示的数据类型,适用于option是对象的时候 展示内容即为option对象key的值
+		optionKey: {
+			type: String
+		},
+		// 是否支持多选
+		multiple: {
+			type: Boolean,
+			default: false
+		},
+		// 是否支持搜索
+		search: {
+			type: Boolean,
+			default: false
+		}
+
+	},
+	data() {
+		return {
+			optionsShow: false,
+			// showSelected: this.defaultSelected,
+			selected: '',
+			inputShow: false,
+			multipleSelected: [],
+			searchText: ''
+		};
+	},
+	computed: {
+		showSelected() {
+			let _txt = ''
+			if (this.optionKey) {
+				if (this.multiple) {
+					_txt = this.multipleSelected.map(item => item[this.optionKey]).join('、')
+				}	else {
+					_txt = this.selected[this.optionKey]
+				}	
+			} else {
+				if (this.multiple) {
+					_txt = this.multipleSelected.join('、')
+				} else {
+					_txt = this.selected
+				}
+			}
+			return _txt || '请选择'
+		},
+		showOptions() {
+			let _options = this.options
+			// 支持搜索的同时处于搜索状态
+			if (this.search && this.inputShow) {
+				if (this.optionKey) {
+					_options = this.options.filter(item => item[this.optionKey].includes(this.searchText))
+				} else {
+					_options = this.options.filter(item => item.includes(this.searchText))
+				}
+			}
+			return _options
+		}
+	},
+	methods: {
+		handleBlur() {
+			if (this.inputShow) return
+			if (this.optionsShow) {
+				this.optionsShow = false
+			}
+			if (this.inputShow) {
+				this.inputShow = false
+			}
+		},
+		
+		handleToggleShowOptions() {
+			if (this.search) {
+				if (this.inputShow) {
+					this.optionsShow = false
+					this.inputShow = false
+					this.searchText = ''
+					return
+				}
+				this.inputShow = true
+				this.optionsShow = true
+				return
+			}
+			this.optionsShow = !this.optionsShow
+		},
+
+		handleInputClick() {
+			// console.log(111)
+		},
+	
+		handleItemClick(option) {
+			if (this.multiple) {
+				if (this.optionKey) {
+					if(this.multipleSelected.some(item => item[this.optionKey] === option[this.optionKey])){
+						this.multipleSelected = this.multipleSelected.filter(item => item[this.optionKey] !== option[this.optionKey])
+					} else {
+						this.multipleSelected.push(option)
+					}
+				} else {
+						if(this.multipleSelected.includes(option)){
+						this.multipleSelected = this.multipleSelected.filter(item => item !== option)
+					} else {
+						this.multipleSelected.push(option)
+					}
+				}
+				this.$emit('selectedChange', this.multipleSelected);
+			} else {
+				this.selected = option
+				this.handleToggleShowOptions()
+				this.$emit('selectedChange', this.selected);
+			}
+		},
+		isSelected(option) {
+			let _selected = false
+			if (this.optionKey) {
+				if (this.multiple) {
+					_selected = this.multipleSelected.some(item => item[this.optionKey] === option[this.optionKey])
+				} else {
+					_selected = this.selected[this.optionKey] === option[this.optionKey]
+				}
+			} else {
+				if (this.multiple) {
+					_selected = this.multipleSelected.includes(option)
+				} else {
+					_selected = this.selected === option
+				}
+			}
+			return _selected
+		}
+	},
+	mounted() {
+		if (this.defaultSelected) {
+			if (this.multiple) {
+				this.multipleSelected = this.defaultSelected
+			} else {
+				this.selected = this.defaultSelected
+			}
+		} else {
+			if (this.optionKey) {
+				this.selected = {}
+			}
+		}
+	}
+}
+</script>
+<style lang="scss" scoped>
+* {
+	box-sizing: border-box;
+}
+.nut-dropdown{
+	outline: none;
+	width: 200px;
+	height: 30px;
+	background: #409eff;
+	border-radius: 5px;
+	position: relative;
+	.default-select {
+		width: 100%;
+		height: 100%;
+		padding: 0 20px;
+		display: flex;
+		justify-content: space-between;
+		align-items: center;
+		.selected {
+			overflow: hidden;
+			white-space: nowrap;
+			text-overflow: ellipsis;
+		}
+		.search-input {
+			width: 100%;
+			height: 100%;
+			outline: none;
+			border: none;
+			padding: 0;
+			transform: translateY(9px);
+			background: transparent;
+		}
+		.arrow {
+			width: 14px;
+			height: 8px;
+			transform: rotateX(180deg);
+			transform-origin: 50% 50%;
+			transition: transform 0.4s;
+			&.up {
+					transform: rotateX(0deg);
+			}
+		}
+	}
+	.select-options {
+		position: absolute;
+		z-index: 999;
+		top: 100%;
+		// height: 200px;
+		left: 0;
+		width: 100%;
+		padding: 10px 0;
+		background: #ffffff;
+		border: 1px solid #d7d7d7;
+		border-radius: 5px;
+
+		.option {
+			display: flex;
+			align-items: center;
+			line-height: 30px;
+			font-size: 14px;
+			padding: 0 20px;
+			cursor: pointer;
+			&:hover {
+				background: #ecf5ff;
+			}
+			i {
+				width: 16px;
+				height: 16px;
+				border: 1px solid #d7d7d7;
+				margin-right: 8px;
+				&.active {
+						border: none;
+						background: url(./img/complate.png) #409eff no-repeat center center;
+				}
+			}
+		}
+	}
+}
+</style>

BIN
src/package/dropdown/src/img/arrow.png


BIN
src/package/dropdown/src/img/complate.png


+ 174 - 0
src/view/dropdown.vue

@@ -0,0 +1,174 @@
+<template>
+    <div>
+        <nut-docheader 
+        :name="$route.name"
+        :showQrCode="true"></nut-docheader>
+        <h5>示例</h5>
+        <h6>通用数据代码和回调示例</h6>
+        <nut-codebox :code="code"></nut-codebox>
+
+        <h6>示例1: 单选、简单数组</h6>
+        <nut-dropdown :options="options" @selectedChange='multipleSelected'></nut-dropdown>
+        <nut-codebox :code="demo1"></nut-codebox>
+
+        <h6>示例2: 单选、简单数组、设置默认值</h6>
+        <nut-dropdown :options="options" @selectedChange='multipleSelected' defaultSelected='二'></nut-dropdown>
+        <nut-codebox :code="demo2"></nut-codebox>
+
+        <h6>示例3: 多选、简单数组</h6>
+        <nut-dropdown :options="options" multiple @selectedChange='selectedChange'></nut-dropdown>
+        <nut-codebox :code="demo3"></nut-codebox>
+
+        <h6>示例4: 多选、简单数组、设置默认值</h6>
+        <nut-dropdown :options="options" multiple @selectedChange='selectedChange' :defaultSelected="['一','二']"></nut-dropdown>
+        <nut-codebox :code="demo4"></nut-codebox>
+
+        <h6>示例5: 单选、复杂对象数组、自定义展示字段</h6>
+        <nut-dropdown :options="options2" @selectedChange='selectedChange' optionKey='name'></nut-dropdown>
+        <nut-codebox :code="demo5"></nut-codebox>
+
+        <h6>示例6: 多选、复杂对象数组、自定义展示字段</h6>
+        <nut-dropdown :options="options2" multiple @selectedChange='selectedChange' optionKey='name'></nut-dropdown>
+        <nut-codebox :code="demo6"></nut-codebox>
+
+        <h6>示例7: 单选、复杂对象数组、自定义展示字段、设置默认值</h6>
+        <nut-dropdown :options="options2" @selectedChange='selectedChange' optionKey='name' :defaultSelected="{name: '李四', id: 2}"></nut-dropdown>
+        <nut-codebox :code="demo7"></nut-codebox>
+
+        <h6>示例8: 多选、复杂对象数组、自定义展示字段、设置默认值</h6>
+        <nut-dropdown :options="options2" multiple @selectedChange='selectedChange' optionKey='name' :defaultSelected="[{name: '李四', id: 2}]"></nut-dropdown>
+        <nut-codebox :code="demo8"></nut-codebox>
+
+        <h6>示例9: 多选、复杂对象数组、自定义展示字段、支持搜索</h6>
+        <nut-dropdown :options="options2" multiple @selectedChange='selectedChange' optionKey='name' search></nut-dropdown>
+        <nut-codebox :code="demo9"></nut-codebox>
+
+        <h6>示例10: 单选、简单数组、支持搜索</h6>
+        <nut-dropdown :options="options" @selectedChange='selectedChange' search></nut-dropdown>
+        <nut-codebox :code="demo10"></nut-codebox>
+
+        <h5>Props</h5>
+        <div class="tbl-wrapper">
+        <table class="u-full-width">
+          <thead>
+            <tr>
+              <th>参数</th>
+              <th>说明</th>
+              <th>类型</th>
+              <th>默认值</th>
+              <th>是否必传</th>
+            </tr>
+          </thead>
+          <tbody>
+            <tr>
+              <td>defaultSelected</td>
+              <td>默认选中得值,单选传入单个得数据项,多选传入数组</td>
+              <td>any</td>
+              <td>--</td>
+              <td>否</td>
+            </tr>
+            <tr>
+              <td>options</td>
+              <td>下拉项options数组,可以是简单数组,也可以是复杂对象数组</td>
+              <td>Array</td>
+              <td>--</td>
+              <td>是</td>
+            </tr>
+            <tr>
+              <td>optionKey</td>
+              <td>当options参数是复杂对象数组的时候,传入option展示的字段名</td>
+              <td>String</td>
+              <td>--</td>
+              <td>当options参数是复杂对象数组的时,必须</td>
+            </tr>
+            <tr>
+              <td>multiple</td>
+              <td>是否支持多选</td>
+              <td>Boolean</td>
+              <td>false</td>
+              <td>true/false</td>
+            </tr>
+            <tr>
+              <td>search</td>
+              <td>是否启用组件的搜索过滤选项功能</td>
+              <td>Boolean</td>
+              <td>false</td>
+              <td>true/false</td>
+            </tr>
+            
+          </tbody>
+        </table>
+        </div>
+
+        <h5>Events</h5>
+        <div class="tbl-wrapper">
+        <table class="u-full-width">
+          <thead>
+            <tr>
+              <th>事件名</th>
+              <th>说明</th>
+              <th>回调参数</th>
+            </tr>
+          </thead>
+          <tbody>
+            <tr>
+              <td>selectedChange</td>
+              <td>当选中的option发生改变的时候触发</td>
+              <td>被选中的option值,多选的时候返回选中项组成的数组</td>
+            </tr>
+          </tbody>
+        </table>
+        </div>
+    </div>
+
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      options: ['一','二','三','四'],
+      options2: [{name: '张三', id: 1}, {name: '李四', id: 2}, {name: '王五', id: 3}, {name: '马六', id: 4}, {name: '王八蛋', id: 5}],
+      code: `
+        export default {
+          data() {
+            retuen {
+              options: ['一','二','三','四'],
+              options2: [{name: '张三', id: 1}, {name: '李四', id: 2}, {name: '王五', id: 3}, {name: '马六', id: 4}, {name: '王八蛋', id: 5}],
+            }
+          },
+          methods: {
+            selectedChange(option) {
+              console.log(option)
+            },
+          }
+        }
+      `,
+      demo1: `<nut-dropdown :options="options" @selectedChange='multipleSelected'></nut-dropdown>`,
+      demo2: `<nut-dropdown :options="options" @selectedChange='selectedChange' defaultSelected='二'></nut-dropdown>`,
+      demo3: `<nut-dropdown :options="options" multiple @selectedChange='selectedChange'></nut-dropdown>`,
+      demo4: `<nut-dropdown :options="options" multiple @selectedChange='selectedChange' :defaultSelected="['一','二']"></nut-dropdown>`,
+      demo5: `<nut-dropdown :options="options2" @selectedChange='selectedChange' optionKey='name' ></nut-dropdown>`,
+      demo6: `<nut-dropdown :options="options2" multiple @selectedChange='selectedChange' optionKey='name'></nut-dropdown>`,
+      demo7: `<nut-dropdown :options="options2" @selectedChange='selectedChange' optionKey='name' :defaultSelected="{name: '李四', id: 2}"></nut-dropdown>`,
+      demo8: `<nut-dropdown :options="options2" multiple @selectedChange='selectedChange' optionKey='name' :defaultSelected="[{name: '李四', id: 2}]"></nut-dropdown>`,
+      demo9: `<nut-dropdown :options="options2" multiple @selectedChange='selectedChange' optionKey='name' search></nut-dropdown>`,
+      demo10: `<nut-dropdown :options="options" @selectedChange='selectedChange' search></nut-dropdown>`
+    };
+  },
+  mounted(){
+  },
+  methods: {
+    selectedChange(option) {
+      console.log(option)
+    },
+    multipleSelected(options) {
+      console.log(options)
+    }
+  }
+};
+</script>
+
+<style lang="scss">
+
+</style>