Skip to content

Commit

Permalink
+ rules added as of eslint@8.56.0, @typescript-eslint@6.14.0 & `e…
Browse files Browse the repository at this point in the history
…slint-plugin-vue@9.19.2`

* config rule `vue/attributes-order` to re-order attrs
* extends from `@typescript-eslint/(strict|stylistic)-type-checked`
- rules that are already enabled in currently using presets: eslint/eslint#14691, vuejs/eslint-plugin-vue#1848
@ .eslintrc.cjs

* change the type of `ApiUsersQuery.pages` to `CursorPagination`
- unused exported type `Pagination`
@ api/index.d.ts
- no longer count user items in noty @ `<User>`
* sync usages of `paginations/usePaginationButtons.ts` with `<PostsPage>` @ `<UsersPage>`
@ fe
  • Loading branch information
n0099 committed Dec 18, 2023
1 parent 1403ed2 commit f500a45
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 27 deletions.
89 changes: 72 additions & 17 deletions fe/.eslintrc.cjs
Expand Up @@ -14,9 +14,11 @@ module.exports = {
}, {
files: '*',
excludedFiles: '.eslintrc.cjs',
parser: 'vue-eslint-parser',
parserOptions: {
parser: '@typescript-eslint/parser',
project: ['./tsconfig.json', './tsconfig.node.json'],
tsconfigRootDir: __dirname,
},
settings: {
'import/resolver': {
Expand All @@ -30,22 +32,20 @@ module.exports = {
'eslint:recommended',
'plugin:vue/vue3-recommended',
'@vue/typescript/recommended',
'plugin:@typescript-eslint/strict-type-checked',
'plugin:@typescript-eslint/stylistic-type-checked',
'plugin:import/recommended',
'plugin:import/typescript',
// https://github.com/vuejs/eslint-config-typescript/issues/29
// 'plugin:@typescript-eslint/recommended-requiring-type-checking'
],
rules: {
'import/no-useless-path-segments': 'error',
'import/extensions': ['error', 'always', { ts: 'never' }],

// as of eslint 8.6.0
// as of eslint@8.56.0
'no-await-in-loop': 'error',
'no-promise-executor-return': 'error',
'no-template-curly-in-string': 'error',
'no-unreachable-loop': 'error',
'no-unsafe-optional-chaining': 'error',
'no-useless-backreference': 'error',
'require-atomic-updates': 'error',
'accessor-pairs': 'error',
'array-callback-return': 'error',
Expand Down Expand Up @@ -75,7 +75,6 @@ module.exports = {
'no-new': 'error',
'no-new-func': 'error',
'no-new-wrappers': 'error',
'no-nonoctal-decimal-escape': 'error',
'no-octal-escape': 'error',
'no-param-reassign': 'error',
'no-proto': 'error',
Expand Down Expand Up @@ -131,7 +130,7 @@ module.exports = {
'@stylistic/no-multiple-empty-lines': 'error',
'no-negated-condition': 'error',
'no-nested-ternary': 'error',
'no-new-object': 'error',
'no-object-constructor': 'error',
'@stylistic/no-tabs': 'error',
'@stylistic/no-trailing-spaces': 'error',
'no-unneeded-ternary': 'error',
Expand Down Expand Up @@ -183,7 +182,6 @@ module.exports = {
'object-shorthand': 'error',
'prefer-arrow-callback': 'error',
'prefer-const': 'error',
'prefer-destructuring': 'error',
'prefer-numeric-literals': 'error',
'prefer-rest-params': 'error',
'prefer-spread': 'error',
Expand All @@ -194,9 +192,21 @@ module.exports = {
'@stylistic/template-curly-spacing': 'error',
'@stylistic/yield-star-spacing': 'error',
'prefer-object-has-own': 'error',
'no-constant-binary-expression': 'error',
'logical-assignment-operators': ['error', 'always', { enforceForIfStatements: true }],
'no-empty-static-block': 'error',
'no-new-native-nonconstructor': 'error',
'@stylistic/lines-around-comment': ['error', {
beforeBlockComment: true,
beforeLineComment: true,
allowBlockStart: true,
allowObjectStart: true,
allowArrayStart: true,
allowClassStart: true,
}],

// as of @typescript-eslint 5.9.0
'@typescript-eslint/no-empty-function': 'off',
// as of @typescript-eslint@6.14.0
'@typescript-eslint/no-empty-function': 'error',

'no-void': 'off',
'@stylistic/brace-style': ['error', '1tbs', { allowSingleLine: true }],
Expand Down Expand Up @@ -254,6 +264,10 @@ module.exports = {
'require-await': 'off',
'@typescript-eslint/require-await': 'error',
'@stylistic/padding-line-between-statements': ['error'],
'class-methods-use-this': 'off',
'@typescript-eslint/class-methods-use-this': 'error',
'prefer-destructuring': 'off',
'@typescript-eslint/prefer-destructuring': 'error',

'@typescript-eslint/array-type': ['error', {
default: 'array-simple',
Expand Down Expand Up @@ -341,16 +355,33 @@ module.exports = {
'@typescript-eslint/prefer-return-this-type': 'error',
'@typescript-eslint/no-non-null-asserted-nullish-coalescing': 'error',
'@typescript-eslint/consistent-type-exports': 'error',
'@typescript-eslint/no-useless-empty-export': 'error',
'@typescript-eslint/no-redundant-type-constituents': 'error',
'@typescript-eslint/no-import-type-side-effects': 'error',
'@typescript-eslint/no-mixed-enums': 'error',
'@typescript-eslint/no-duplicate-type-constituents': ['error', { ignoreUnions: true }],
'@typescript-eslint/no-unsafe-enum-comparison': 'error',
'@typescript-eslint/no-unsafe-unary-minus': 'error',

// as of eslint-plugin-vue 8.2.0
// as of eslint-plugin-vue@9.19.2
'vue/html-indent': ['error', 4],
'vue/max-attributes-per-line': 'off',
'vue/no-reserved-component-names': 'off', // for component in antdv
'vue/attribute-hyphenation': ['error', 'never'],
'vue/singleline-html-element-content-newline': 'off',
'vue/attributes-order': ['error', {
order: ['DEFINITION', ['LIST_RENDERING', 'UNIQUE'], 'CONDITIONALS', 'TWO_WAY_BINDING', 'RENDER_MODIFIERS', 'SLOT', 'EVENTS', 'OTHER_DIRECTIVES', 'GLOBAL', 'OTHER_ATTR', 'CONTENT'],
}],
'vue/attributes-order': ['error', { order: [
'DEFINITION',
['LIST_RENDERING', 'UNIQUE'],
'CONDITIONALS',
'RENDER_MODIFIERS',
'TWO_WAY_BINDING',
'EVENTS',
'SLOT',
'OTHER_DIRECTIVES',
'OTHER_ATTR',
'GLOBAL',
'CONTENT',
] }],
'vue/multi-word-component-names': 'off',
'vue/first-attribute-linebreak': ['error', {
singleline: 'beside',
Expand All @@ -372,10 +403,8 @@ module.exports = {
'vue/custom-event-name-casing': ['error', 'camelCase'],
'vue/html-comment-content-spacing': 'error',
'vue/html-comment-indent': ['error', 4],
'vue/no-child-content': 'error',
'vue/no-duplicate-attr-inheritance': 'error',
'vue/no-empty-component-block': 'error',
'vue/no-expose-after-await': 'error',
'vue/no-invalid-model-keys': 'error',
'vue/no-multiple-objects-in-class': 'error',
'vue/no-undef-components': 'error',
Expand All @@ -389,7 +418,6 @@ module.exports = {
// 'vue/require-expose': 'error',
// 'vue/static-class-names-order': 'error',
'vue/v-for-delimiter-style': 'error',
'vue/v-on-function-call': 'error',
'vue/array-bracket-newline': ['error', 'consistent'],
'vue/array-bracket-spacing': 'error',
'vue/arrow-spacing': 'error',
Expand Down Expand Up @@ -433,6 +461,33 @@ module.exports = {
nonwords: false,
}],
'vue/template-curly-spacing': 'error',
'vue/quote-props': ['error', 'as-needed'],
'vue/object-shorthand': 'error',
'vue/prefer-true-attribute-shorthand': 'error',
'vue/prefer-prop-type-boolean-first': 'error',
'vue/define-macros-order': ['error', { order: [
'defineOptions',
'defineProps',
'defineEmits',
// 'defineModel', https://github.com/vuejs/eslint-plugin-vue/issues/2130
'defineSlots',
] }],
'vue/match-component-import-name': 'error',
'vue/define-props-declaration': 'error',
'vue/define-emits-declaration': 'error',
'vue/no-required-prop-with-default': 'error',
'vue/v-on-handler-style': ['error', ['method', 'inline']],
'vue/multiline-ternary': 'error',
'vue/array-element-newline': ['error', 'consistent'],
'vue/prefer-define-options': 'error',
'vue/valid-define-options': 'error',
'vue/require-macro-variable-name': 'error',
'vue/require-typed-ref': 'error',
'vue/no-deprecated-model-definition': 'error',
'vue/require-typed-object-prop': 'error',
'vue/no-use-v-else-with-v-for': 'error',
'vue/no-unused-emit-declarations': 'error',
'vue/no-ref-object-reactivity-loss': 'error',
},
}],
};
3 changes: 1 addition & 2 deletions fe/src/api/index.d.ts
Expand Up @@ -41,10 +41,9 @@ export interface ApiStatsForumPostCountQueryParam {
endTime: UnixTimestamp
}

export type Pagination = { [P in 'currentPage' | 'firstItem' | 'itemCount']: UInt };
interface ApiQueryParamPagination { page?: UInt }
export interface ApiUsersQuery {
pages: Pagination,
pages: CursorPagination,
users: TiebaUser[]
}
export type ApiUsersQueryQueryParam
Expand Down
6 changes: 3 additions & 3 deletions fe/src/components/User/UsersPage.vue
@@ -1,6 +1,6 @@
<template>
<div>
<PageCurrentButton :page="users.pages" :pageRoutes="pageRoutes" />
<PageCurrentButton :currentCursor="users.pages.currentCursor" />
<div v-for="(user, userIndex) in users.users" :key="user.uid" :id="String(user.uid)" class="row">
<div class="col-3">
<img :data-src="toTiebaUserPortraitImageUrl(user.portrait)"
Expand All @@ -15,7 +15,7 @@
</div>
<div v-if="userIndex !== users.users.length - 1" class="w-100"><hr /></div>
</div>
<PageNextButton v-if="!isLoadingNewPage && isLastPageInPages" :pageRoutes="pageRoutes" />
<PageNextButton v-if="!isLoadingNewPage && isLastPageInPages" :nextCursorRoute="nextCursorRoute" />
</div>
</template>

Expand All @@ -32,7 +32,7 @@ const props = defineProps<{
isLoadingNewPage: boolean,
isLastPageInPages: boolean
}>();
const pageRoutes = useNextCursorRoute(props.users.pages.currentPage);
const nextCursorRoute = useNextCursorRoute(props.users.pages.currentCursor);
const userGender = (gender: TiebaUserGender) => {
const gendersList = {
Expand Down
10 changes: 5 additions & 5 deletions fe/src/views/User.vue
@@ -1,8 +1,8 @@
<template>
<UserQueryForm :query="$route.query" :params="params" :selectUserBy="selectUserBy" class="my-4" />
<UsersPage v-for="(users, pageIndex) in userPages"
:key="`page${users.pages.currentPage}`"
:id="`page${users.pages.currentPage}`"
:key="`page${users.pages.currentCursor}`"
:id="`page${users.pages.currentCursor}`"
:users="users"
:isLoadingNewPage="isLoading"
:isLastPageInPages="pageIndex === userPages.length - 1" />
Expand Down Expand Up @@ -66,10 +66,10 @@ const fetchUsersData = async (_route: RouteLocationNormalizedLoaded, isNewQuery:
if (isNewQuery)
userPages.value = [usersQuery];
else
userPages.value = _.sortBy([...userPages.value, usersQuery], i => i.pages.currentPage);
userPages.value = _.sortBy([...userPages.value, usersQuery], i => i.pages.currentCursor);
const networkTime = Date.now() - startTime;
await nextTick(); // wait for child components finish dom update
notyShow('success', `已加载第${usersQuery.pages.currentPage}页 ${usersQuery.pages.itemCount}条记录`
notyShow('success', `已加载第${usersQuery.pages.currentCursor}页`
+ ` 耗时${((Date.now() - startTime) / 1000).toFixed(2)}s 网络${networkTime}ms`);
return true;
};
Expand All @@ -86,7 +86,7 @@ onBeforeRouteUpdate(async (to, from) => {
const isNewQuery = compareRouteIsNewQuery(to, from);
if (!(isNewQuery || _.isEmpty(_.filter(
userPages.value,
i => i.pages.currentPage === getRouteCursorParam(to)
i => i.pages.currentCursor === getRouteCursorParam(to)
))))
return true;
const isFetchSuccess = await fetchUsersData(to, isNewQuery);
Expand Down

0 comments on commit f500a45

Please sign in to comment.