小达不刘
0%

前言

记录学习过程的心得体会,可能对可能错,但没关系,在学习中纠正,实践中成长。

发球

在偶数区发球:

  1. 1号内角 封正手
  2. 3号外角 封反手 启动 左腿后侧一步
  3. 2号中间区 对方正手握拍封正手 对方反手握拍封反手
    注:对方站的靠后 发重球 封网方向同上
  4. 4号内后场 大概率对方杀对角
  5. 5号外后场 大概率杀直线

    在奇数区发球:

  6. 1号内角 左腿后侧一步奇数区头顶球封网
  7. 3号外角 封正手 右脚后侧一步
  8. 2号 对方抢网 我需要马上反手握拍 前进一步 封中间或奇数区
  9. 4号内后场 封奇数区
  10. 5号外后场 封偶数区
  11. 站的靠后就发重球 轻重结合

接发

重心压低

偶数区接球:

迈右腿

阅读全文 »

在完成了一个项目,去做另一个项目时,会用到重复的组件,我们可以去打开上一个工程,把组件代码拷过来,再重新调整数据,这样会很麻烦,随着项目的越来越多,也不好定位哪个项目中使用了可复用的组件,所以业务组件库就发挥了它的优势,直接安装好后,按需引入,不用再手搬代码。本篇文章会讲述如何从 0-1 搭建自己的组件库。

技术栈:

  • Vue3
  • TypeScript
  • pnpm

1 环境准备

在 cmd 终端安装 pnpm

1
npm install pnpm -g

创建工程目录:vue3-components。

用 vscode 打开工程目录,在 vscode 终端执行:

1
pnpm init
阅读全文 »

  1. Component name “Tabs” should always be multi-word vue/multi-word-component-names

配置.eslintrc.json中的rules:

1
"vue/multi-word-component-names": ["off"]
  1. error ‘.native’ modifier on ‘v-on’ directive is deprecated vue/no-deprecated-v-on-native-modifier

‘.native‘修饰符在vue3中被弃用了,所以在代码中去掉.native就可以了。

  1. error Custom elements in iteration require ‘v-bind:key’ directives vue/valid-v-for

原因是代码模板中使用了v-for, 但是没有绑定key值,解决办法建议给v-for绑定key值。

  1. Unexpected mutation of “isShowDialog” prop vue/no-mutating-props

父组件传递过来的变量绑定弹窗会报错,原因是单向数据流,子组件不能该变父组件变量。

阅读全文 »

在多人合作的项目中,如果没有规范约束,可能每个人提上来的代码都要被格式化一遍,不便于查看该功能具体修改了哪些代码,并且commit信息写的五花八门,有时也不利于理解,所以规范是一个非常nice的东西,有了它,在多人合作的项目中,避免了很多不必要的麻烦,也会节省很多时间。

本人将如何一步一步添加规范的过程记录下来,方便和我一样有同样需求的小伙伴学习。

配置eslint

  1. 安装eslint依赖并初始化
1
2
3
npm i eslint -D
// 安装好后,进行初始化
npx eslint --init

初始化的步骤如下:

image.png

image.png

这一步需要根据你项目的框架选择,vue.js:
image.png
Vue3使用了TypeScript所以需要选“Yes”:

阅读全文 »

Vue3项目中,使用TypeScript遇到的问题及解决方案。

  1. Vue3的template中使用v-for,提示错误:对象的类型为 “unknown”。ts(2571)

解决方案:
给循环中item定义类型;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
<template>
<el-form :model="state.form" ref="form" :label-width="labelWidth"
@submit.native.prevent
>
<el-row :gutter="20">
<el-col v-bind="item.layout||layout" v-for="(item, index) in elements" :key="index">
<el-form-item
:prop="item.prop"
:label="item.label"
:label-width="item.labelWidth ? (item.labelWidth + 'px') : ''"
>
<!-- el-input -->
<el-input
v-if="item.type === 'input' || item.type === undefined"
v-model="state.form[item.prop]"
:size="item.size ? item.size : size"
:disabled="item.disabled"
:placeholder="item.placeholder"
:suffix-icon="item.suffixIcon"
clearable
/>
</el-form-item>
</el-col>
</el-row>
</el-form>
</template>

<script lang="ts" setup>
import { ref, reactive, defineProps,watch, PropType } from 'vue'
import { Search, RefreshLeft } from '@element-plus/icons-vue'

type elementItem = {
prop: string,
label: string,
type: string,
size?: string,
disabled?: boolean,
placeholder?: string,
suffixIcon?: string,
filterable?: boolean,
multiple?: boolean,
style?: object,
optionGroup?: boolean,
options: Array<any>,
layout?:object,
labelWidth?: number | string,
}
const emits = defineEmits(['search'])
const props = defineProps({
// layout
layout: {
type: Object,
default: () => ({
lg: {
span: 6,
},
md: {
span: 8,
},
sm: {
span: 12,
},
xs: {
span: 24,
},
}),
},
// 表单label宽度
labelWidth: {
type: [String, Number],
default: 'auto',
},
// 表单元素大小 默认 meidum
size: {
type: String,
default: 'default',
// validator: sizeValidator,
},
// 表单元素
elements: {
type: Array as unknown as PropType<[elementItem]>,
required: true,
},
// 是否展示搜索、重置按钮
hideBtns: {
type: Boolean,
default: false,
},
})

const form = ref()
const state = reactive({
form: {},
formatters: {},
})
</script>
  1. 在定义接口时,入参如果不定义类型会报:
    1
    2
    3
    (parameter) params: any

    参数“params”隐式具有“any”类型。ts(7006)

image.png
解决办法就是给入参定义接口类型:

1
2
3
4
5
6
7
8
interface generalViewIn {
page: number,
pagesize: number,
}
//获取概览列表数据
export async function getGeneralView(params: generalViewIn) {
return await http.get(Api.getGeneralView, params)
}

这样params入参就不会标红了。

  1. 对象使用变量索引时,会标红,报:
阅读全文 »

从0-1搭建Vue3+Vite3模板工程(1)-创建工程

从0-1搭建Vue3+Vite3模板工程(2)-安装依赖

0-1搭建Vue3+Vite3模板工程(3)-布局

左侧菜单导航封装,包含多级菜单,可以配置隐藏某一个菜单。

  1. 先配置好路由,根据自己的需求,建立好相应的目录;

我的目录如下:

image.png

所以我的路由配置如下(别忘了提前在scr/views/下建立相应的页面级组件,在路由中需要引用):
src\router\index.ts:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
import { createRouter, createWebHistory, RouteRecordRaw } from "vue-router"
import Layout from "@/layout/Index.vue"
export const routes: Array<RouteRecordRaw> = [
{
path: "/",
component: Layout,
redirect: "/home",
meta: {
title: "首页",
icon: "House",
hidden: false,
roles: [],
},
children: [
{
path: "/home",
component: () => import("@/views/home/index.vue"),
name: "home",
meta: {
title: "首页",
icon: "House",
hidden: true,
roles: [],
},
},
],
},

{
path: "/system",
component: Layout,
name: "system",
meta: {
title: "系统管理",
icon: "Medal",
hidden: false,
roles: [],
},
children: [
{
path: "/system/department",
component: () => import("@/views/system/department/index.vue"),
name: "department",
meta: {
title: "机构管理",
icon: "MostlyCloudy",
hidden: false,
roles: [],
},
},
{
path: "/userList",
component: () => import("@/views/system/user/index.vue"),
name: "userList",
meta: {
title: "用户管理",
icon: "MostlyCloudy",
roles: ["sys:user"],
hidden: false,
},
},
{
path: "/roleList",
component: () => import("@/views/system/role/index.vue"),
name: "roleList",
meta: {
title: "角色管理",
icon: "MostlyCloudy",
roles: ["sys:role"],
hidden: false,
},
},
{
path: "/menuList",
component: () => import("@/views/system/menu/index.vue"),
name: "menuList",
meta: {
title: "权限管理",
icon: "MostlyCloudy",
roles: ["sys:menu"],
hidden: false,
},
},
],
},
{
path: "/goods",
component: Layout,
name: "goods",
meta: {
title: "商品管理",
icon: "MostlyCloudy",
roles: ["sys:goods"],
hidden: false,
},
children: [
{
path: "/goodCategory",
component: () =>
import("@/views/goods/goodsCategory/index.vue"),
name: "goodCategory",
meta: {
title: "商品分类",
icon: "MostlyCloudy",
roles: ["sys:goodsCategory"],
hidden: false,
},
},
],
},
{
path: "/systenConfig",
component: Layout,
name: "systenConfig",
meta: {
title: "系统工具",
icon: "MostlyCloudy",
roles: ["sys:systenConfig"],
hidden: false,
},
children: [
{
path: "/document",
component: () => import("@/views/system/config/index.vue"),
name: "http://42.193.158.170:8089/swagger-ui/index.html",
meta: {
title: "接口文档",
icon: "MostlyCloudy",
roles: ["sys:document"],
hidden: false,
},
},
],
},
]
//创建
const router = createRouter({
history: createWebHistory(),
routes,
})
export default router

阅读全文 »

0-1搭建Vue3+Vite3模板工程(1)-创建工程

0-1搭建Vue3+Vite3模板工程(2)-安装依赖

接上篇。

通常后管平台多以左右布局或上下布局为主,本篇讲解如何进行整体布局,以左右布局为例。

  1. 在index.html中加入以下样式:
1
2
3
4
5
6
html,body,#app{
padding: 0px;
margin: 0px;
height: 100%;
box-sizing: border-box;
}
  1. 将main.ts引入的额外样式注释掉

image.png

  1. 在src下新建layout文件夹,在layout下新建index.vue文件,在此文件中写整体布局。
阅读全文 »

一些常见的tsconfig.json配置。TypeScript官方文档

英文:https://www.typescriptlang.org/docs/

中文:https://www.tslang.cn/docs/home.html

先简单上一个tsconfig.json的配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
{
"compilerOptions": {
"target": "esnext",
"useDefineForClassFields": true,
"module": "esnext",
"moduleResolution": "node",
"strict": true,
"jsx": "preserve",
"sourceMap": true,
"resolveJsonModule": true,
"esModuleInterop": true,
"lib": ["esnext", "dom"],
"skipLibCheck": true,
"baseUrl": ".",
"paths": {
"@/*":[
"src/*"
]
}

},
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
"exclude": ["node_modules"],
"suppressImplicitAnyIndexErrors":true, //
}

下面具体理解一下。

compilerOptions下的配置:

定义项目的运行时期望、JavaScript 的发出方式和位置以及与现有 JavaScript 代码的集成级别。

  1. target

    TypeScript文件编译后生成的javascript文件里的语法应该遵循哪个JavaScript的版本。可选项为:”ES5”, “ES6”/ “ES2015”, “ES2016”, “ES2017”或 “ESNext”

  2. useDefineForClassFields: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#the-usedefineforclassfields-flag-and-the-declare-property-modifier

  3. module

    告诉编译器对发出的.js文件中的模块使用什么语法。可选择 none、commonjs、amd、system、umd、es2015或esnext告诉编译器以哪种语法编写代码,意味着必须从哪个代码将其编译为commonjs。如果用于服务器端项目 如果使用的是Angular前端应用程序,则使用Node.js,然后可能使用CJS 可能不是ESM 较新的JS版本有时包含用于模块导入/导出的更多功能。 将export设置为”module”可以支持这些功能,而这些功能通常尚未添加到官方规范中。例如dynamic import的”ESNext”表达式。无论如何,编译器的目的是将代码编译成浏览器可理解的语法(commonjs) module影响发出代码的模块语法,而target影响其余代码。

  4. moduleResolution

    模块解析策略,ts默认用node的解析策略,即相对的方式导入, 可选值:node、classic
    如果未指定,则 –module commonjs 默认为 node,否则默认为 classic(包括 –module 设置为 amd、system、umd、es2015、esnext 等)Node 模块解析是 TypeScript 社区中最常用的,推荐用于大多数项目。 如果您在 TypeScript 中遇到导入和导出的解析问题,请尝试设置 moduleResolution: “node” 以查看它是否解决了问题。

  5. strict

    开启所有严格的类型检查

    • true => 同时开启 alwaysStrict, noImplicitAny, noImplicitThis 和 strictNullChecks
    • alwaysStrict:严格模式,为每个文件添加 “use strict”
    • noImplicitAny:不允许隐式 any,如果true,函数的形参必须带类型,如果叫不出class名的js对象,那就得any。比如(d:any)=>{};如果false, 则允许隐式any,函数的样子更像js (d)=>{}
    • noImplicitThis:不允许 this 为隐式 any
    • strictNullChecks:undefined 和 null 两个空类型的设计,使用上不方便,所以 通过strictNullChecks严格校验类型,让代码更安全
  6. jsx

    指定jsx代码用于的开发环境: ‘preserve’, ‘react-native’, or ‘react’

    • preserve:生成代码中会保留JSX以供后续的转换操作使用(比如:Babel)。另外,输出文件会带有.jsx扩展名。
    • react:会生成React.createElement,在使用前不需要再进行转换操作了,输出文件的扩展名为.js。
    • react-native:相当于preserve,它也保留了所有的JSX,但是输出文件的扩展名是.js
  7. sourceMap

    是否生成目标文件的sourceMap文件。此文件允许调试器和其他工具在实际使用发出的JavaScript文件时显示原始的TypeScript源代码。此文件为 .js.map (or .jsx.map) 格式,位于相应的.js 输出文件相同目录

  8. resolveJsonModule

    防止 ts文件中引入json文件,会报如下红色波浪线。TypeScript 2.9的resolveJsonModule功能,只要我使用ts-node执行应用程序,该功能就可以正常工作。

  9. esModuleInterop

    作用是支持使用import d from ‘cjs’的方式引入commonjs包。

  10. lib

    编译过程中需要引入的库文件的列表,告诉 typescript 编译器可以使用哪些功能。

    • 比如说,我们这里有一个 dom 的库文件,这个文件会告诉编译器 dom api 的接口,所以当我们在 ts 代码中使用 dom 的时候,比如说执行 “document.getElementById (“root”)” 这句话的时候,编译器就会知道该如何进行检查。
    • 如果我们不设置这个选项,那么编译器也有自己默认的库文件列表,一般来说是 [“dom”, “es6”,”DOM.Iterable”] 等等。
  11. skipLibCheck

    解决打包报vue-tsc --noEmit && vite build的错,忽略所有的声明文件(*.d.ts)的类型检查

  12. path

    用于拓宽引入非相对模块时的查找路径的。其默认值就是”./“,目的是解决项目代码层级较深相互之间引用起来会比较麻烦的问题,各种 …/,…/…/,…/…/…/ 等等。

    include

    用于指定要编译的路径列表,但是和files的区别在于,这里的路径可以是文件夹,也可以是文件,可以使用相对和绝对路径,而且可以使用通配符, 比如”./src”即表示要编译src文件夹下的所有文件以及子文件夹的文件。

    exclude

    ts 排除的文件

    将suppressImplicitAnyIndexErrors

    将suppressImplicitAnyIndexErrors 设为true 将禁止在对对象进行索引时报告有关隐式anys 的错误。

阅读全文 »

接上篇0-1搭建Vue3+Vite3模板工程(1)-创建工程

一、eslint、css 预处理器sass安装

  1. /tsconfig.json配置文件可以配置使用‘@’符号引入
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
{
"compilerOptions": {
"target": "esnext",
"useDefineForClassFields": true,
"module": "esnext",
"moduleResolution": "node",
"strict": true,
"jsx": "preserve",
"sourceMap": true,
"resolveJsonModule": true,
"esModuleInterop": true,
"lib": ["esnext", "dom"],
"skipLibCheck": true, // 解决打包报`vue-tsc --noEmit && vite build`的错,忽略所有的声明文件(*.d.ts)的类型检查
"baseUrl": ".",
"paths": {
"@/*":[
"src/*"
]
}

},
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
// ts 排除的文件
"exclude": ["node_modules"],
"suppressImplicitAnyIndexErrors":true, //
}

想了解这些配置含义可以参考这篇文章,
# tsconfig.json常见配置

  1. eslint安装
1
npm install --save-dev eslint eslint-plugin-vue

eslint配置文件: 在src文件夹下建立.eslintrc.ts文件,配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
module.exports = {
root: true,
parserOptions: {
sourceType: 'module'
},
parser: 'vue-eslint-parser',
extends: ['plugin:vue/vue3-essential', 'plugin:vue/vue3-stronglyrecommended', 'plugin:vue/vue3-recommended'],
env: {
browser: true,
node: true,
es6: true
},
rules: {
'no-console': 'off',
'comma-dangle': [2, 'never'] //禁止使用拖尾逗号
}
}
阅读全文 »

从0搭建一个工程可以更清楚的了解工程的组成,对工程的依赖、配置和运行理解更深入,以后搭建自己脚手架,生成自己的模板工程,提高效率。

技术栈

  1. Vite3.x
  2. Vue3.2
  3. TypeScript
  4. Vuex4.x
  5. Vue Router4.x
  6. CSS3

    准备

  7. node.js版本需要大于12.0.0
  8. npm

    创建项目

    根据vue3官网生成模板工程:https://v3.cn.vuejs.org/guide/installation.html#vite

记得将project-name换成自己项目的名字:

1
npm init vite@latest <project-name> --template vue

1.选择vue:
image.png
2.选择vue-ts:

image.png

3.看到这里就已经创建成功了:

image.png
4.根据提示启动工程:
cd vue3-demo npm install npm run dev
5.访问本地http://127.0.0.1:5173/:

阅读全文 »