From deada0aeb8feec862530e1135d7a98fb1a18b0fa Mon Sep 17 00:00:00 2001 From: tangjinzhou <415800467@qq.com> Date: Wed, 30 Aug 2023 21:44:03 +0800 Subject: [PATCH] chore: udpate lint, close #6896 --- .eslintignore | 2 + .eslintrc.js | 28 ++- .../_util/{BaseMixin.js => BaseMixin.ts} | 3 +- ...InputDirective.js => antInputDirective.ts} | 15 +- components/_util/{json2mq.js => json2mq.ts} | 8 +- .../_util/props-util/{index.js => index.ts} | 221 +++--------------- components/form/demo/custom-validation.vue | 6 +- components/form/demo/dynamic-form-item.vue | 2 +- .../form/demo/dynamic-form-items-complex.vue | 2 +- components/form/demo/dynamic-form-items.vue | 2 +- components/input/demo/password-input.vue | 4 +- components/menu/demo/sider-current.vue | 2 +- components/table/demo/ajax.vue | 2 +- components/vc-slick/dots.jsx | 12 +- components/vc-slick/inner-slider.jsx | 2 +- package.json | 10 +- 16 files changed, 93 insertions(+), 228 deletions(-) rename components/_util/{BaseMixin.js => BaseMixin.ts} (92%) rename components/_util/{antInputDirective.js => antInputDirective.ts} (75%) rename components/_util/{json2mq.js => json2mq.ts} (86%) rename components/_util/props-util/{index.js => index.ts} (53%) diff --git a/.eslintignore b/.eslintignore index 1b06d2da6..257d80189 100644 --- a/.eslintignore +++ b/.eslintignore @@ -7,4 +7,6 @@ es/ lib/ _site/ dist/ +site/dist/ components/version/version.tsx +site/src/router/demoRoutes.js diff --git a/.eslintrc.js b/.eslintrc.js index ee1ee27a9..face650ee 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -15,9 +15,20 @@ module.exports = { 'plugin:vue/vue3-recommended', 'plugin:import/recommended', 'plugin:import/typescript', - 'prettier', + '@vue/typescript/recommended', + '@vue/prettier', + // 'prettier', ], + // extends: [ + // 'eslint:recommended', + // 'plugin:vue/vue3-recommended', + // '@vue/typescript/recommended', + // '@vue/prettier', + // ], plugins: ['markdown', 'jest', '@typescript-eslint', 'import'], + globals: { + defineProps: 'readonly', + }, overrides: [ { files: ['*.md'], @@ -28,12 +39,11 @@ module.exports = { }, { files: ['*.ts', '*.tsx'], - extends: ['@vue/typescript/recommended', '@vue/prettier', '@vue/prettier/@typescript-eslint'], + // extends: ['@vue/typescript/recommended', '@vue/prettier'], parserOptions: { project: './tsconfig.json', }, rules: { - '@typescript-eslint/no-explicit-any': 0, '@typescript-eslint/ban-types': 0, '@typescript-eslint/consistent-type-imports': 'error', '@typescript-eslint/explicit-module-boundary-types': 0, @@ -51,17 +61,21 @@ module.exports = { parser: 'vue-eslint-parser', parserOptions: { parser: '@typescript-eslint/parser', + ecmaVersion: 2021, }, rules: { 'no-console': 'off', - '@typescript-eslint/no-unused-vars': [ - 'error', - { vars: 'all', args: 'after-used', ignoreRestSiblings: true }, - ], + 'vue/no-reserved-component-names': 'off', }, }, ], rules: { + '@typescript-eslint/no-explicit-any': 0, + '@typescript-eslint/no-empty-function': 0, + '@typescript-eslint/no-unused-vars': [ + 'error', + { vars: 'all', args: 'after-used', ignoreRestSiblings: true, argsIgnorePattern: '^_' }, + ], 'import/no-named-as-default': 'off', 'import/namespace': [2, { allowComputed: true }], 'import/no-named-as-default-member': 'off', diff --git a/components/_util/BaseMixin.js b/components/_util/BaseMixin.ts similarity index 92% rename from components/_util/BaseMixin.js rename to components/_util/BaseMixin.ts index eeec056e3..33831b9fa 100644 --- a/components/_util/BaseMixin.js +++ b/components/_util/BaseMixin.ts @@ -3,7 +3,7 @@ import { getOptionProps } from './props-util'; export default { methods: { - setState(state = {}, callback) { + setState(state = {}, callback: () => any) { let newState = typeof state === 'function' ? state(this.$data, this.$props) : state; if (this.getDerivedStateFromProps) { const s = this.getDerivedStateFromProps(getOptionProps(this), { @@ -26,6 +26,7 @@ export default { }, __emit() { // 直接调用事件,底层组件不需要vueTool记录events + // eslint-disable-next-line prefer-rest-params const args = [].slice.call(arguments, 0); let eventName = args[0]; eventName = `on${eventName[0].toUpperCase()}${eventName.substring(1)}`; diff --git a/components/_util/antInputDirective.js b/components/_util/antInputDirective.ts similarity index 75% rename from components/_util/antInputDirective.js rename to components/_util/antInputDirective.ts index c8ccf2d58..204390f4c 100644 --- a/components/_util/antInputDirective.js +++ b/components/_util/antInputDirective.ts @@ -1,8 +1,10 @@ -function onCompositionStart(e) { +import type { Directive } from 'vue'; + +function onCompositionStart(e: any) { e.target.composing = true; } -function onCompositionEnd(e) { +function onCompositionEnd(e: any) { // prevent triggering an input event for no reason if (!e.target.composing) return; e.target.composing = false; @@ -15,10 +17,15 @@ function trigger(el, type) { el.dispatchEvent(e); } -export function addEventListener(el, event, handler, options) { +export function addEventListener( + el: HTMLElement, + event: string, + handler: EventListenerOrEventListenerObject, + options?: boolean | AddEventListenerOptions, +) { el.addEventListener(event, handler, options); } -const antInput = { +const antInput: Directive = { created(el, binding) { if (!binding.modifiers || !binding.modifiers.lazy) { addEventListener(el, 'compositionstart', onCompositionStart); diff --git a/components/_util/json2mq.js b/components/_util/json2mq.ts similarity index 86% rename from components/_util/json2mq.js rename to components/_util/json2mq.ts index 2418d7c67..f384396db 100644 --- a/components/_util/json2mq.js +++ b/components/_util/json2mq.ts @@ -3,7 +3,7 @@ * https://github.com/akiran/json2mq.git */ -const camel2hyphen = function (str) { +const camel2hyphen = function (str: string) { return str .replace(/[A-Z]/g, function (match) { return '-' + match.toLowerCase(); @@ -11,12 +11,12 @@ const camel2hyphen = function (str) { .toLowerCase(); }; -const isDimension = function (feature) { +const isDimension = function (feature: string) { const re = /[height|width]$/; return re.test(feature); }; -const obj2mq = function (obj) { +const obj2mq = function (obj: { [x: string]: any }) { let mq = ''; const features = Object.keys(obj); features.forEach(function (feature, index) { @@ -40,7 +40,7 @@ const obj2mq = function (obj) { return mq; }; -export default function (query) { +export default function (query: any[]) { let mq = ''; if (typeof query === 'string') { return query; diff --git a/components/_util/props-util/index.js b/components/_util/props-util/index.ts similarity index 53% rename from components/_util/props-util/index.js rename to components/_util/props-util/index.ts index 38b0c9252..85d694af8 100644 --- a/components/_util/props-util/index.js +++ b/components/_util/props-util/index.ts @@ -1,19 +1,19 @@ -import isPlainObject from 'lodash-es/isPlainObject'; import classNames from '../classNames'; -import { isVNode, Fragment, Comment, Text, h } from 'vue'; +import { isVNode, Fragment, Comment, Text } from 'vue'; import { camelize, hyphenate, isOn, resolvePropValue } from '../util'; import isValid from '../isValid'; import initDefaultProps from './initDefaultProps'; +import type { VueInstance } from '../hooks/_vueuse/unrefElement'; // function getType(fn) { // const match = fn && fn.toString().match(/^\s*function (\w+)/); // return match ? match[1] : ''; // } -const splitAttrs = attrs => { +const splitAttrs = (attrs: any) => { const allAttrs = Object.keys(attrs); - const eventAttrs = {}; - const onEvents = {}; - const extraAttrs = {}; + const eventAttrs: Record = {}; + const onEvents: Record = {}; + const extraAttrs: Record = {}; for (let i = 0, l = allAttrs.length; i < l; i++) { const key = allAttrs[i]; if (isOn(key)) { @@ -25,7 +25,7 @@ const splitAttrs = attrs => { } return { onEvents, events: eventAttrs, extraAttrs }; }; -const parseStyleText = (cssText = '', camel) => { +const parseStyleText = (cssText = '', camel = false) => { const res = {}; const listDelimiter = /;(?![^(]*\))/g; const propertyDelimiter = /:(.+)/; @@ -42,34 +42,9 @@ const parseStyleText = (cssText = '', camel) => { return res; }; -const hasProp = (instance, prop) => { +const hasProp = (instance: any, prop: string) => { return instance[prop] !== undefined; }; -// 重构后直接使用 hasProp 替换 -const slotHasProp = (slot, prop) => { - return hasProp(slot, prop); -}; - -const getScopedSlots = ele => { - return (ele.data && ele.data.scopedSlots) || {}; -}; - -const getSlots = ele => { - let componentOptions = ele.componentOptions || {}; - if (ele.$vnode) { - componentOptions = ele.$vnode.componentOptions || {}; - } - const children = ele.children || componentOptions.children || []; - const slots = {}; - children.forEach(child => { - if (!isEmptyElement(child)) { - const name = (child.data && child.data.slot) || 'default'; - slots[name] = slots[name] || []; - slots[name].push(child); - } - }); - return { ...slots, ...getScopedSlots(ele) }; -}; export const skipFlattenKey = Symbol('skipFlatten'); const flattenChildren = (children = [], filterEmpty = true) => { @@ -97,39 +72,29 @@ const flattenChildren = (children = [], filterEmpty = true) => { return res; }; -const getSlot = (self, name = 'default', options = {}) => { +const getSlot = (self: any, name = 'default', options = {}) => { if (isVNode(self)) { if (self.type === Fragment) { - return name === 'default' ? flattenChildren(self.children) : []; + return name === 'default' ? flattenChildren(self.children as any[]) : []; } else if (self.children && self.children[name]) { return flattenChildren(self.children[name](options)); } else { return []; } } else { - let res = self.$slots[name] && self.$slots[name](options); + const res = self.$slots[name] && self.$slots[name](options); return flattenChildren(res); } }; -const getAllChildren = ele => { - let componentOptions = ele.componentOptions || {}; - if (ele.$vnode) { - componentOptions = ele.$vnode.componentOptions || {}; - } - return ele.children || componentOptions.children || []; -}; -const getSlotOptions = () => { - throw Error('使用 .type 直接取值'); -}; -const findDOMNode = instance => { +const findDOMNode = (instance: any) => { let node = instance?.vnode?.el || (instance && (instance.$el || instance)); while (node && !node.tagName) { node = node.nextSibling; } return node; }; -const getOptionProps = instance => { +const getOptionProps = (instance: VueInstance) => { const res = {}; if (instance.$ && instance.$.vnode) { const props = instance.$.vnode.props || {}; @@ -146,7 +111,7 @@ const getOptionProps = instance => { Object.keys(originProps).forEach(key => { props[camelize(key)] = originProps[key]; }); - const options = instance.type.props || {}; + const options = (instance.type as any).props || {}; Object.keys(options).forEach(k => { const v = resolvePropValue(options, props, k, props[k]); if (v !== undefined || k in props) { @@ -156,7 +121,7 @@ const getOptionProps = instance => { } return res; }; -const getComponent = (instance, prop = 'default', options = instance, execute = true) => { +const getComponent = (instance: any, prop = 'default', options = instance, execute = true) => { let com = undefined; if (instance.$) { const temp = instance[prop]; @@ -184,94 +149,13 @@ const getComponent = (instance, prop = 'default', options = instance, execute = } return com; }; -const getComponentFromProp = (instance, prop, options = instance, execute = true) => { - if (instance.$createElement) { - // const h = instance.$createElement; - const temp = instance[prop]; - if (temp !== undefined) { - return typeof temp === 'function' && execute ? temp(h, options) : temp; - } - return ( - (instance.$scopedSlots[prop] && execute && instance.$scopedSlots[prop](options)) || - instance.$scopedSlots[prop] || - instance.$slots[prop] || - undefined - ); - } else { - // const h = instance.context.$createElement; - const temp = getPropsData(instance)[prop]; - if (temp !== undefined) { - return typeof temp === 'function' && execute ? temp(h, options) : temp; - } - const slotScope = getScopedSlots(instance)[prop]; - if (slotScope !== undefined) { - return typeof slotScope === 'function' && execute ? slotScope(h, options) : slotScope; - } - const slotsProp = []; - const componentOptions = instance.componentOptions || {}; - (componentOptions.children || []).forEach(child => { - if (child.data && child.data.slot === prop) { - if (child.data.attrs) { - delete child.data.attrs.slot; - } - if (child.tag === 'template') { - slotsProp.push(child.children); - } else { - slotsProp.push(child); - } - } - }); - return slotsProp.length ? slotsProp : undefined; - } -}; -const getAllProps = ele => { - let props = getOptionProps(ele); - if (ele.$) { - props = { ...props, ...this.$attrs }; - } else { - props = { ...ele.props, ...props }; - } - return props; -}; - -const getPropsData = ins => { - const vnode = ins.$ ? ins.$ : ins; - const res = {}; - const originProps = vnode.props || {}; - const props = {}; - Object.keys(originProps).forEach(key => { - props[camelize(key)] = originProps[key]; - }); - const options = isPlainObject(vnode.type) ? vnode.type.props : {}; - options && - Object.keys(options).forEach(k => { - const v = resolvePropValue(options, props, k, props[k]); - if (k in props) { - // 仅包含 props,不包含默认值 - res[k] = v; - } - }); - return { ...props, ...res }; // 合并事件、未声明属性等 -}; -const getValueByProp = (ele, prop) => { - return getPropsData(ele)[prop]; -}; - -const getAttrs = ele => { - let data = ele.data; - if (ele.$vnode) { - data = ele.$vnode.data; - } - return data ? data.attrs || {} : {}; -}; - -const getKey = ele => { - let key = ele.key; +const getKey = (ele: any) => { + const key = ele.key; return key; }; -export function getEvents(ele = {}, on = true) { +export function getEvents(ele: any = {}, on = true) { let props = {}; if (ele.$) { props = { ...props, ...ele.$attrs }; @@ -281,27 +165,9 @@ export function getEvents(ele = {}, on = true) { return splitAttrs(props)[on ? 'onEvents' : 'events']; } -export function getEvent(child, event) { - return child.props && child.props[event]; -} - -// 获取 xxx.native 或者 原生标签 事件 -export function getDataEvents(child) { - let events = {}; - if (child.data && child.data.on) { - events = child.data.on; - } - return { ...events }; -} - -// use getListeners instead this.$listeners -// https://github.com/vueComponent/ant-design-vue/issues/1705 -export function getListeners(context) { - return (context.$vnode ? context.$vnode.componentOptions.listeners : context.$listeners) || {}; -} -export function getClass(ele) { +export function getClass(ele: any) { const props = (isVNode(ele) ? ele.props : ele.$attrs) || {}; - let tempCls = props.class || {}; + const tempCls = props.class || {}; let cls = {}; if (typeof tempCls === 'string') { tempCls.split(' ').forEach(c => { @@ -318,7 +184,7 @@ export function getClass(ele) { } return cls; } -export function getStyle(ele, camel) { +export function getStyle(ele: any, camel?: boolean) { const props = (isVNode(ele) ? ele.props : ele.$attrs) || {}; let style = props.style || {}; if (typeof style === 'string') { @@ -332,19 +198,19 @@ export function getStyle(ele, camel) { return style; } -export function getComponentName(opts) { +export function getComponentName(opts: any) { return opts && (opts.Ctor.options.name || opts.tag); } -export function isFragment(c) { +export function isFragment(c: any) { return c.length === 1 && c[0].type === Fragment; } -export function isEmptyContent(c) { +export function isEmptyContent(c: any) { return c === undefined || c === null || c === '' || (Array.isArray(c) && c.length === 0); } -export function isEmptyElement(c) { +export function isEmptyElement(c: any) { return ( c && (c.type === Comment || @@ -353,11 +219,11 @@ export function isEmptyElement(c) { ); } -export function isEmptySlot(c) { +export function isEmptySlot(c: any) { return !c || c().every(isEmptyElement); } -export function isStringElement(c) { +export function isStringElement(c: any) { return c && c.type === Text; } @@ -375,7 +241,7 @@ export function filterEmpty(children = []) { return res.filter(c => !isEmptyElement(c)); } -export function filterEmptyWithUndefined(children) { +export function filterEmptyWithUndefined(children: any[]) { if (children) { const coms = filterEmpty(children); return coms.length ? coms : undefined; @@ -384,34 +250,18 @@ export function filterEmptyWithUndefined(children) { } } -export function mergeProps() { - const args = [].slice.call(arguments, 0); - const props = {}; - args.forEach((p = {}) => { - for (const [k, v] of Object.entries(p)) { - props[k] = props[k] || {}; - if (isPlainObject(v)) { - Object.assign(props[k], v); - } else { - props[k] = v; - } - } - }); - return props; -} - -function isValidElement(element) { +function isValidElement(element: any) { if (Array.isArray(element) && element.length === 1) { element = element[0]; } return element && element.__v_isVNode && typeof element.type !== 'symbol'; // remove text node } -function getPropsSlot(slots, props, prop = 'default') { +function getPropsSlot(slots: any, props: any, prop = 'default') { return props[prop] ?? slots[prop]?.(); } -export const getTextFromElement = ele => { +export const getTextFromElement = (ele: any) => { if (isValidElement(ele) && isStringElement(ele[0])) { return ele[0].children; } @@ -422,21 +272,12 @@ export { hasProp, getOptionProps, getComponent, - getComponentFromProp, - getSlotOptions, - slotHasProp, - getPropsData, getKey, - getAttrs, - getValueByProp, parseStyleText, initDefaultProps, isValidElement, camelize, - getSlots, getSlot, - getAllProps, - getAllChildren, findDOMNode, flattenChildren, getPropsSlot, diff --git a/components/form/demo/custom-validation.vue b/components/form/demo/custom-validation.vue index 2ecf6bc6f..bc520f60d 100644 --- a/components/form/demo/custom-validation.vue +++ b/components/form/demo/custom-validation.vue @@ -59,7 +59,7 @@ const formState = reactive({ checkPass: '', age: undefined, }); -let checkAge = async (_rule: Rule, value: number) => { +const checkAge = async (_rule: Rule, value: number) => { if (!value) { return Promise.reject('Please input the age'); } @@ -73,7 +73,7 @@ let checkAge = async (_rule: Rule, value: number) => { } } }; -let validatePass = async (_rule: Rule, value: string) => { +const validatePass = async (_rule: Rule, value: string) => { if (value === '') { return Promise.reject('Please input the password'); } else { @@ -83,7 +83,7 @@ let validatePass = async (_rule: Rule, value: string) => { return Promise.resolve(); } }; -let validatePass2 = async (_rule: Rule, value: string) => { +const validatePass2 = async (_rule: Rule, value: string) => { if (value === '') { return Promise.reject('Please input the password again'); } else if (value !== formState.pass) { diff --git a/components/form/demo/dynamic-form-item.vue b/components/form/demo/dynamic-form-item.vue index 196c71bf3..d1cb0769e 100644 --- a/components/form/demo/dynamic-form-item.vue +++ b/components/form/demo/dynamic-form-item.vue @@ -101,7 +101,7 @@ const resetForm = () => { formRef.value.resetFields(); }; const removeDomain = (item: Domain) => { - let index = dynamicValidateForm.domains.indexOf(item); + const index = dynamicValidateForm.domains.indexOf(item); if (index !== -1) { dynamicValidateForm.domains.splice(index, 1); } diff --git a/components/form/demo/dynamic-form-items-complex.vue b/components/form/demo/dynamic-form-items-complex.vue index 62b9d4625..b9f5d7569 100644 --- a/components/form/demo/dynamic-form-items-complex.vue +++ b/components/form/demo/dynamic-form-items-complex.vue @@ -102,7 +102,7 @@ watch( }, ); const removeSight = (item: Sights) => { - let index = dynamicValidateForm.sights.indexOf(item); + const index = dynamicValidateForm.sights.indexOf(item); if (index !== -1) { dynamicValidateForm.sights.splice(index, 1); } diff --git a/components/form/demo/dynamic-form-items.vue b/components/form/demo/dynamic-form-items.vue index 8135cf7bf..3f768b21c 100644 --- a/components/form/demo/dynamic-form-items.vue +++ b/components/form/demo/dynamic-form-items.vue @@ -75,7 +75,7 @@ const dynamicValidateForm = reactive<{ users: User[] }>({ users: [], }); const removeUser = (item: User) => { - let index = dynamicValidateForm.users.indexOf(item); + const index = dynamicValidateForm.users.indexOf(item); if (index !== -1) { dynamicValidateForm.users.splice(index, 1); } diff --git a/components/input/demo/password-input.vue b/components/input/demo/password-input.vue index c2c4ec666..4114feb31 100644 --- a/components/input/demo/password-input.vue +++ b/components/input/demo/password-input.vue @@ -19,8 +19,8 @@ Input type of password. -