从0创建一个Vue3项目
本文目标是从0搭建一个vue3+vite+ts+pinia+eslint的项目,以及学习和熟悉Vue3的新特性
vite版本2.9.9
搭建vue3+vite+ts+eslint的脚手架
输入以下命令创建一个vue3+ts的脚手架
npm init vite@latest vue3-vite-ts-test0 -- --template vue-ts
安装并启动项目
npm install --registry=https://registry.npm.taobao.org
npm run dev
初始页面
添加Eslint支持(使用Airbnb规则)
安装相关依赖
npm install eslint --save-dev --registry=https://registry.npm.taobao.org
npm install eslint-plugin-vue --save-dev --registry=https://registry.npm.taobao.org
npm install eslint-config-airbnb-base --save-dev --registry=https://registry.npm.taobao.org
添加相关配置
创建.eslintrc.js文件(项目根目录)
module.exports = {
root: true,
env: {
browser: true, // browser global variables
es2021: true, // adds all ECMAScript 2021 globals and automatically sets the ecmaVersion parser option to 12.
},
parserOptions: {
ecmaVersion: 12,
},
}
为了规范团队成员代码格式,以及保持统一的代码风格,项目采用当前业界最火的Airbnb规范,并引入代码风格管理工具Prettier。
module.exports = {
root: true,
env: {
browser: true, // browser global variables
es2022: true, // adds all ECMAScript 2021 globals and automatically sets the ecmaVersion parser option to 12.
},
parserOptions: {
ecmaVersion: 12,
},
extends: [
'plugin:vue/vue3-recommended',
'airbnb-base',
],
}
这时重启项目就可以看到项目使用了刚刚配置的eslint规则,如果没有的话,可以尝试重启编辑器的eslint服务。
本次项目不单独引入prettier,而是使用eslint插件将prettier作为eslint规则执行。
npm install --save-dev eslint-plugin-prettier
npm install --save-dev --save-exact prettier
修改.eslintrc.js文件
module.exports = {
root: true,
env: {
browser: true,
es2022: true,
},
parserOptions: {
ecmaVersion: 12,
},
extends: ['plugin:vue/vue3-recommended', 'airbnb-base'],
plugins: ['prettier'], // ++
rules: {
'prettier/prettier': 'error', // ++
},
};
配置到此时,大概率会遇到 eslint 规则和 prettier 规则冲突的情况,比如下图。eslint告诉我们要使用单引号,但是改为单引号以后,prettier有告诉我们要使用双引号。
这时候就需要另一个eslint的插件 eslint-config-prettier,这个插件的作用是禁用所有与格式相关的eslint规则,也就是说把所有格式相关的校验都交给 prettier 处理。
npm install --save-dev eslint-config-prettier
修改.eslintrc.js文件
module.exports = {
root: true,
env: {
browser: true,
es2022: true,
},
parserOptions: {
ecmaVersion: 12,
},
extends: [
"plugin:vue/vue3-recommended",
"airbnb-base",
"plugin:prettier/recommended",
],
plugins: ["prettier"], // ++
rules: {
"prettier/prettier": "error", // ++
},
};
plugin:prettier/recommended 的配置需要注意的是,一定要放在最后。因为extends中后引入的规则会覆盖前面的规则。
我们还可以在根目录新建 .prettierrc.js 文件自定义 prettier 规则,保存规则后,重启编辑器的eslint服务以更新编辑器读取的配置文件。
创建.prettierrc.js文件(项目根目录)
// .prettierrc.js
module.exports = {
singleQuote: true, // 使用单引号
}
其他规则配置
npm install --save-dev @typescript-eslint/eslint-plugin @typescript-eslint/parser
修改.eslintrc.js文件
module.exports = {
root: true,
env: {
browser: true,
es2022: true,
},
parserOptions: {
ecmaVersion: 12,
parser: '@typescript-eslint/parser',
},
extends: [
'plugin:vue/vue3-recommended',
'airbnb-base',
'plugin:prettier/recommended',
],
plugins: ['prettier'], // ++
rules: {
'prettier/prettier': 'error', // ++
},
};
适配@通配符
在tsconfig.json中添加如下配置
"baseUrl": ".",
"paths": {
"@/*": ["src/*"]
}
tsconfig.json完整示例
{
"compilerOptions": {
"target": "esnext",
"useDefineForClassFields": true,
"module": "esnext",
"moduleResolution": "node",
"strict": true,
"jsx": "preserve",
"sourceMap": true,
"resolveJsonModule": true,
"isolatedModules": true,
"esModuleInterop": true,
"lib": ["esnext", "dom"],
"skipLibCheck": true,
"baseUrl": ".",
"paths": {
"@/*": ["src/*"]
}
},
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
"references": [{ "path": "./tsconfig.node.json" }],
"exclude": ["node_modules"]
}
在.eslintrc.js中添加如下代码
settings: {
'import/resolver': {
typescript: {},
},
},
.eslintrc.js完整示例
module.exports = {
root: true,
env: {
browser: true,
es2022: true,
},
parserOptions: {
ecmaVersion: 12,
parser: '@typescript-eslint/parser',
},
extends: [
'plugin:vue/vue3-recommended',
'airbnb-base',
'plugin:prettier/recommended',
],
plugins: ['prettier'],
rules: {
'prettier/prettier': 'error',
'vue/multi-word-component-names': 'off',
},
settings: {
'import/resolver': {
typescript: {},
},
},
};
安装eslint-import-resolver-typescript插件
npm install --save-dev eslint-import-resolver-typescript
安装@types/node模块
npm install --save-dev @types/node
在vite.config.ts中配置
resolve: {
alias: [
{
find: '@',
replacement: resolve(__dirname, './src'),
},
{
find: 'assets',
replacement: resolve(__dirname, './src/assets'),
},
],
extensions: ['.ts', '.js'],
},
vite.config.ts全部配置
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import { resolve } from 'path';
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
resolve: {
alias: [
{
find: '@',
replacement: resolve(__dirname, './src'),
},
{
find: 'assets',
replacement: resolve(__dirname, './src/assets'),
},
],
extensions: ['.ts', '.js'],
},
});
重启项目即可
解决Missing file extension “ts” for "./XXX"的问题
// 在rules下
'import/extensions': [
2,
'ignorePackages',
{
js: 'never',
jsx: 'never',
ts: 'never',
tsx: 'never',
},
],
修改后的.eslintrc.js
module.exports = {
root: true,
env: {
browser: true,
es2022: true,
},
parserOptions: {
ecmaVersion: 12,
parser: '@typescript-eslint/parser',
},
extends: [
'plugin:vue/vue3-recommended',
'airbnb-base',
'plugin:prettier/recommended',
],
plugins: ['prettier'],
settings: {
'import/resolver': {
typescript: {},
},
},
rules: {
'prettier/prettier': 'error',
'vue/multi-word-component-names': 'off',
'import/extensions': [
2,
'ignorePackages',
{
js: 'never',
jsx: 'never',
ts: 'never',
tsx: 'never',
},
],
'import/no-extraneous-dependencies': 0,
},
};
解决’vite’ should be listed in the project’s dependencies, not devDependencies的问题
// rules下
'import/no-extraneous-dependencies': 0,
修改后的.eslintrc.js
module.exports = {
root: true,
env: {
browser: true,
es2022: true,
},
parserOptions: {
ecmaVersion: 12,
parser: '@typescript-eslint/parser',
},
extends: [
'plugin:vue/vue3-recommended',
'airbnb-base',
'plugin:prettier/recommended',
],
plugins: ['prettier'],
settings: {
'import/resolver': {
typescript: {},
},
},
rules: {
'prettier/prettier': 'error',
'vue/multi-word-component-names': 'off',
'import/extensions': [
2,
'ignorePackages',
{
js: 'never',
jsx: 'never',
ts: 'never',
tsx: 'never',
},
],
'import/no-extraneous-dependencies': 0,
},
};
添加sass支持
npm install sass --save-dev --registry=https://registry.npm.taobao.org
npm install sass-loader --save-dev --registry=https://registry.npm.taobao.org
添加vue-router
安装
npm install vue-router@4
创建并绑定vue-router
1.创建src/router文件夹以及src/router/index.ts文件
2.编写路由文件index.ts
import { createRouter, createWebHistory } from 'vue-router';
const router = createRouter({
history: createWebHistory(),
routes: [
{
path: '/',
redirect: 'main',
},
{
path: '/main',
name: 'main',
component: () => import('@/views/main/index.vue'),
},
],
});
export default router;
3.在main.ts中添加router
import { createApp } from 'vue';
import router from './router';
import App from './App.vue';
const app = createApp(App);
app.use(router);
app.mount('#app');
4.修改App.vue应用router-view标签
<template>
<router-view></router-view>
</template>
<script setup lang="ts"></script>
<style>
#app {
}
</style>
5.编写具体的页面vue文件
这里是’@/views/main/index.vue’文件
<script lang="ts" setup></script>
<template>
<div>11111111111111111</div>
</template>
*添加UI框架Arco Design
参考文档:https://arco.design/vue/docs/start
安装
npm install --save-dev @arco-design/web-vue
完整引入
import { createApp } from 'vue';
import ArcoVue from '@arco-design/web-vue';
import router from './router';
import App from './App.vue';
import '@arco-design/web-vue/dist/arco.css';
const app = createApp(App);
app.use(router);
app.use(ArcoVue);
app.mount('#app');
添加状态管理pinia支持
安装
npm install pinia
在main.ts中引入pinia
import { createPinia } from 'pinia';
app.use(createPinia());
创建store文件夹并新建ts-store文件
新建store/system.ts
import { defineStore } from 'pinia';
const system = defineStore('system', {
state: (): {
name: string | null;
user: string | null;
price: number;
[propName: string]: any;
} => {
return {
name: null,
user: null,
price: 10,
};
},
getters: {
doublePrice(): number {
return this.price * 2;
},
},
actions: {
increment() {
this.price += 1;
},
},
});
export default system;
使用store
<template>
<div>11111</div>
<div>{{ system.name }}</div>
<div>{{ system.user }}</div>
<div>{{ system.doublePrice }}</div>
</template>
<script lang="ts" setup>
import systemStore from '@/store/system';
const system = systemStore();
if (!system.name) {
console.log('重新赋值【name】');
system.name = '你好';
}
if (!system.user) {
console.log('重新赋值【user】');
system.user = '甲天下';
}
console.log(new Date().getTime());
system.selfname = '家天下';
setTimeout(() => {
console.log('计时10秒');
console.log(new Date().getTime());
system.$reset();
system.price = 40;
system.increment();
}, 10000);
</script>
<script lang="ts">
export default {
mounted() {
console.log(this);
},
};
</script>
Vue3新概念(部分解释)
ref
官方解释:https://v3.cn.vuejs.org/api/refs-api.html#ref
接收一个初始值并返回一个响应式且可变的 ref 对象,ref 对象仅有一个 .value
property,指向该内部值。
const count = ref(0)
console.log(count.value) // 0
count.value++
console.log(count.value) // 1