详解Vite创建Vue3项目router-less-scss-pinia-持久化

前言

Vite 和 Webpack 都是现代化的前端构建工具,它们可以帮助开发者优化前端项目的构建和性能。虽然它们的目标是相似的,但它们在设计和实现方面有许多不同之处。webpack可以看我的上一篇文章

一、准备工作安装工具

这里我们简单介绍一下文章中使用到的工具,使用这些工具可以提高我们开发效率。

当然了只有nodejs 是必须要安装的,nvm 、Vite 、NRM 这些都不是必须的,

如果已经有了node npm 忽略以上,没有则看卸载node,nvm的详细使用方法-CSDN博客

二、创建Vue3项目

兼容注意:Vite需要Node.js的版本14.18+,16+

然而,有些模板需要依赖更高的 Node 版本才能正常运行,当你的包管理器发出警告时,请注意升级你的 Node 版本。

1-使用 NPM

javascript 复制代码
npm create vite@latest

使用 Yarn:

javascript 复制代码
yarn create vite@latest

使用 PNPM:

javascript 复制代码
pnpm create vite@latest

2-输入vue项目名称,我们这里就叫vite-project,默认就是这个

3-选择使用哪种框架,这里我们当然是选择Vue 了(Vite 不仅仅支持Vue 框架,还支持React、Vanilla、Lit 等前端主流框架)

4-选择Javascript 和TypeScript(Vue3 已经全面拥抱TypeScript,所以这里我们就选TypeScript)

5-到此我们就创建完成了,是不是很简单了

6-启动Vue 项目

javascript 复制代码
// 启动项目
npm run dev

当控制台看到如下所示,说明启动成功了

注意点:

我们如果之前都是用vue2写之前开发项目时候,我们这里突然转换用vue3开发,在使用Vscode的代码工具时候,vue3需要禁用了以前的vue2,为了兼容代码规范,代码高亮显示的一款插件安装插件Vetur不然代码会提示报错报红。再建议安装Prettier - Code formatter插件【该插件主要用于格式化代码】,为了高效快捷开发,再提供一款插件方便寻找路径和提示Path-intellisens

三、项目结构和特殊页面介绍

2- 特殊页面介绍

(1)index.html

首页文件的初始代码如下:

html 复制代码
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Vite + Vue + TS</title>
  </head>
  <body>
    <div id="app"></div>
    <script type="module" src="/src/main.ts"></script>
  </body>
</html>

看似这个是普通的html文件,让它与众不同的是

加了id="app"

整个项目只有这一个 html 文件,所以 这是一个 单页面应用,当我们打开这个应用,表面上可以有很多页面,实际上它们都只不过在一个 div 中

(2) App.vue

该文件称为"父组件",所有组件都是这个组件的儿子组件

.vue 文件是vue 中自定义的文件类型,我们把它看作成html即可,可以在里面写标签元素、css样式、js/ts代码

我们来看看其初始化的代码

javascript 复制代码
<script setup lang="ts">
import HelloWorld from './components/HelloWorld.vue'
</script>

<template>
  <div>
    <a href="https://vitejs.dev" target="_blank">
      <img src="/vite.svg" class="logo" alt="Vite logo" />
    </a>
    <a href="https://vuejs.org/" target="_blank">
      <img src="./assets/vue.svg" class="logo vue" alt="Vue logo" />
    </a>
  </div>
  <HelloWorld msg="Vite + Vue" />
</template>

<style scoped>
.logo {
  height: 6em;
  padding: 1.5em;
  will-change: filter;
  transition: filter 300ms;
}
.logo:hover {
  filter: drop-shadow(0 0 2em #646cffaa);
}
.logo.vue:hover {
  filter: drop-shadow(0 0 2em #42b883aa);
}
</style>

(3)main.ts

main.ts 通常是应用程序的入口文件, App.vue就是通过这个文件和 index.html 里的

产生联系的

javascript 复制代码
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'

createApp(App).mount('#app')
  • import { createApp } from 'vue' 导入了 Vue 的 createApp 函数,用于创建一个 Vue 应用实例。
  • import './style.css' 导入了一个 CSS 文件,这里可以忽略
  • import App from './App.vue' 导入了根组件 App ,而App又包含了所有子组件
  • createApp(App).mount('#app') 创建了一个 Vue 应用实例,并将根组件 App 挂载到具有 id 为 app 的 DOM 元素上。

(4)package.json 文件

package.json 主要是项目依赖配置。

javascript 复制代码
{
  "name": "vite-project", //指定项目的名称为 "vite-project"
  "private": true,
  "version": "0.0.0", //指定项目的版本号,这是一个初始版本号
  "type": "module",
  "scripts": { //定义了一些脚本命令,用于开发、构建和预览项目
    "dev": "vite", //启动开发服务器,用于在开发环境下运行项目。 我们前面通过npm run dev就是这里
    "build": "vue-tsc && vite build",//我们使用TypeScript ,需要将 TypeScript 代码编译为js
    "preview": "vite preview"
  },
  "dependencies": { //列出了项目的生产环境依赖项。
    "vue": "^3.3.11"
  },
  "devDependencies": { //列出了项目的开发环境依赖项。
    "@vitejs/plugin-vue": "^4.5.2",
    "typescript": "^5.2.2",
    "vite": "^5.0.8",
    "vue-tsc": "^1.8.25"
  }
}

四、项目出现报红,但可以运行,如何解决

1.创建vite-env.d.ts

javascript 复制代码
declare module "*.vue" {
  import { DefineComponent } from "vue"
  const component: DefineComponent<{}, {}, any>
  export default component
}
  1. 删除Vetur插件,安装更适合的Volar

五、安装路由以及配置文件

1-安装Typescript依赖

javascript 复制代码
npm install @types/node --save-dev

2-修改vite.config.ts配置文件代码

javascript 复制代码
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from 'path'

export default defineConfig({
  plugins: [vue()],
  //解决"vite use `--host` to expose"
  base: './',	//不加打包后白屏
  server: {             
    host: '0.0.0.0',	
    // port: 8080,      
    open: true
  },
  resolve:{   
    //别名配置,引用src路径下的东西可以通过@如:import Layout from '@/layout/index.vue'
    alias:[   
      {
        find:'@',
        replacement:resolve(__dirname,'src') 
      }
    ]
  }
})

3-安装路由

javascript 复制代码
npm install vue-router@4

在src目录下新建router文件夹,在router里创建index.ts文件

javascript 复制代码
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'
import Layout from '../components/HelloWorld.vue'

const routes: Array<RouteRecordRaw> = [
  {
  //路由初始指向
    path: '/',
    name: 'HelloWorld',
    component:()=>import('../components/HelloWorld.vue'),
  }
]

const router = createRouter({
  history: createWebHistory(),
  routes
})

export default router

4- main.ts中导入挂载路由

javascript 复制代码
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import router from './router'

const app = createApp(App);
app.use(router).mount('#app')

5- 修改App.vue管理路由

javascript 复制代码
<script setup lang="ts">
</script>
<template>
  <router-view></router-view>
</template>

<style>

</style>

6- 修改HelloWorld组件

javascript 复制代码
<template>
  <h1>HelloWorld</h1>
</template>

<script setup lang="ts">
</script>

<style scoped>
.read-the-docs {
  color: #888;
}
</style>

HelloWorld

五、安装less/scss

由于是使用vite,它提供了对 .scss, .sass, .less, .styl.stylus 文件的内置支持,但必须安装相应的预处理器依赖;

国内一般只使用 less 或 scss,所以我只写这两个安装

javascript 复制代码
 npm add -D less 
 npm add -D sass 

安装后可以直接使用less了 ,当然,也可以使用scss,一般只下一个就够了,我比较推荐scss

使用CSS 嵌套 可能会有嵌套报错,这时可以按下面的方法解决

javascript 复制代码
第一步下载
npm i postcss-nesting
 
第二步在vite.config.ts
import postcssNesting from 'postcss-nesting' //引入进来
export default defineConfig({
  css: {
    postcss: {
      plugins: [
        postcssNesting
      ],
    },
  },
  ......
});

六、自动导入

这个是我非常非常非常推荐的两个插件,不过用过element、naiveui等的人一般也会知道,尤大推荐

javascript 复制代码
npm install -D unplugin-vue-components unplugin-auto-import
javascript 复制代码
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from "path";
// 自动导入vue中hook reactive ref等
import AutoImport from "unplugin-auto-import/vite"
//自动导入ui-组件 比如说ant-design-vue  element-plus等
import Components from 'unplugin-vue-components/vite';
 
// https://vitejs.dev/config/
export default defineConfig({
	plugins: [
		vue(),
		AutoImport({
			//安装两行后你会发现在组件中不用再导入ref,reactive等
			imports: ['vue', 'vue-router'],
            //存放的位置
			dts: "src/auto-import.d.ts",
		}),
		Components({
			// 引入组件的,包括自定义组件
            // 存放的位置
            dts: "src/components.d.ts",
		}),
	],
 
})

七、安装pinia

因为是vue3+ts,安装pinia更好点,vuex拥抱ts没有pinia好,定义一个 Store | Pinia 中文文档

javascript 复制代码
 npm install pinia 
javascript 复制代码
/*
 * @Author: hukai huzhengen@gmail.com
 * @Date: 2024-09-18 11:23:48
 * @LastEditors: hukai huzhengen@gmail.com
 * @LastEditTime: 2024-09-18 14:43:47
 * @FilePath: \vite\vite-project\src\main.ts
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import router from './router'
import { createPinia } from 'pinia'
const pinia = createPinia()

const app = createApp(App);
app.use(pinia)
app.use(router).mount('#app')

在src下创建一个 store 文件夹,再创建一个 home.ts 文件

其它名也可以,因为pinia它有一个根文件,会把 defineStore 第一个参数当id值,相当于vuex中的 module 自动引入,也会在Vue.js devtools 插件中以第一个参数名展示(下面展示)

注意:defineStore第一个参数很重要,而且是唯一值。它的命名在devtools 插件能方便找到这个文件的数据,方便调试

javascript 复制代码
/*
 * @Author: hukai huzhengen@gmail.com
 * @Date: 2024-09-18 14:48:26
 * @LastEditors: hukai huzhengen@gmail.com
 * @LastEditTime: 2024-09-18 14:48:57
 * @FilePath: \vite\vite-project\src\store\index.ts
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
import { defineStore } from 'pinia'
// useMain  可以是 useUser、useCart 之类的名字 
// defineStore('main',{..}) 在devtools 就使用 main 这个名
export const useMain = defineStore('main', {
    // 相当于data
    state: () => {
        return {
            // 所有这些属性都将自动推断其类型,如果推断失败可以试下 as xxx
            counter: 0,
            name: 'Eduardo',
        }
    },
    // 相当于计算属性
    getters: {
        doubleCount: (state) => {
            return state.counter * 2
        },
    },
    // 相当于vuex的 mutation + action,可以同时写同步和异步的代码
    actions: {
        increment() {
            this.counter++
        },
        randomizeCounter() {
            setTimeout(() => {
                this.counter = Math.round(100 * Math.random())
            }, 0);
        },
        // 如果是异步
        async fnName() {
            // await
        }
    },
})

在要使用pinia的组件

以下使用只是用的比较常用的方法,还有其它方法请查看官网 定义一个 Store | Pinia 中文文档

javascript 复制代码
<!--
 * @Author: hukai huzhengen@gmail.com
 * @Date: 2024-09-18 14:44:55
 * @LastEditors: hukai huzhengen@gmail.com
 * @LastEditTime: 2024-09-18 15:52:05
 * @FilePath: \vite\vite-project\src\components\Aouts.vue
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<template>
    <div>counter:{{counter}}</div>
    <div>doubleCount:{{doubleCount}}</div>
    <a-button @click="main.randomizeCounter()">counter(round)</a-button>
    <a-button type="primary" @click="main.increment()">counter++</a-button>
 
    <div>{{name}}</div>
    <a-button @click="amend()">修改</a-button>
</template>
<script setup lang='ts'>
 
//引入想要的pinia文件 {} 里面就是对应导出的名字
import { useMain } from '../store/home.ts'
import { storeToRefs } from 'pinia';
 
const main = useMain()
// 解构main里面的state和getters的数据,
// 使用storeToRefs解构才有响应式,响应式可以直接修改数据,不过这我只用来渲染
let { counter,name ,doubleCount } = storeToRefs(main)
 
//(常用方法三种)
//常用方法一: 使用数据
console.log( counter );
//使用方法(方法可以直接解构,不需要使用storeToRefs)
main.increment()
const T = ref(1)
 console.log( T )
 
// 常用方法二:修改数据
// counter = 9999
 
//常用方法三:
//进阶使用$patch,多个修改
const amend=()=>{
    main.$patch((state) => {
        state.counter += 10;
        state.name = '张三'
    })
}
 
</script>

Vue.js devtools 环境下通过 defineStore 第一个参数当id值找到对应的仓库

vue-devtools插件

如果你没有vue-devtools,就去谷歌扩展应用

然后搜索,直接安装就可以了,从控制台中打开

数据持久化插件

如果你想要数据持久化可以试下这个插件,简单使用

pinia 和 vuex 一样,数据是短时的,只要一刷新页面,数据就会恢复成初始状态,为了避免这个问题,可以对其采用持久化保存方法。

持久化保存的原理是在 pinia 中数据更新时,同步保存到 localStorage 或 sessionStorage 中,刷新后从本地存储中读取数据,你可以选择自己去写,但是实现起来并不像想象中那么容易,当然,也没那么难。

我推荐使用插件去实现持久化存储,这样更便捷,省时省力。推荐插件为 pinia-plugin-persist,当然,实现持久化存储的插件肯定不止这一种,想用别的也无所谓,本文仅对这款插件讲解使用方法

1. 安装
javascript 复制代码
yarn add pinia-plugin-persist
# 或者使用 npm
npm install pinia-plugin-persist
2. 引入
javascript 复制代码
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'

const pinia = createPinia()

createApp(App).use(pinia).mount('#app') // vue3 的简写语法
3. 使用插件
方式1:默认保存

下面这种写法会将当前模块中的所有数据都进行持久化保存,默认保存在 sessionStorage 中, key 为模块 id,刷新页面不需要手动读取数据,插件会自动读取。

store/user.ts

javascript 复制代码
import { defineStore } from 'pinia'

export const useUserStore = defineStore('user', {
  state: () => ({
    name: null,
    age: null,
    sex: null,
  }),
  persist: {
    enabled: true // true 表示开启持久化保存
  }
})
方式2:设置 key 、指定保存内容

你可以主动设置 key 名,也可以指定哪些数据保存,默认会保存当前模块全部数据。

store/user.ts

javascript 复制代码
export const useUserStore = defineStore('storeUser', {
  state: () => ({
    name: null,
    age: null,
    sex: null,
  }),
  persist: {
    enabled: true,
    strategies: [
      {
        key: 'user',
        storage: localStorage,
        paths: ['name'] 
      },
    ],
  },
})

你甚至可以对不同数据设置不同的本地存储方式。

javascript 复制代码
export const useUserStore = defineStore('storeUser', {
  state: () => ({
    name: null,
    age: null,
    sex: null,
  }),
  persist: {
    enabled: true,
    strategies: [
      { storage: sessionStorage, paths: ['name'] },
      { storage: localStorage, paths: ['age'] },
    ],
  },
})

保存到 cookie 中当然也是可以的,不过需要手动添加 cookie 的保存方式,同样,此处也是推荐使用插件 js-cookie 来完成。

javascript 复制代码
npm install js-cookie
javascript 复制代码
import Cookies from 'js-cookie'

const cookiesStorage: Storage = {
  setItem (key, state) {
    return Cookies.set(key, state.accessToken, { expires: 3 }) // 设置有效期 3 天,不设置默认同 sessionStorage 有效期一致
  },
  getItem (key) {
    return JSON.stringify({
      accessToken: Cookies.get(key),
    })
  },
}

export const useUserStore = defineStore('storeUser', {
  state: () => ({
    name: null,
    age: null,
    sex: null,
    accessToken: 'xxxxxxxxx',
  }),
  persist: {
    enabled: true,
    strategies: [
      {
        storage: cookiesStorage,
        paths: ['accessToken'] // cookie 一般用来保存 token
      },
    ],
  },
})
方式4:2023-12-08更新:持久化存储插件推荐修改

pinia-plugin-persist 在 typeScript 中有类型声明问题。推荐插件改为 pinia-plugin-persistedstate。官网地址如下:

https://prazdevs.github.io/pinia-plugin-persistedstate/zh/

官网的文档非常详细,且使用方法与 pinia-plugin-persist 类似,因此本文不做过多赘述,仅简要描述下使用方法

1.安装插件
javascript 复制代码
npm i pinia-plugin-persistedstate
2、引入插件

main.ts

javascript 复制代码
import { createPinia } from 'pinia'
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'

const pinia = createPinia()
pinia.use(piniaPluginPersistedstate)
3、使用插件
javascript 复制代码
import { defineStore } from 'pinia'

export const useStore = defineStore('main', {
  state: () => {
    return {
      someState: '你好 pinia',
    }
  },
  persist: true,
})

只需要添加 persist: true, 整个 store 都将被持久化存储。

当然也可以指定部分数据持久化,方法如下:

javascript 复制代码
import { defineStore } from 'pinia'

export const useUserStore = defineStore('user', {
  state: () => ({
    name: null,
    age: null,
    sex: null,
    info: {
    	des: null
    }
  }),
  persist: {
    paths: ['name', 'info.des'],
  },
})

这样则只有 nameinfo.des 被持久化保存了。

相关推荐
苹果酱05676 小时前
Golang的文件加密技术研究与应用
java·vue.js·spring boot·mysql·课程设计
vvw&6 小时前
如何在 Ubuntu 22.04 上安装 Caddy Web 服务器教程
linux·运维·服务器·前端·ubuntu·web·caddy
AH_HH8 小时前
如何学习Vue设计模式
vue.js·学习·设计模式
落日弥漫的橘_8 小时前
npm run 运行项目报错:Cannot resolve the ‘pnmp‘ package manager
前端·vue.js·npm·node.js
梦里小白龙8 小时前
npm发布流程说明
前端·npm·node.js
No Silver Bullet8 小时前
Vue进阶(贰幺贰)npm run build多环境编译
前端·vue.js·npm
怜渠客9 小时前
Google Chrome 去除更新 Windows
chrome·windows
破浪前行·吴9 小时前
【初体验】【学习】Web Component
前端·javascript·css·学习·html
猛踹瘸子那条好腿(职场发疯版)9 小时前
Vue.js Ajax(vue-resource)
vue.js·ajax·okhttp
泷羽Sec-pp9 小时前
基于Centos 7系统的安全加固方案
java·服务器·前端