|
|
@ -1,31 +1,41 @@
|
|
|
|
import PropTypes from 'ant-design-vue/es/_util/vue-types'
|
|
|
|
// 从 'ant-design-vue/es/_util/vue-types' 模块中导入 PropTypes,它通常用于定义 Vue 组件的属性(props)类型验证相关功能,类似于 React 中的 PropTypes,可帮助确保传入组件的属性符合预期的类型要求。
|
|
|
|
import Option from './TagSelectOption.jsx'
|
|
|
|
import PropTypes from 'ant-design-vue/es/_util/vue-types';
|
|
|
|
import { filterEmpty } from '../../components/_util/util'
|
|
|
|
// 从当前目录下的 'TagSelectOption.jsx' 文件中导入 Option 组件(具体该组件的功能要看其内部定义,但大概率是与 TagSelect 组件相关的一个选项组件,可能用于展示单个可选择的标签选项等)。
|
|
|
|
|
|
|
|
import Option from './TagSelectOption.jsx';
|
|
|
|
|
|
|
|
// 从 '../../components/_util/util' 模块中导入 filterEmpty 函数,从函数名推测它可能用于过滤空值或者无效的元素,也许是对传入的插槽内容等数据进行预处理,去除空元素的操作。
|
|
|
|
|
|
|
|
import { filterEmpty } from '../../components/_util/util';
|
|
|
|
|
|
|
|
|
|
|
|
export default {
|
|
|
|
export default {
|
|
|
|
|
|
|
|
// 将导入的 Option 组件注册到当前组件中,使得在该组件的模板或其他地方可以直接使用 <Option> 标签来调用这个组件,具体用法和功能取决于 Option 组件本身的定义。
|
|
|
|
Option,
|
|
|
|
Option,
|
|
|
|
name: 'TagSelect',
|
|
|
|
name: 'TagSelect',
|
|
|
|
|
|
|
|
// 定义组件的 v-model 绑定相关配置,指定了绑定的属性名为 'checked',触发的事件名为 'change'。这意味着在使用该组件时,如果要进行双向数据绑定(类似 Vue 中常见的 v-model 用法),外部数据的变化会通过 'change' 事件传递进来更新内部的 'checked' 属性,同时内部 'checked' 属性的变化也会通过触发 'change' 事件通知外部进行相应更新。
|
|
|
|
model: {
|
|
|
|
model: {
|
|
|
|
prop: 'checked',
|
|
|
|
prop: 'checked',
|
|
|
|
event: 'change'
|
|
|
|
event: 'change'
|
|
|
|
},
|
|
|
|
},
|
|
|
|
props: {
|
|
|
|
props: {
|
|
|
|
|
|
|
|
// 定义 prefixCls 属性,类型为字符串,用于设置组件的类名前缀,默认值是 'ant-pro-tag-select',通过这个前缀可以方便地对组件添加自定义样式,外部传入不同的前缀可以改变样式应用的类名基础,便于样式定制和主题切换等操作。
|
|
|
|
prefixCls: {
|
|
|
|
prefixCls: {
|
|
|
|
type: String,
|
|
|
|
type: String,
|
|
|
|
default: 'ant-pro-tag-select'
|
|
|
|
default: 'ant-pro-tag-select'
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
// 定义 defaultValue 属性,类型为通过 PropTypes.array 定义的数组类型(借助导入的 PropTypes 进行类型验证),用于设置组件的默认值(通常是初始状态下选中项等相关数据),默认值为 null,表示如果外部没有传入该属性值,初始状态下对应的值为 null,后续可能根据业务逻辑进行相应处理(比如使用空数组等其他默认情况)。
|
|
|
|
defaultValue: {
|
|
|
|
defaultValue: {
|
|
|
|
type: PropTypes.array,
|
|
|
|
type: PropTypes.array,
|
|
|
|
default: null
|
|
|
|
default: null
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
// 定义 value 属性,同样类型为通过 PropTypes.array 定义的数组类型,用于接收外部传入的当前值(比如选中项的数组等情况),默认值为 null,与 defaultValue 类似,但它更侧重于外部动态传入的值来控制组件的当前状态,在双向数据绑定等场景中会经常用到。
|
|
|
|
value: {
|
|
|
|
value: {
|
|
|
|
type: PropTypes.array,
|
|
|
|
type: PropTypes.array,
|
|
|
|
default: null
|
|
|
|
default: null
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
// 定义 expandable 属性,类型为布尔值,用于控制组件是否可展开(具体展开的功能和表现形式要看组件内部实现,可能是展开更多选项、显示隐藏部分内容等相关操作),默认值为 false,表示默认情况下组件不可展开。
|
|
|
|
expandable: {
|
|
|
|
expandable: {
|
|
|
|
type: Boolean,
|
|
|
|
type: Boolean,
|
|
|
|
default: false
|
|
|
|
default: false
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
// 定义 hideCheckAll 属性,类型为布尔值,用于控制是否隐藏全选按钮(从后续代码中可以看到与全选相关的逻辑,这里通过该属性来决定是否展示全选的操作入口),默认值为 false,即默认不隐藏全选按钮。
|
|
|
|
hideCheckAll: {
|
|
|
|
hideCheckAll: {
|
|
|
|
type: Boolean,
|
|
|
|
type: Boolean,
|
|
|
|
default: false
|
|
|
|
default: false
|
|
|
@ -33,71 +43,108 @@ export default {
|
|
|
|
},
|
|
|
|
},
|
|
|
|
data () {
|
|
|
|
data () {
|
|
|
|
return {
|
|
|
|
return {
|
|
|
|
|
|
|
|
// 定义 expand 属性,用于记录组件当前是否处于展开状态,初始值为 false,表示默认是未展开的,后续可以通过相关逻辑(比如点击展开按钮等操作)来改变这个值。
|
|
|
|
expand: false,
|
|
|
|
expand: false,
|
|
|
|
|
|
|
|
// 定义 localCheckAll 属性,用于记录当前是否全选了所有选项,初始值为 false,表示默认没有全选,会根据选项的选中情况动态更新这个值(通过后续的相关方法来改变)。
|
|
|
|
localCheckAll: false,
|
|
|
|
localCheckAll: false,
|
|
|
|
|
|
|
|
// 调用 getItemsKey 方法,传入过滤空值后的默认插槽内容(this.$slots.default 通过 filterEmpty 函数处理后),获取并存储每个选项对应的键值对象,用于记录每个选项的选中状态等相关信息,具体结构和用法要看 getItemsKey 方法的实现细节。
|
|
|
|
items: this.getItemsKey(filterEmpty(this.$slots.default)),
|
|
|
|
items: this.getItemsKey(filterEmpty(this.$slots.default)),
|
|
|
|
|
|
|
|
// 根据组件传入的 value 属性或者 defaultValue 属性(如果 value 不存在则使用 defaultValue)来初始化 val 属性,如果两者都为 null,则初始化为空数组,这个 val 属性可能用于存储组件当前的实际值(比如选中项等相关数据),后续操作会基于这个值进行处理和更新。
|
|
|
|
val: this.value || this.defaultValue || []
|
|
|
|
val: this.value || this.defaultValue || []
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
methods: {
|
|
|
|
methods: {
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 当选项的选中状态发生改变时调用的方法,接收一个包含选中信息的对象(checked)参数,用于更新组件内部的选中状态相关数据以及全选状态的判断。
|
|
|
|
|
|
|
|
* @param checked 包含选中信息的对象,可能包含类似 value(选项的值)、checked(是否选中的布尔值)等属性,具体结构取决于调用时传入的参数情况以及相关组件的约定。
|
|
|
|
|
|
|
|
*/
|
|
|
|
onChange (checked) {
|
|
|
|
onChange (checked) {
|
|
|
|
const key = Object.keys(this.items).filter(key => key === checked.value)
|
|
|
|
// 通过 Object.keys 获取 items 对象(存储选项键值及选中状态的对象)的所有键(即每个选项对应的键),然后过滤出与传入的 checked.value 相等的键,得到对应的选项键数组(这里的逻辑是找到与当前改变选中状态的选项对应的键)。
|
|
|
|
this.items[key] = checked.checked
|
|
|
|
const key = Object.keys(this.items).filter(key => key === checked.value);
|
|
|
|
const bool = Object.values(this.items).lastIndexOf(false)
|
|
|
|
// 根据找到的选项键,更新 items 对象中对应选项的选中状态为传入的 checked.checked 值(即更新该选项在组件内部记录的选中状态)。
|
|
|
|
|
|
|
|
this.items[key] = checked.checked;
|
|
|
|
|
|
|
|
// 通过 Object.values 获取 items 对象中所有值(即所有选项的选中状态值),然后查找最后一个值为 false 的索引位置(也就是查找是否还有未选中的选项),如果返回 -1,表示所有选项都被选中了,没有值为 false 的情况;否则表示还有未选中的选项。
|
|
|
|
|
|
|
|
const bool = Object.values(this.items).lastIndexOf(false);
|
|
|
|
if (bool === -1) {
|
|
|
|
if (bool === -1) {
|
|
|
|
this.localCheckAll = true
|
|
|
|
// 如果所有选项都被选中,将 localCheckAll 属性设置为 true,表示当前处于全选状态。
|
|
|
|
|
|
|
|
this.localCheckAll = true;
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
this.localCheckAll = false
|
|
|
|
// 如果还有未选中的选项,将 localCheckAll 属性设置为 false,表示当前不是全选状态。
|
|
|
|
|
|
|
|
this.localCheckAll = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 当点击全选按钮时调用的方法,接收一个包含全选按钮选中状态信息的对象(checked)参数,用于更新所有选项的选中状态以及组件内部的全选状态记录。
|
|
|
|
|
|
|
|
* @param checked 包含全选按钮选中状态的对象,通常包含 checked 属性(布尔值,表示全选按钮是否被选中),用于统一设置所有选项的选中状态。
|
|
|
|
|
|
|
|
*/
|
|
|
|
onCheckAll (checked) {
|
|
|
|
onCheckAll (checked) {
|
|
|
|
|
|
|
|
// 遍历 items 对象的所有键(即每个选项对应的键),将每个选项的选中状态都设置为传入的 checked.checked 值,实现全选或者取消全选所有选项的操作。
|
|
|
|
Object.keys(this.items).forEach(v => {
|
|
|
|
Object.keys(this.items).forEach(v => {
|
|
|
|
this.items[v] = checked.checked
|
|
|
|
this.items[v] = checked.checked;
|
|
|
|
})
|
|
|
|
});
|
|
|
|
this.localCheckAll = checked.checked
|
|
|
|
// 将组件内部记录全选状态的 localCheckAll 属性设置为传入的 checked.checked 值,保持全选状态的记录与实际选项的选中情况一致。
|
|
|
|
|
|
|
|
this.localCheckAll = checked.checked;
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 用于获取每个选项对应的键值对象,根据传入的选项数组(items)创建一个新的对象,对象的键为每个选项的特定值(通常是用于唯一标识选项的值,比如选项的 ID 等),值初始化为 false(表示默认未选中状态),方便后续根据选项的键来记录和查询其选中状态等信息。
|
|
|
|
|
|
|
|
* @param items 选项数组,数组元素可能是包含选项相关信息的虚拟 DOM 节点或者对象(具体取决于组件插槽传入内容的结构和格式)。
|
|
|
|
|
|
|
|
* @returns {Object} 返回一个对象,对象的键为选项的特定值,值为布尔类型的选中状态(初始化为 false)。
|
|
|
|
|
|
|
|
*/
|
|
|
|
getItemsKey (items) {
|
|
|
|
getItemsKey (items) {
|
|
|
|
const totalItem = {}
|
|
|
|
const totalItem = {};
|
|
|
|
items.forEach(item => {
|
|
|
|
items.forEach(item => {
|
|
|
|
totalItem[item.componentOptions.propsData && item.componentOptions.propsData.value] = false
|
|
|
|
// 从每个选项对象(这里假设 item 是包含选项相关属性的对象,比如从插槽传入的组件选项配置对象)中获取用于唯一标识选项的值(通过 item.componentOptions.propsData.value 获取,具体的属性名 'value' 可能是组件约定的用于标识选项的关键属性),并以此值作为键,在 totalItem 对象中创建对应项,初始值设置为 false,表示默认未选中该选项。
|
|
|
|
})
|
|
|
|
totalItem[item.componentOptions.propsData && item.componentOptions.propsData.value] = false;
|
|
|
|
return totalItem
|
|
|
|
});
|
|
|
|
|
|
|
|
return totalItem;
|
|
|
|
},
|
|
|
|
},
|
|
|
|
// CheckAll Button
|
|
|
|
// CheckAll Button
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 用于渲染全选按钮的方法,根据 hideCheckAll 属性判断是否需要隐藏全选按钮,如果不隐藏(hideCheckAll 为 false),则返回一个 <Option> 组件(之前导入的组件)作为全选按钮,设置其 key 属性为 'total',选中状态为 localCheckAll 属性的值(即当前组件内部记录的全选状态),并绑定 onChange 事件为 onCheckAll 方法,按钮显示文本为 'All';如果需要隐藏(hideCheckAll 为 true),则返回 null,表示不渲染全选按钮。
|
|
|
|
|
|
|
|
*/
|
|
|
|
renderCheckAll () {
|
|
|
|
renderCheckAll () {
|
|
|
|
return !this.hideCheckAll && (<Option key={'total'} checked={this.localCheckAll} onChange={this.onCheckAll}>All</Option>) || null
|
|
|
|
return!this.hideCheckAll && (<Option key={'total'} checked={this.localCheckAll} onChange={this.onCheckAll}>All</Option>) || null;
|
|
|
|
},
|
|
|
|
},
|
|
|
|
// expandable
|
|
|
|
// expandable
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 用于处理组件可展开相关逻辑的方法,目前函数体为空,可能后续需要在这里添加代码来实现组件展开时的具体行为,比如展开显示更多选项、展开后加载更多数据等相关操作,具体功能取决于组件的设计需求。
|
|
|
|
|
|
|
|
*/
|
|
|
|
renderExpandable () {
|
|
|
|
renderExpandable () {
|
|
|
|
|
|
|
|
|
|
|
|
},
|
|
|
|
},
|
|
|
|
// render option
|
|
|
|
// render option
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 用于渲染选项的方法,接收选项数组(items)参数,主要功能是为每个选项添加 change 事件监听器,当选项的选中状态改变时,先触发组件内部的 onChange 方法更新内部状态,再通过 $emit 触发 'change' 事件将选中状态变化通知给外部组件(实现双向数据绑定或者让外部组件能响应选项变化等功能),最后返回处理后的选项数组(包含添加了事件监听器的虚拟 DOM 节点等),用于在组件模板中进行渲染展示。
|
|
|
|
|
|
|
|
* @param items 选项数组,同前面提到的选项相关数组,包含要渲染的各个选项的信息。
|
|
|
|
|
|
|
|
*/
|
|
|
|
renderTags (items) {
|
|
|
|
renderTags (items) {
|
|
|
|
const listeners = {
|
|
|
|
const listeners = {
|
|
|
|
change: (checked) => {
|
|
|
|
change: (checked) => {
|
|
|
|
this.onChange(checked)
|
|
|
|
this.onChange(checked);
|
|
|
|
this.$emit('change', checked)
|
|
|
|
this.$emit('change', checked);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
return items.map(vnode => {
|
|
|
|
return items.map(vnode => {
|
|
|
|
const options = vnode.componentOptions
|
|
|
|
const options = vnode.componentOptions;
|
|
|
|
options.listeners = listeners
|
|
|
|
options.listeners = listeners;
|
|
|
|
return vnode
|
|
|
|
return vnode;
|
|
|
|
})
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
render () {
|
|
|
|
render () {
|
|
|
|
const { $props: { prefixCls } } = this
|
|
|
|
// 从组件实例的 $props 对象中解构出 prefixCls 属性,获取组件当前的类名前缀,用于后续构建类名相关的对象来应用样式。
|
|
|
|
|
|
|
|
const { $props: { prefixCls } } = this;
|
|
|
|
const classString = {
|
|
|
|
const classString = {
|
|
|
|
|
|
|
|
// 创建一个对象 classString,以 `${prefixCls}` 作为键,值为 true,用于在模板中通过动态绑定类名(比如使用 :class 指令)来添加组件的基础类名,方便样式应用(后续可以根据这个基础类名添加更多修饰类名等进行样式定制)。
|
|
|
|
[`${prefixCls}`]: true
|
|
|
|
[`${prefixCls}`]: true
|
|
|
|
}
|
|
|
|
};
|
|
|
|
const tagItems = filterEmpty(this.$slots.default)
|
|
|
|
const tagItems = filterEmpty(this.$slots.default);
|
|
|
|
return (
|
|
|
|
return (
|
|
|
|
<div class={classString}>
|
|
|
|
<div class={classString}>
|
|
|
|
{this.renderCheckAll()}
|
|
|
|
{this.renderCheckAll()}
|
|
|
|
{this.renderTags(tagItems)}
|
|
|
|
{this.renderTags(tagItems)}
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|