ivue-material-plus
Version:
A high quality UI components Library with Vue.js
1 lines • 11.1 kB
Source Map (JSON)
{"version":3,"file":"option.mjs","sources":["../../../../../src/components/ivue-select/option.vue"],"sourcesContent":["<template>\r\n <li\r\n v-show=\"data.visible\"\r\n :data-visible=\"data.visible\"\r\n data-select=\"select-item\"\r\n :class=\"classes\"\r\n :style=\"styles\"\r\n v-ripple=\"ripple\"\r\n @click.stop=\"handleOptionClick\"\r\n @mousedown.prevent\r\n @mouseenter=\"handleMouseenter\"\r\n @mouseleave=\"handleMouseleave\"\r\n >\r\n <slot>{{ showLabel }}</slot>\r\n </li>\r\n</template>\r\n\r\n<script lang=\"ts\">\r\nimport {\r\n defineComponent,\r\n computed,\r\n getCurrentInstance,\r\n inject,\r\n reactive,\r\n onBeforeUnmount,\r\n onMounted,\r\n nextTick,\r\n} from 'vue';\r\n\r\nimport ripple from '../../utils/directives/ripple';\r\n\r\n// type\r\nimport { Props, Data } from './types/option';\r\nimport { SelectContextKey, OptionInstance } from './types/select';\r\nimport { SelectGroupContextKey } from './types/option-group';\r\n\r\nconst prefixCls = 'ivue-select-item';\r\n\r\nfunction isCssColor(color: string) {\r\n return !!color && !!color.match(/^(#|(rgb|hsl)a?\\()/);\r\n}\r\n\r\nexport default defineComponent({\r\n name: 'ivue-option',\r\n componentName: 'ivue-select-item',\r\n directives: {\r\n ripple,\r\n },\r\n props: {\r\n /**\r\n * 启用/禁用涟漪\r\n *\r\n * @type {Boolean}\r\n */\r\n ripple: {\r\n type: Boolean,\r\n default: false,\r\n },\r\n /**\r\n * 是否禁用选项\r\n *\r\n * @type {Boolean}\r\n */\r\n disabled: {\r\n type: Boolean,\r\n default: false,\r\n },\r\n /**\r\n * 是否选择当前项\r\n *\r\n * @type {Boolean}\r\n */\r\n selected: {\r\n type: Boolean,\r\n default: false,\r\n },\r\n /**\r\n * 是否获取到焦点\r\n *\r\n * @type {Boolean}\r\n */\r\n isFocused: {\r\n type: Boolean,\r\n default: false,\r\n },\r\n /**\r\n * 渲染的 label\r\n *\r\n * @type {String, Number}\r\n */\r\n label: {\r\n type: [String, Number],\r\n },\r\n /**\r\n * 渲染的 value\r\n *\r\n * @type {String, Number}\r\n */\r\n value: {\r\n type: [String, Number],\r\n },\r\n /**\r\n * 选择选项时的颜色\r\n *\r\n * @type {String | Array}\r\n */\r\n selectedColor: {\r\n type: [String, Array],\r\n },\r\n /**\r\n * hover 选择选项时的颜色\r\n *\r\n * @type {String | Array}\r\n */\r\n hoverColor: {\r\n type: [String, Array],\r\n },\r\n /**\r\n * 是否允许用户创建新条目,需开启 filterable\r\n *\r\n * @type {Boolean}\r\n */\r\n allowCreate: {\r\n type: Boolean,\r\n default: false,\r\n },\r\n /**\r\n * 显示创建的选项\r\n *\r\n * @type {Boolean}\r\n */\r\n showCreateItem: {\r\n type: Boolean,\r\n default: false,\r\n },\r\n /**\r\n * 输入框输入数据\r\n *\r\n * @type {String}\r\n */\r\n filterQuery: {\r\n type: String,\r\n default: '',\r\n },\r\n },\r\n setup(props: Props, { emit }) {\r\n // inject\r\n const select = inject(SelectContextKey);\r\n\r\n // 有选项组\r\n const selectGroup = inject(SelectGroupContextKey, {\r\n disabled: false,\r\n });\r\n\r\n // data\r\n const data = reactive<Data>({\r\n /**\r\n * 是否获取到焦点\r\n *\r\n * @type {Boolean}\r\n */\r\n isFocused: false,\r\n /**\r\n * 是否禁用选项\r\n *\r\n * @type {Boolean}\r\n */\r\n disabled: props.disabled,\r\n /**\r\n * 鼠标悬浮\r\n *\r\n * @type {Boolean}\r\n */\r\n hasMouseHover: false,\r\n /**\r\n * 是否显示\r\n *\r\n * @type {Boolean}\r\n */\r\n visible: true,\r\n });\r\n\r\n // vm\r\n const { proxy } = getCurrentInstance();\r\n\r\n // computed\r\n\r\n // classes\r\n const classes = computed(() => {\r\n return [\r\n prefixCls,\r\n {\r\n [`${prefixCls}-disabled`]: isDisabled.value,\r\n [`${prefixCls}-focus`]: data.isFocused,\r\n [`${prefixCls}-selected`]:\r\n itemSelected.value && !select.props.autoComplete,\r\n },\r\n ];\r\n });\r\n\r\n // styles\r\n const styles = computed(() => {\r\n let obj = {};\r\n\r\n // 单选触发\r\n if (\r\n (itemSelected.value && !select.props.autoComplete) ||\r\n data.isFocused\r\n ) {\r\n // 单选\r\n if (!select.props.multiple) {\r\n obj = {\r\n ...obj,\r\n ...setBackgroundColor(select.props.selectedColor),\r\n };\r\n }\r\n // 多选\r\n else {\r\n if (data.isFocused) {\r\n obj = {\r\n ...obj,\r\n ...setBackgroundColor(select.props.selectedColor),\r\n };\r\n } else {\r\n obj = {\r\n ...obj,\r\n ...setTextColor(select.props.selectedColor),\r\n };\r\n }\r\n }\r\n }\r\n\r\n // 鼠标悬浮\r\n if (data.hasMouseHover && !isDisabled.value) {\r\n // 单选\r\n if (!select.props.multiple) {\r\n obj = {\r\n ...obj,\r\n ...setBackgroundColor(props.hoverColor || select.props.hoverColor),\r\n };\r\n }\r\n // 多选\r\n else {\r\n obj = {\r\n ...obj,\r\n ...setBackgroundColor(\r\n props.selectedColor || select.props.selectedColor\r\n ),\r\n color: '#ffffff',\r\n };\r\n }\r\n }\r\n\r\n return obj;\r\n });\r\n\r\n // 是否禁用\r\n const isDisabled = computed(() => {\r\n return data.disabled || selectGroup.disabled;\r\n });\r\n\r\n // 是否显示label\r\n const showLabel = computed(() => {\r\n return props.label ? props.label : props.value;\r\n });\r\n\r\n // 获取label\r\n const getLabel = computed(() => {\r\n return props.label || proxy.$el.textContent;\r\n });\r\n\r\n // 当前选项是否激活\r\n const itemSelected = computed(() => {\r\n // 单选激活\r\n if (!select.props.multiple) {\r\n return isEqual(props.value, select.props.modelValue);\r\n }\r\n // 多选激活\r\n else {\r\n return contains(select.props.modelValue, props.value);\r\n }\r\n });\r\n\r\n // computed\r\n const isObject = computed(() => {\r\n return (\r\n Object.prototype.toString.call(props.value).toLowerCase() ===\r\n '[object object]'\r\n );\r\n });\r\n\r\n // methods\r\n\r\n // 点击选项\r\n const handleOptionClick = () => {\r\n // 禁用\r\n if (isDisabled.value) {\r\n return;\r\n }\r\n\r\n // 开启了创建列表\r\n if (props.allowCreate) {\r\n handleCreateItem();\r\n }\r\n // 普通点击\r\n else {\r\n select.handleOptionClick({\r\n value: props.value,\r\n label: getLabel.value,\r\n });\r\n }\r\n };\r\n\r\n // 创建新列表\r\n const handleCreateItem = () => {\r\n if (\r\n props.allowCreate &&\r\n props.filterQuery !== '' &&\r\n props.showCreateItem\r\n ) {\r\n emit('on-create');\r\n }\r\n };\r\n\r\n // 两个值是否相等\r\n const isEqual = (a: string | number, b: string | number) => {\r\n if (!isObject.value) {\r\n return a === b;\r\n }\r\n };\r\n\r\n // 是否包含元素\r\n const contains = (\r\n arr: (string | number)[] = [],\r\n target: string | number\r\n ) => {\r\n if (!isObject.value) {\r\n return arr && arr.indexOf(target) > -1;\r\n }\r\n };\r\n\r\n // 设置背景颜色\r\n const setBackgroundColor = (color: string | string[]) => {\r\n let style = {};\r\n\r\n // 是否是数组\r\n if (Array.isArray(color)) {\r\n style = {\r\n background: `linear-gradient(135deg,${color[0]} 0%, ${color[1]} 100%)`,\r\n color: '#fff',\r\n };\r\n } else if (isCssColor(color)) {\r\n style = {\r\n 'background-color': `${color}`,\r\n color: '#fff',\r\n };\r\n }\r\n\r\n return style;\r\n };\r\n\r\n // 设置文字颜色\r\n const setTextColor = (color: string | string[]) => {\r\n let style = {};\r\n\r\n // 是否是数组\r\n if (Array.isArray(color)) {\r\n style = {\r\n color: `${color[0]}`,\r\n };\r\n } else if (isCssColor(`${color}`)) {\r\n style = {\r\n color: `${color}`,\r\n };\r\n }\r\n\r\n return style;\r\n };\r\n\r\n // 鼠标进入\r\n const handleMouseenter = () => {\r\n if (!select.dropVisible) {\r\n return;\r\n }\r\n\r\n data.hasMouseHover = true;\r\n };\r\n\r\n // 鼠标离开\r\n const handleMouseleave = () => {\r\n data.hasMouseHover = false;\r\n };\r\n\r\n // onMounted\r\n onMounted(() => {\r\n if (!props.allowCreate) {\r\n // 插入dom\r\n select.options.push(proxy as OptionInstance);\r\n }\r\n });\r\n\r\n // onBeforeUnmount\r\n onBeforeUnmount(() => {\r\n nextTick(() => {\r\n select.onOptionDestroy(\r\n select.options.map((item) => item.value).indexOf(props.value)\r\n );\r\n });\r\n });\r\n\r\n return {\r\n // data,\r\n data,\r\n\r\n // computed\r\n classes,\r\n styles,\r\n showLabel,\r\n getLabel,\r\n itemSelected,\r\n isDisabled,\r\n\r\n // methods\r\n handleOptionClick,\r\n handleMouseenter,\r\n handleMouseleave,\r\n setBackgroundColor,\r\n };\r\n },\r\n});\r\n</script>\r\n"],"names":["_resolveDirective","_withDirectives","_openBlock","_createElementBlock","_normalizeClass","_normalizeStyle","_withModifiers","_vShow"],"mappings":";;;;;;AACE,EAAA,MAAA,iBAAA,GAAAA,iBAAA,QAAA,CAAA,CAAA;AAGE,EAAA,OAAAC,cAAY,EAAAC,SAAA,EAAa,EAAAC,kBAAA,CAAA,IAAA,EAAA;AAAA,IACxB,cAAA,EAAK,KAAE,IAAA,CAAA,OAAA;AAAA,IACP,aAAK,EAAA,aAAA;AAAA,IAEL,KAAA,EAAKC,cAAA,CAAA,IAAA,CAAA,OAAA,CAAA;AAAA,IACL,KAAA,EAASC,cAAA,CAAA,IAAA,CAAA,MAAA,CAAA;AAAA,IACT,SAAA,MAAU,CAAA,CAAA,CAAA,gCAAE,GAAA,IAAA,KAAgB,IAAA,CAAA,iBAAA,IAAA,KAAA,iBAAA,CAAA,GAAA,IAAA,CAAA,EAAA,CAAA,MAAA,CAAA,CAAA,CAAA;AAAA,IAC5B,aAAU,MAAE,CAAA,CAAA,CAAA,KAAA,MAAA,CAAA,CAAA,CAAA,GAAAC,cAAA,MAAA;AAAA,KAAA,EAAA,CAAA,SAAA,CAAA,CAAA,CAAA;AAAA,IAAA,YAAA,EAAA,MAAA,CAAA,CAAA,CAAA,KAAA,MAAA,CAAA,CAAA,CAAA,GAAA,CAAA,GAAA,IAAA,KAAA,IAAA,CAAA,gBAAA,IAAA,IAAA,CAAA,gBAAA,CAAA,GAAA,IAAA,CAAA,CAAA;AAAA,IAEb,YAA4B,EAAA,MAAA,gBAA5B,CAAA,GAAA,CAAA,GAA4B,IAAA,KAAA,IAAA,CAAA,gBAAA,IAAA,IAAA,CAAA,gBAAA,CAAA,GAAA,IAAA,CAAA,CAAA;AAAA,GAAA,EAAA;AAAA;;;GANZ,EAAA,EAAA,EAAA,UAAA,CAAA,GAAA;AAAA,IAAA,CAAAC,KAAA,EAAA,IAAA,CAAA,IAAA,CAAA,OAAA,CAAA;AAAA;;;;;;;"}