我们在学习本文时遇到的一些问题及其解决方案并不一定是最好的解决方案。如果您有更好的解决方案,欢迎在评论区留言讨论。
学习文档
Vue3
Vue2 迁移
Vue 路由器 4
Vite
Typescript 入门指南
母语问题
- setTimeout 类型问题:
开头加window
,表示是web,否则编辑器要求使用NodeJS.Timeout
类型,但无法编译。
let timer: number = window.setTimeout(() => {
...
}, 17)
setInterval
是一样的。
- 卡片
优先使用Map对象来实现需求,而不是常规对象,否则判断类型会比较困难。
const modeMaps = new Map<string, string>([
['clickable', 'RightOutlined'],
['closable', 'CloseOutlined']
])
代替:
const modeMap = {
'clickable': 'RightOutlined',
'closable': 'CloseOutlined',
}
Eslint 配置
- 使用以下标准,否则会出现未知问题。
extends: [
'plugin:vue/vue3-essential',
'eslint:recommended',
'@vue/typescript/recommended',
'@vue/prettier',
'@vue/prettier/@typescript-eslint'
]
- 还有一个规则是必须先定义的,否则有些交叉引用的服务可能不满足这个规则。
rules: {
'@typescript-eslint/no-use-before-define': 'off',
'@typescript-eslint/no-empty-function': 'off',
'@typescript-eslint/camelcase': 'off',
'@typescript-eslint/no-explicit-any': 'off',
}
别名
需要安装相关声明
npm i -D @types/node
vue-cil处理方法
const { resolve } = require('path')
module.exports = {
chainWebpack: config => {
// alias
config.resolve.alias.set('@', resolve('path/to/xxx'))
}
}
Vite加工方法
需要安装相关声明
npm i -D @types/node
vue-cil处理方法
const { resolve } = require('path')
module.exports = {
chainWebpack: config => {
// alias
config.resolve.alias.set('@', resolve('path/to/xxx'))
}
}
Vite加工方法
vite.config.ts
const { resolve } = require('path')
export default defineConfig({
resolve: {
alias: [{ find: '@', replacement: resolve('path/to/xxx') }]
}
})
Vue 反应式
Proxy
实现响应能力本质上是将原始对象包装在层中以生成新对象。可能存在原对象占用内存无法释放的问题。因此,在声明响应式对象时,尽量不要使用任何变量来引用原始对象,而是将对象直接放在reactive
中。
不推荐的做法:
import {reactive} from 'vue'
export default {
setup() {
let obj = { name: '零一', age: 23 } // 原始对象
const state = reactive(obj) // 将obj包装成响应式
return {state}
}
}
推荐做法:
import {reactive} from 'vue'
export default {
setup() {
// 不再先声明原始对象
const state = reactive({ name: '零一', age: 23 })
return {state}
}
}
Vue 道具
- 功能类型
官方介绍。
- 枚举类型
mode: {
type: String as PropType<'clickable' | 'closable'>,
default: 'default'
},
- validator或者default是一个函数,使用
=>
,否则会导致setup props参数Typescript异常
PS:如果是引用函数,则引用函数也必须是=>
Vue 手表
- 监听props.xxx,建议使用getter函数形式
watch(() => props.xxx, () => {
...
})
如果 props.xxx 是对象或数组
watch(() => props.xxx, () => {
...
}, {
deep: true
})
Vue 参考
- 引用 DOM
<div ref="root"></div>
setup() {
const root = ref(null)
...
onMounted(() => {
console.log(root.value) // HTMLElement
})
return {
root
}
}
在打字稿中应该这样写:
setup() {
const root = ref<HTMLElement>()
...
onMounted(() => {
console.log(root.value as HTMLElement) // HTMLElement
})
return {
root
}
}
- 参考组件
import FooComponent from 'path/to/FooComponent.vue'
setup() {
const foo = shallowRef<ComponentPublicInstance<typeof FooComponent>>()
...
onMounted(() => {
console.log(foo.value as ComponentPublicInstance) // ComponentPublicInstance
})
return {
foo
}
}
Svg 图标
使用 vue-svg-loader 构建的 vue-cli- 安装取决于
npm i -D vue-svg-loader@beta vue-loader
注:这是与vue同步的测试版本
- 在 vue.config.js 中配置
chainWebpack: config => {
// svg
const svgRule = config.module.rule('svg')
svgRule.uses.clear()
svgRule
.use('vue-loader-v16')
.loader('vue-loader-v16') // or `vue-loader-v16` if you are using a preview support of Vue 3 in Vue CLI
.end()
.use('vue-svg-loader')
.loader('vue-svg-loader')
}
使用 vite-svg-loader 构建
参考:www.npmjs.com/package/vit…
- 安装
npm install vite-svg-loader --save-dev
- 涂抹
vite.config.ts
import svgLoader from 'vite-svg-loader'
export default {
plugins: [vue(), svgLoader()]
}
tsconfig.json
{
"compilerOptions": {
"types": ["vite-svg-loader", "vite/client"]
}
}
使用 markRaw 格式返回对象本身
import { markRaw, defineComponent } from 'vue'
import TaobaoSvg from './svgs/taobao.svg'
export default defineComponent({
setup() {
return {
TaobaoSvg: markRaw(TaobaoSvg)
}
}
})
注:关于markRaw
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。