一、TS 环境说明
1. 编译器选项:
Vite 仅执行 .ts 文件的转译工作,并 不 执行任何类型检查。
在 tsconfig.json
中的 compilerOptions
下设置 "isolatedModules": true
。
"isolatedModules": true,
2. 客户端类型
将 vite/client
添加到 tsconfig
中的 compilerOptions.types
下:
"types": ["vite/client"],
二、setup
1. Vue 3 支持三种写法:
- Option API
- Composition API
<script setup>
(Composition API 的语法糖)
<!-- 组合式 API 语法糖 script setup -->
<script lang="ts" setup>
import { ref, defineProps, defineEmits } from 'vue'
// 声明一个数据接收 defineProps
const props = defineProps({
msg: {
type: String,
default: ''
}
})
// 自定义事件
const emit = defineEmits(['increment'])
const msg = 'abc'
const count = ref(100)
const increment = () => {
count.value++
console.log('msg=>', props.msg)
// => Hello Vue 3 + TypeScript + Vite
// => abc (重名后会以本地的赋值为主)
// 导出自定义事件
emit('increment')
}
</script>
2. 编译宏
编译器宏,例如defineProps和defineEmits生成no-undef警告;
您需要在 ESLint 配置文件中启用编译器宏环境。如果您不想全局公开这些变量,则可以/* global defineProps, defineEmits */改用。
// 引用文件
// import { ref, defineProps, defineEmits } from 'vue'
import { ref } from 'vue'
在 .eslintrc.js
下:
module.exports = {
globals: {
// 'vue/setup-compiler-macros': true
// 去掉 以下方法未引用时报错
defineProps: 'readonly',
defineEmits: 'readonly',
defineExpose: 'readonly',
withDefaults: 'readonly'
},
}
三、渲染函数、JSX、TSX
1. 渲染函数
Vue 推荐在绝大多数情况下使用模板来创建你的 HTML。然而在一些场景中,你真的需要 JavaScript 的完全编程的能力。这时你可以用渲染函数,它比模板更接近编译器。
2. jsx、tsx
// 安装
npm i -D @vitejs/plugin-vue-jsx
配置 vite.config.ts
插件:
import vueJsx from '@vitejs/plugin-vue-jsx'
plugins: [
vueJsx({
// 配置选项
})
]
四、VueRouter
1. 基础配置
安装:
npm install vue-router@4
新建 src / router / index.ts
文件:
import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router'
const routes: RouteRecordRaw[] = [
{
path: '/',
name: 'home',
component: () => import('../views/home/index.vue')
},
{
path: '/login',
name: 'login',
component: () => import('../views/login/index.vue')
}
]
const router = createRouter({
history: createWebHashHistory(), // 路由模式
routes // 路由规则
})
export default router
2. 路由页面
新建 src / views / home / index.vue
文件:
<template>
<h1>主页</h1>
</template>
<script lang="ts" setup></script>
<style lang="scss" scoped></style>
新建 src / views / login / index.vue
文件:
<template>
<h1>登录</h1>
</template>
<script lang="ts" setup></script>
<style lang="scss" scoped></style>
3. eslint 报错
Component name “index” should always be multi-word.eslintvue/multi-word-component-names
组件名称“索引”应始终为多字 vue/多字组件名称
编辑 .eslintrc.js
文件:
rules: {
// 去掉 单字 组件名称报错
'vue/multi-word-component-names': ['error', {
ignores: ['index']
}]
}
五、Vuex
1. 基础配置
// 安装
npm install vuex@next --save
新建 src / store / index.ts
文件:
import { createStore, Store, useStore as baseUseStore } from 'vuex'
import { InjectionKey } from 'vue'
export interface State {
count: number
foo: string
}
// 定义 injection key
export const key: InjectionKey<Store<State>> = Symbol('store')
// 创建一个新的 store 实例
export const store = createStore<State>({
state () {
return {
count: 0,
foo: 'Hello world'
}
},
mutations: {
increment (state) {
state.count++
}
}
})
// 定义自己的 `useStore` 组合式函数
export function useStore () {
return baseUseStore(key)
}
2. 全局引用
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import { store, key } from './store'
createApp(App)
.use(router)
.use(store, key)
.mount('#app')
3. 组件调用
<template>
<h1>主页</h1>
<p>{{ $store.state.count }}</p>
<p>{{ store.state.count }}</p>
</template>
<script lang="ts" setup>
// ts 中使用 store
// import { useStore } from 'vuex'
// const store = useStore()
// console.log(store.state.count)
// import { useStore } from 'vuex'
// import { key } from '../../store'
// const store = useStore(key)
// console.log(store.state.)
import { useStore } from '../../store'
const store = useStore()
console.log(store.state)
</script>
<style lang="scss" scoped></style>
4. ts 支持
新建 src / vuex.d.ts
文件:
/* eslint-disable no-unused-vars */
import { ComponentCustomProperties } from 'vue'
import { Store } from 'vuex'
import { State } from './store/index'
declare module '@vue/runtime-core' {
// 声明自己的 store state
// interface State {
// count: number
// }
// 为 `this.$store` 提供类型声明
interface ComponentCustomProperties {
$store: Store<State>
}
}
六、配置路径别名
1. 基础配置
// 在 ts 模块中加载 node 核心模块需要安装 node 的类型补充模块
npm i -D @types/node
编辑 vite.config.ts
文件:
import path from 'path'
export default defineConfig({
...
resolve: {
alias: {
'@': path.join(__dirname, 'src')
}
}
2. 绝对路径
编辑 tsconfig.json
文件:
{
"compilerOptions": {
...
// 绝对路径
"paths": { "@/*": [ "src/*" ]}
3. 示例
编辑 src / views / home / index.vue
文件:
<template>
<h1>主页</h1>
<img src="@/assets/logo.png">
<div class="box" />
</template>
<script lang="ts" setup>
import User from '@/api/user'
console.log(User)
</script>
<style lang="scss" scoped>
.box {
width: 200px;
height: 200px;
background: url('@/assets/logo.png');
}
</style>
七、CSS 样式管理
1. 基础配置
// 安装
# .scss and .sass
npm install -D sass
# .less
npm install -D less
# .styl and .stylus
npm install -D stylus
// mac
$ gem install sass
// 遇到权限问题
$ sudo gem install sass
// sass
$ npm i sass-loader node-sass -D
// 安装依赖
$ npm install stylus-loader css-loader style-loader --save-dev
2. 样式文件
variables.scss # 全局 Sass 变量
mixin.scss # 全局 mixin
common.scss # 全局公共样式
transition.scss # 全局过渡动画样式
index.scss # 组织统一导出
编辑 src / styles / index.scss
文件:
@import './variables.scss';
@import './mixin.scss';
@import './transition.scss';
@import './common.scss';
3. 全局引用
编辑 main.js
文件:
// 全局样式
import './styles/index.scss'