摘要
我一直觉得vue特别难入门,其实不是vue的语法难学,而是vue所附加的其他生态链让人头疼。
由此记录。
正文
实战项目可参考meethigher/code2word: Code2Word - 让高亮的代码完美呈现至 Word
一、Node版本管理 1.1 搭建node 1.1.1 Windows 准备nvm-windows ,是windows系统用来管理node版本的工具。使用过node的应该都知道,node新版本是完全不兼容旧版本的,这就是这个工具存在的意义
1
2
3
4
5
6
7
8
9
# 查看列表
nvm list
# 下载 16.16.0
nvm install 16.16.0
# 切换版本
nvm use 16.16.0
# 查看版本
node -v
npm -v
操作如图
展开
1.1.2 Linux 保证配置代理的基础上,执行如下命令
1
2
3
4
5
6
7
curl -L -o a.tar.gz https://github.com/nvm-sh/nvm/archive/refs/tags/v0.39.2.tar.gz && tar -zxvf a.tar.gz && mv nvm-0.39.2/ /usr/local/nvm
cat > /etc/profile.d/nvm.sh <<EOF
#!/usr/bin/env bash
export NVM_DIR="/usr/local/nvm"
[ -s "\$NVM_DIR/nvm.sh" ] && \. "\$NVM_DIR/nvm.sh" # This loads nvm
EOF
source /etc/profile && nvm --version
操作如图
展开
参考CentOS7下安装NVM_centos 安装nvm_veejaLiu的博客-CSDN博客
1.2 创建vue项目 参考文档简介 | Vue.js ,执行命令
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
C:\U sers\m eethigher\D esktop>npm init vue@3.4
npm WARN config global ` --global` , ` --local` are deprecated. Use ` --location= global` instead.
Vue.js - The Progressive JavaScript Framework
√ Project name: ... vue-admin
√ Add TypeScript? ... No
√ Add JSX Support? ... No
√ Add Vue Router for Single Page Application development? ... Yes
√ Add Pinia for state management? ... No
√ Add Vitest for Unit Testing? ... No
√ Add an End-to-End Testing Solution? » No
√ Add ESLint for code quality? ... No
Scaffolding project in C:\U sers\m eethigher\D esktop\v ue-admin...
Done. Now run:
cd vue-admin
npm install
npm run dev
按提示命令,启动项目
展开
二、项目理解 2.1 配置IDE 作为一个后端人员来说,还是更喜欢jetbrains家的产品,此处使用的webstorm。由于写js习惯性带;,习惯用"",所以需要配置自动添加分号。
进行ctrl+alt+L格式化代码时,即可自动添加。
展开
2.2 理解代码 1.) 理解main.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 解构出 createApp
import { createApp } from "vue" ;
// 导入根组件
import App from "./App.vue" ;
// 导入路由配置
import router from "./router" ;
// 导入全局样式
import "./assets/main.css" ;
// 创建一个根app实例
const app = createApp ( App );
// 将路由挂载到app实例
app . use ( router );
// 将app实例挂载到id为app的元素上
app . mount ( "#app" );
2.) 理解router.js,参考文档介绍 | Vue Router
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
/*
* 1. 先导入 vue-router
* createRouter 创建路由的方法
* createWebHistory 路由模式(History) 前面用的是 / 开头,一般是要后端配合使用,容易产生404
* createWebHashHistory 路由模式(Hash) 前面用的是 # 开头,无需配合
* */
import { createRouter , createWebHistory , createWebHashHistory } from "vue-router" ;
// 导入home组件
import HomeView from "../views/HomeView.vue" ;
// 配置路由规则
const routers = [
{
//访问时的路径
path : "/" ,
//命名路由,路由的别名
name : "home" ,
//当访问到对应路由后需要展示的组件
//路由的急加载
component : HomeView
},
{
path : "/about" ,
name : "about" ,
//路由的懒加载,对于一些不确定立即需要显示的页面,可以使用懒加载
component : () => import ( "../views/AboutView.vue" )
}
];
// 创建router
const router = createRouter ({
// 配置路由模式
history : createWebHistory ( import . meta . env . BASE_URL ),
// 配置路由规则
routes : routers
});
// 导出路由
export default router ;
展开
3.) 理解app.vue
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
<!--
在script标签中,带setup,说明在该script中写的所有代码,就是在setup中写的
-->
< script setup >
import { RouterLink , RouterView } from "vue-router" ;
//在setup中,不需要手动注册组件,直接导入即可使用
import HelloWorld from "./components/HelloWorld.vue" ;
</ script >
< template >
< header >
< div class = "wrapper" >
< HelloWorld msg = "You did it!" />
< nav >
<!--RouterLink表示声明式跳转-->
<!--还有编程式跳转 通过js跳转-->
<!--to属性指定需要跳转的路径-->
< RouterLink to = "/" > Home</ RouterLink >
< RouterLink to = "/about" > About</ RouterLink >
</ nav >
</ div >
</ header >
<!--RouterView:路由出口,所有的组件页面,都可以通过RouterView来展示-->
< RouterView />
</ template >
<!--
scoped该属性是用来标记当前样式只能在当前组件中使用
其存在的目的是为了防止样式冲突
-->
< style scoped >
header {
line-height : 1.5 ;
max-height : 100 vh ;
}
. logo {
display : block ;
margin : 0 auto 2 rem ;
}
nav {
width : 100 % ;
font-size : 12 px ;
text-align : center ;
margin-top : 2 rem ;
}
nav a . router-link-exact-active {
color : var ( -- color - text );
}
nav a . router-link-exact-active : hover {
background-color : transparent ;
}
nav a {
display : inline-block ;
padding : 0 1 rem ;
border-left : 1 px solid var ( -- color - border );
}
nav a : first-of-type {
border : 0 ;
}
@ media ( min-width : 1024px ) {
header {
display : flex ;
place-items : center ;
padding-right : calc ( var ( -- section - gap ) / 2 );
}
. logo {
margin : 0 2 rem 0 0 ;
}
header . wrapper {
display : flex ;
place-items : flex-start ;
flex-wrap : wrap ;
}
nav {
text-align : left ;
margin-left : -1 rem ;
font-size : 1 rem ;
padding : 1 rem 0 ;
margin-top : 1 rem ;
}
}
</ style >
三、搭建项目 3.1 置空项目 将不必要的文件都删除,最后的结构如图
展开
启动项目后是个空的
展开
3.2 安装css预编译less 安装
1
2
# 带上-D参数,表示安装到devDepencencies
npm install less
使用
1
2
3
4
<!--css预编译语言:less、sass-->
<!--webstorm不支持sass的代码提示,刚好我也不会-->
< style scoped lang = "less" >
</ style >
3.3 安装全局初始化样式 normalize - npm
安装
在main.js中全局引用
1
2
// 导入全局格式化标签样式
import "normalize.css/normalize.css" ;
3.4 安装element-plus 在element-plus中,元素名恰好是对应的class名称,可以直接配样式
快速开始 | Element Plus
安装
1
npm install element-plus
配置自动按需导入
1
npm install -D unplugin-vue-components unplugin-auto-import
按照官网要求修改vite.config.js
展开
3.5 安装element-icon Icon 图标 | Element Plus 安装
1
npm install @element-plus/icons-vue
实际使用时,手动按需引入即可,如下
1
import { Fold , Expand } from "@element-plus/icons-vue" ;
3.6 安装axios 3.6.1 配置axios Axios 安装
封装通用request.js
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
import axios from "axios" ;
//封装baseUrl
//开发环境development 打包命令npm run dev
//生产环境production 打包命令npm run build
const isDev = process . env . NODE_ENV == "development" ;
const dev = "http://127.0.0.1/api/" ;
const pro = "http://121.89.205.189:3000/" ;
const request = axios . create ({
baseURL : isDev ? dev : pro ,
timeout : 60000 , //单位毫秒
headers : { "X-Custom-Header" : "foobar" }
});
// 添加请求拦截器
request . interceptors . request . use ( function ( config ) {
// 在发送请求之前做些什么
return config ;
}, function ( error ) {
// 对请求错误做些什么
return Promise . reject ( error );
});
// 添加响应拦截器
request . interceptors . response . use ( function ( response ) {
// 2xx 范围内的状态码都会触发该函数。
// 对响应数据做点什么
return response ;
}, function ( error ) {
// 超出 2xx 范围的状态码都会触发该函数。
// 对响应错误做点什么
return Promise . reject ( error );
});
// 自定义各种数据请求
export default function ajax ( config ) {
//解构赋值 https://www.cnblogs.com/tfxz/p/12838739.html
// let node = {
// type: "Identifier"
// };
// // 使用解构来创建两个字段,type、name,如果node中该字段有值,则覆盖掉
// ({type = 'type', name = 'name'} = node);
// console.log(type); // "Identifier"
// console.log(name); // "name"
const { url = "" , method = "GET" , data = {}, headers = {}} = config ;
//判断请求类型
switch ( method . toUpperCase ()) {
case "GET" :
return request . get ( url , {
params : data
});
case "POST" :
//表单形式
if ( headers [ "content-type" ] == "application/x-www-form-url-encoded" ) {
//格式化数据
const obj = new URLSearchParams ();
for ( let key in data ) {
obj . append ( key , data [ key ]);
}
return request . post ( url , data , { headers });
}
//文件形式
if ( headers [ "content-type" ] == "multipart/form-data" ) {
//文件处理对象
let obj = new FormData ();
for ( let key in data ) {
obj . append ( key , data [ key ]);
}
return request . post ( url , data , { headers });
}
//json形式
return request . post ( url , data );
}
}
3.6.2 配置vite跨域 开发服务器选项 | Vite 官方中文文档
1
2
3
4
5
6
7
8
9
10
11
12
13
14
server : {
port : 80 ,
open : false , //自动打开
base : "./ " , //生产环境路径
/*配置代理转发,开发环境使用https://www.cnblogs.com/tik2012/p/16866356.html*/
proxy : { // 本地开发环境通过代理实现跨域,生产环境使用 nginx 转发
// 正则表达式写法
'^/api' : {
target : 'http://121.89.205.189:3000/' , // 后端服务实际地址
changeOrigin : true , //开启代理
rewrite : ( path ) => path . replace ( /^\/api/ , '' )
}
}
}
3.7 安装全局数据管理工具 可选框架,两者二选一即可
在vue2.x中推荐使用vuex,在vue3.x中推荐使用pinia。pinia相比vuex使用起来更简洁。
3.7.1 vuex 配置vuex Vuex 是什么? | Vuex 安装
封装通用vuex.js
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
// 使用vuex进行全局状态管理
import { createStore } from "vuex" ;
const store = createStore ({
//严格模式,在生产环境中,不能打开
strict : process . env . NODE_ENV !== "production" ,
//全局状态
state () {
return {
count : 100 ,
//用户信息
userInfo : {}
};
},
//项目中唯一修改数据的方法
//严格模式中,不允许在这里做异步,要在actions里面做。比如setTimeout等
mutations : {
add ( state ) {
state . count ++ ;
},
addNum ( state , amount ) {
state . count += amount ;
},
//保存用户数据
updateUserInfo ( state , value ) {
state . userInfo = value ;
}
},
//异步修改数据的地方
actions : {
addAction ( context ) {
setTimeout ( function () {
/*所谓异步,也还要调用同步的方法进行修改数据*/
context . commit ( "add" );
}, 5000 );
},
addActionNum ( context , amount ) {
setTimeout ( function () {
/*所谓异步,也还要调用同步的方法进行修改数据*/
context . commit ( "addNum" , amount );
}, 5000 );
}
},
//vuex中的计算属性
getters : {},
//全局状态模块
modules : {}
});
//导出创建好的实例
export default store ;
vuex数据持久化 持久化vuex数据,方便在页面重新加载时,恢复数据。
通过自己手动存储需要持久化的数据 通过插件进行自动持久化 自动持久化,需要安装vuex插件
1
npm install vuex-persistedstate
添加plugins,如下图
展开
使用生命周期函数验证登录 1
2
3
4
5
6
7
8
9
10
export default {
//生命周期函数
mounted () {
//用户没有登录
if ( ! this . $store . state . userInfo . adminname ) {
this . $router . push ( "/login" );
return ;
}
}
}
3.7.2 pinia Vue3项目中推荐使用Pinia ,安装
在main.js注册pinia
1
2
3
4
5
6
7
8
9
10
// src/main.js
import { createApp } from 'vue' ;
import { createPinia } from 'pinia' ;
import App from './App.vue' ;
const app = createApp ( App );
const pinia = createPinia ();
app . use ( pinia );
app . mount ( '#app' );
创建Pinia Store
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// src/stores/codeStore.js
import { defineStore } from 'pinia'
export const useCodeStore = defineStore ( 'code' , {
state : () => ({
detectedLanguage : '未识别' ,
rawCode : '' , // 原始代码(输入区)
emitCode : '' , // 高亮按钮传递的数据
highlightedCode : '' , // 高亮后的代码(预览区)
outside : false // 序号是否展示在外侧。word只支持内侧
}),
actions : {
// 更新输入的代码
setRawCode ( code ) {
this . rawCode = code
},
// 更新高亮代码(这里可以集成 highlight.js 进行高亮处理)
setHighlightCode ( code ) {
this . highlightedCode = code ;
}
}
})
在组件中使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
< template >
< nav class = "navbar" >
< div class = "nav-links" >
< a :href = "Utils.home" class = "link" > 主页 </ a >
< a :href = "Utils.blog" class = "link" > 博客 </ a >
< a :href = "Utils.github" target = "_blank" class = "link" > GitHub </ a >
</ div >
</ nav >
</ template >
< script setup >
import { Utils } from "./utils/utils" ;
import logo from "@/assets/logo.svg" ;
Utils . printProjectInfo ();
Utils . printAttention ();
</ script >