一、前端工程化
1.前端框架理解
二、ES6+
速通知识点:
- let、const关键字
- 结构
- 链判断
- 参数默认值
- 箭头函数
- Promise
- async关键字
- 模块化
1.let、const关键字
let关键子用于声明变量,const关键字用于声明常量【不能修改】
1.1 let关键字
在我们学习前端语法的时候,使用var定义变量,但是使用var定义变量会有越狱、重复声明、变量提升问题。
因此以后在前端声明变量的时候再也不适用var,而是使用let
-
越狱
//{}是声明的一个代码块 { var a = 1; let b = 2;//逃不出作用域 } console.log(a); // 1 问题:代码块外面也能访问 console.log(b); // 访问不到,只在代码块中生效
-
重复声明
// var 可以声明多次 var m = 1 var m = 2 // let 只能声明一次 let n = 3 let n = 4 //这里就会报错 console.log(m) // 2 console.log(n) // Identifier 'n' has already been declared
-
变量提升
// var 会变量提升 // let 不存在变量提升 console.log(x); // 不会报错,但是会打印undefined var x = 10; console.log(y); //会报错: y is not defined let y = 20;
1.2 const关键字
声明不可变的量,和java中的final一样,只是地址不能修改,如果是一个对象,那么对象的属性值可以修改。
// 1. 声明之后不允许改变
// 2. 一但声明必须初始化,否则会报错
const a = 1;
a = 3; //会报错: Assignment to constant variable.
2.解构
2.1 数组结构
将数组中的值拿出来赋值到对应变量/常量,访问的时候就不用下标了
数组结构使用[ ]
let arr = [1, 2, 3];
//以前我们想获取其中的值,只能通过角标。
console.log(arr[1]);
//ES6 可以这样:[x,y,z]将与 arr 中的每个位置对应来取值
const [x, y, z] = arr;//使用let也一样
// 然后打印
console.log(x);//获取x的值1
2.2 对象结构
将对象中的属性值拿出来赋值到对应变量/常量,访问的时候就不用对象名.属性名了
对象结构使用{ }
//定义了一个对象
const person = {
name: "jack",
age: 21,
language: ['java', 'js', 'css']
}
// 解构表达式获取值,将 person 里面每一个属性和左边对应赋值
const {name, age, language} = person;
const {name, age} = person;//将对象里面对应的值拿出来
// 等价于下面
// const name = person.name;
// const age = person.age;
// const language = person.language;
// 可以分别打印
console.log(name);
console.log(age);
console.log(language);
//扩展:如果想要将 name 的值赋值给其他变量,可以如下,nn 是新的变量名
const {name: nn, age, language} = person;
console.log(nn);
console.log(age);
console.log(language);
3.链判断
如果读取对象内部的某个属性,往往需要判断属性的上层对象是否存在。
比如,读取message.body.user.firstName属性,安全的写法是写成下面这样。
let message = null;
// 错误的写法
const firstName = message.body.user.firstName || 'default';
// 正确的写法【如果前面的属性都不为空才能拿到对应的属性,否则就是默认的】
const firstName = (message
&& message.body
&& message.body.user
&& message.body.user.firstName) || 'default';
console.log(firstName)
//链判断代码
//意思就是:message有吗,如果有才.body,如果没有直接终止判断
const firstName = message?.body?.user?.firstName || 'default';
4.参数默认值
在 ES6 以前,我们无法给一个函数参数设置默认值,只能采用变通写法:
function add(a, b) {
b = b || 1;//判断b是否为空,为空就给默认值 1
return a + b;
}
//只传入一个参数,会用默认值,但是上面这个方法很麻烦
console.log(add(10));
如果是一个大的方法或者参数多的方法上面这么写就很麻烦,所以可以用下面的写法
//现在可以这么写:直接给参数写上默认值,没传就会自动使用默认值
function add2(a, b = 1) {
return a + b;
}
// 传一个参数
console.log(add2(10));
5.箭头函数
用于简化方法的声明,相当于java中的lambda表达式
//传统的定义方法
let sum=function (a,b){
return a+b;
}
//或者
let function sum (a,b){
return a+b;
}
ES6语法可以这样写
//一个函数的方法
var print = obj => {
console.log(obj);
}
//如果方法体只有一行方法,还可以如下这么写
var print = obj => console.log(obj);
// 测试调用
print(100);
//两个参数的写法
var print = (a, b) => {
return a+b;
}
//可以简写为
var sum2 = (a, b) => a + b;//当只有一行语句,并且需要返回结果时,可以省略{},结果会自动返回。
//测试调用
console.log(sum2(10, 10));//20
// 代码不止一行,可以用`{}`括起来
var sum3 = (a, b) => {
c = a + b;
return c;
};
//测试调用
console.log(sum3(10, 20));//30
6.Promise
Promise是异步对象。可以允许我们一个任务还没完成时就执行另一个任务。
Promise对象的结果需要调用then方法获取,调用catch方法获取错误信息
//传统的同步方法
console.log(111);
console.log(222);//这个方法的执行必须要等到上面111执行完成之后才执行
//问题:如果我中间调用了一个函数需要从网上获取参数,但是获取的这个参数暂时还没有用,这就会影响我的程序执行速度了
6.1 fetch
fetch 是浏览器支持从远程获取数据的一个函数,这个函数返回的就是 Promise 对象
//通过fetch方法访得到了一个Promise对象
const fetchPromise = fetch(
"https://mdn.github.io/learning-area/javascript/apis/fetching-data/can-store/products.json",
);
//这个Promise对象调用then可以获取 Response 对象
//then方法里面需要传一个箭头函数
fetchPromise.then((response) => {
//response.status: 读取响应状态码
//response.json():读取响应体json数据;(这也是个异步对象)
const jsonPromise = response.json();
jsonPromise.then((json) => {
console.log(json[0].name);
});
});
6.2 Promise状态
- 待定(pending):初始状态,既没有被兑现,也没有被拒绝。这是调用 fetch() 返回 Promise 时的状态,此时请求还在进行中。
- 已兑现(fulfilled):意味着操作成功完成。当 Promise 完成时,它的 then() 处理函数被调用。
- 已拒绝(rejected):意味着操作失败。当一个 Promise 失败时,它的 catch() 处理函数被调用。
6.3 自定义Promise
基本语法如下
const promise = new Promise((resolve, reject) => {
// 执行异步操作
if (/* 异步操作成功 */) {
resolve(value);// 调用 resolve,代表 Promise 将返回成功的结果
} else {
reject(error);// 调用 reject,代表 Promise 会返回失败结果
}
});
使用案例
let get = function (url, data) {
return new Promise((resolve, reject) => {
$.ajax({
url: url,
type: "GET",
data: data,
success(result) {
resolve(result);
},
error(error) {
reject(error);
}
});
})
}
7.Async关键字
Aysnc关键字的作用是声明当前方法是异步的,相较于定义Promise更简单。
返回的结果是一个Promise对象
//基本语法
async function myFunction() {
return 12222;
}
//既然返回Promise对象,那么就是用then获取结果
myFunction.then(xxx=>console.log(xxxx));
如果我的异步方法中执行了一个fetch操作,我的后续操作需要fetch结果中的内容,那怎么办
可以使用await关键字,让后面的代码等待当前异步方法执行完成之后,才执行
说明:await关键字只能在async修饰的方法里面使用
async function fetchProducts() {
console.log("111222")
//让后面的方法等待当前的fetch执行完成
const response = await fetch(
"https://mdn.github.io/learning-area/javascript/apis/fetching.json",
);
//让后面的方法等待当前的方法执行完成
const json = await response.json();
console.log("333333");
return json;
}
//错误写法
let network=await fetchProducts();//await只能在async修饰的方法里面使用
//正确写法:获取结果,只能用then函数获取
fetchProducts().then();
8.模块化
如果所有的js代码都写到一个文件里面会很乱,不好查阅。
模块化解决了这个问题,模块化允许用户将代码写到多个js文件中
8.1 模块化的步骤
- 编写自己的js文件
- 将js文件允许调用的方法暴漏出来
- 需要使用js的地方使用import导入js文件的功能【只能导入暴漏的方法】
8.2 基本案例
-
创建html文件,导入main.js文件,说明是模块化的
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <!--type里面module属性用来说明是模块化的js文件--> <script src="main.js" type="module"/> </head> <body> <h1>模块化测试</h1> </body> </html>
-
编写自定义的js,并暴漏
//定义了一个对象 const user = { username: "张三", age: 18 } //定义了一个方法 const isAdult = (age)=>{ if (age > 18){ console.log("成年人") }else { console.log("未成年") } } //暴漏哪些对象和方法【只有暴漏了,别人才能调用】 export {user,isAdult}
-
在其他js文件中导入方法,并调用
//导入自定义的js文件,设置导入的内容 import {user,isAdult} from './libs/user.js' //调用方法 alert("当前用户:"+user.username) isAdult(user.age);
三、npm
1.npm、nvm、node.js的关系
- nvm:nvm是node.js的版本管理工具,通过nvm可以快速切换node.js的版本,包括下载、切换等功能
- node.js:node.js是js的运行环境
- npm:是node.js的一个命令可以,将项目需要的依赖下载到本地,也可以将自己写的包上传到服务器
2.nvm的下载
-
安装包下载地址:https://github.com/coreybutler/nvm-windows/releases
-
如果电脑上之前已经单独安装了node,先卸载,然后解压nvm-setup.zip安装包,进入解压的文件夹,双击exe后缀文件进行安装
-
安装完毕后输入 nvm -v 查看版本
-
安装完毕后,找到安装的路径,打开setting.txt
-
在后面添加这两行代码
node_mirror: https://npm.taobao.org/mirrors/node/ npm_mirror: https://npm.taobao.org/mirrors/npm/
-
基本命令
nvm off // 禁用node.js版本管理(不卸载任何东西) nvm on // 启用node.js版本管理 nvm install <version> // 安装node.js的命名 version是版本号 例如:nvm install 8.12.0 nvm uninstall <version> // 卸载node.js是的命令,卸载指定版本的nodejs,当安装失败时卸载使用 nvm ls // 显示所有安装的node.js版本 nvm list available // 显示可以安装的所有node.js的版本 nvm use <version> // 切换到使用指定的nodejs版本 nvm v // 显示nvm版本 nvm install stable // 安装最新稳定版
3.npm环境设置
-
使用nvm下载好node.js,可以使用下面的命令查看版本号
node -v
-
配置npm
npm config set registry https://registry.npmmirror.com
-
查看是否设置成功
npm config get registry
-
可以设置依赖下载路径【切换到管理员】
npm config set prefix "C:\XXXXX\XXXX"
-
查看是否设置成功
npm config get prefix
4.常用命令
-
初始化项目,会生成一个package.json,就相当于的pom.xml
npm init
-
安装依赖
//安装package.json中的所有依赖 npm install //安装指定依赖到项目【会自动添加到package.json中】 npm install axios
-
更新依赖版本
npm update 依赖名
-
卸载依赖
npm uninstall 依赖名
-
运行项目
npm run xxx
5. 运行项目
项目的package.json文件中有一个scripts属性,里面有很多属性。
能够run的命令就是这些属性,例如下图可以
npm run test
和npm run haha
,属性的值就是脚本
例如:
-
创建一个js文件写入如下内容
console.log("1234");
-
然后可以直接用
node xxx.js
运行这个js文件 -
现在我们想使用npm run运行这个文件就可以将命令写到package.json文件中的scripts里面
scripts里面的属性名就是运行的名,属性值就是运行的脚本
"scripts":{ "yfj":"node xxx.js" }
-
现在可以使用
npm run yfj
运行js文件
四、Vite
Vite是一个前端脚手架,类似于我们使用Spring Initializr快速创建一个SpringBoot项目,可以用来初始化项目
官网:https://cn.vitejs.dev
-
创建一个项目,创建一个包
-
进入cmd,输入命令创建项目
#Vite 需要 Node.js 版本 18+,20+。 npm create vite
-
输入项目名
-
选择技术栈
-
选择脚本语言
-
项目的架构
-
创建成功之后下载依赖
npm install
-
进入package.json查看运行命令
npm run dev
-
项目打包
npm run build
-
打包后的文件会在dist文件中,将dist文件夹下的文件部署到nginx下的web中就可以运行
五、Vue3
1.vue文件的构成
-
template:用来写页面
-
script:用来写js脚本
-
style:用来写css文件
2.vue文件显示到主界面
-
在components中编写自己的vue页面
-
在App.vue文件的template标签中直接写文件名,script标签中会自动引用过来
也可以先在scripte标签中导入页面,然后在template标签中写<导入的名/>
3.Vue3语法
3.1 插值表达式
作用:展示数据
使用方法:使用两个大括号,然后大括号里使用变量名
语法:{{name}}、{{car.brand}}
<script setup>
//基本数据
let name = "张三"
let age = 18
//对象数据
let car = {
brand: "奔驰",
price: 777
}
</script>
<template>
<p> name: {{name}} </p>
<p> age: {{age}} </p>
<div>
<p>品牌:{{car.brand}}</p>
<p>价格:{{car.price}}</p>
</div>
</template>
3.2 事件绑定
3.2.1 v-on
作用:给某个区域绑定方法
语法:v-on:click=“方法名”
简化语法:@click=“方法名”
<script>
function buy(){
alert("购买成功")
}
</script>
<template>
<!--详细写法-->
<button v-on:click="buy">购买</button>
<!--简化方法-->
<button @click="buy">购买</button>
</template>
3.2.2 v-if
作用:根据条件渲染,不符合条件不渲染
语法:v-if=“条件”
<script>
let buy=false;
</script>
<template>
<p v-if="buy">购买成功</p>
<p v-else>购买失败</p>
</template>
3.2.3 v-for
作用:循环遍历
语法:v-for=“随便起一个名 in 集合名”
例如:v-for=“s in fruits”
<script>
let fruits=["香蕉","橘子","苹果","猕猴桃"]
</script>
<template>
<!--将集合中的数据输入到f中,然后在输出-->
<li v-for="f in fruits">{{f}}</li>
<!--可以加索引-->
<li v-for="(f,i) in fruits">{{f}}{{i}}</li>
</template>
3.2.4 v-bind
单向数据绑定,将变量的值给属性
语法:v-bind:href=“变量”
<script>
let url="www.bilibili.com"
</script>
<template>
<!--详细写法-->
<a v-bing:href="url">gogogo</a>
<!--简化写法-->
<a :href="url">gogogo</a>
</template>
3.2.5 v-mode
双向数据绑定,数据会动态变化
语法:v-mode=“xxx”
<script>
let url="www.baidu.com"
</script>
<template>
<!--a标签的跳转地址会根据input的变化-->
<a v-bind:href="url">网上书城</a>
<input type="text" v-mode="url">
</template>
3.3 响应式ref
所有数据需要动态更新显示,都需要编程响应式数据。响应式数据的修改需要使用变量名.value。ref可以修饰变量,也可以修饰对象
语法:let 变量名=ref(值);
修改值:变量名.value=xxx;
获取值:变量名
说明:在js中修改值使用变量名.value=xxx,在template中修改的时候直接变量名=xxx
<script>
<!--响应式数据绑定变量-->
let success=ref(false);
<!--响应式数据绑定对象-->
let car=ref({
brand:"奔驰",
price:666
})
function buy(){
alert("购买成功");
<!--修改响应式数据的值使用:变量名.value-->
success.value=true;
<!--修改响应式数据的值使用:变量名.value-->
car.value.price+=100;
}
</script>
<template>
<button @click="buy">购买</button>
<!--取响应式的值还是直接使用变量名-->
<p>{{success}}</p>
</template>
3.4 响应式reactive
作用和ref一样,只不过他只能修饰对象,同时修饰之后修改对象直接用常规的方法就行
语法:let 对象名=reactive({属性:值})
修改数据:对象名.属性=值
<script>
let car=ref({
brand:"奔驰",
price:666
})
function buy(){
alert("购买成功");
<!--reactive响应式数据的值可以直接修改-->
car.price+=100;
}
</script>
<template>
<!--取响应式的值还是直接使用变量名-->
<p>{{car.price}}</p>
</template>
3.5 计算属性
根据已有数据计算出新数据
<script setup>
import {computed, reactive, toRef, toRefs} from "vue";
//省略基础代码
const totalPrice = computed(()=>{
return price.value * num.value - coupon.value*100
})
</script>
<template>
<div class="car">
<h2>优惠券:{{ car.coupon }} 张</h2>
<h2>数量:{{ car.num }}</h2>
<h2>单价:{{ car.price }}</h2>
<h1>总价:{{totalPrice}}</h1>
<button @click="getCoupon">获取优惠</button>
<button @click="addNum">加量</button>
<button @click="changePrice">加价</button>
</div>
</template>
3.6 监听
可以监听对象的变化
//wath函数需要传入一个对象和一个回调方法,当对象发生变化之后会调用回调方法
//这里传入的对象是num
//回调方法里可以写三个参数:
//value:最新的值
//oldValue:之前的值
//第三个参数不用不用管,写上就行
watch(num, (value, oldValue, onCleanup) => {
console.log("newValue:" + value + ";oldValue:" + oldValue)
})
4.Vue生命周期
Vue生命周期有8个阶段,每触发一个生命周期事件,就会自动执行一个生命周期的方法,主要掌握mounted生命周期,当Vue挂在完成之后,可以发送请求到客户端,获取数据
常用的钩子函数
- onMounted(挂载完毕)
- onUpdated(更新完毕)
- onBeforeUnmount(卸载之前)
<script setup>
import {onBeforeMount, onBeforeUpdate, onMounted, onUpdated, ref} from "vue";
const count = ref(0)
const btn01 = ref()
// 生命周期钩子
onBeforeMount(()=>{
console.log('挂载之前',count.value,document.getElementById("btn01"))
})
onMounted(()=>{
console.log('挂载完毕',count.value,document.getElementById("btn01"))
})
onBeforeUpdate(()=>{
console.log('更新之前',count.value,btn01.value.innerHTML)
})
onUpdated(()=>{
console.log('更新完毕',count.value,btn01.value.innerHTML)
})
</script>
<template>
<button ref="btn01" @click="count++"> {{count}} </button>
</template>
<style scoped>
</style>
5.Vue-router
如果有多个界面,我们怎么点击某个链接之后,就跳转到对应的界面?
5.1 基本使用
-
在src目录下,编写多个vue页面
-
安装vue-router依赖
npm install vue-router@4
-
在src下面创建一个route文件夹,并创建一个js文件
-
在创建的js文件中定义路由表【是一个数组】
import User from "../views/User.vue"; import Home from "../views/Home.vue"; //路由表 const routes = [ //当请求路径为:/,就会跳转到Home页面 【上面import导入页面决定的】 { path: '/', component:Home}, //当请求路径为:/person,就会跳转到User页面 { path: '/person', component:User }, ]
-
在创建的js文件中创建路由器
//导入依赖,这样可以直接调用下面的方法 import { createMemoryHistory, createRouter } from 'vue-router' //路由器 const router = createRouter({ history: createMemoryHistory(), routes,//路由表:这个是routes:routes的缩写【因为上面定义的路由表名和这里的属性名一样】 })
-
在js文件中将router路由器导出
export default router;//路由器的名字
-
在main.js中添加路由器并使用
//格式:import 导出的路由器名字 from 'js文件地址' import router from './router/index.js' const app = createApp(App)如果没有app对象,那么createApp的时候就将对象名改为app app.use(router)//这里就是使用了 app.mount('#app')//挂载到APP下
-
在App.vue页面中的template标签中添加路由
<template> <!--to是路由表中定义的路径--> <router-link to="/">首页</router-link> <router-link to="/person">人事</router-link> </template>
-
然后在第8步的基础上,设置哪里显示该页面
<template> <!--to是路由表中定义的路径--> <router-link to="/">首页</router-link> <router-link to="/person">人事</router-link> <!--页面需要渲染到哪里就在哪加router-view标签--> <router-view></router-view> </template>
-
然后启动项目测试即可
5.2 路径参数
页面根据请求地址中参数的变化,动态显示数据,从而达到使用同一个页面,显示不同的数据
例如:请求地址是xxx/1,就显示用户1的信息,xxx/2,就显示用户2的信息。我们只需要再路由表中定义一个路由,就可以。
-
路由表的路径设置动态路径参数
const routes = [ //:参数就说明哪个参数是动态的 //匹配 /user/1 { path: '/user/:id' }, // 匹配 /p/book { path: '/p/:name' }, ]
-
在router-link中传入具体的值
<router-link to="/user/1">用户1</router-link> <router-link to="/user/2">用户2</router-link> <router-link to="/p/book">图书</router-link> <router-link to="/p/pen">笔</router-link>
-
可以在具体页面中获取路径参数
<!--例如我们已经跳转到了/user/1页面,想要获取路径参数值--> <!--$router:就是当前页面的路由信息 params:就是路由的参数信息 id:就是具体的哪个参数【这里获取的是id参数】--> 欢迎你:{{$router.params.id}}
5.3 嵌套路由
作用:一个页面里面,还有两个页面。也就是我们跳转到一个页面之后,页面里面还有两个页面供我们点击
例如:点击我的之后会跳转到我的页面,我的页面里面有两个链接个人信息、我的邮箱
-
路由文件编写路由信息
const routes = [ { path: '/user/:id', component: User, //children指定指定子路由的信息 children: [ { // 当 /user/:id/profile 匹配成功 path: 'profile', //请求路径,不要写/,一旦写/就是从项目根路径开始了 component: UserProfile,//渲染的组件 }, { // 当 /user/:id/posts 匹配成功 path: 'posts', component: UserPosts, }, ], }, ]
-
页面中添加链接
<router-link to="/user/2/profile">个人信息</router-link> <router-link to="/user/2/posts">个人邮箱</router-link>
5.4 编程式路由
作用:可以随时随地获取路由地址,进行跳转
例如:我有一个按钮【不是链接了】,要求点击之后跳转到对应的页面
-
给按钮绑定一个方法
<button @click="login">登录</button>
-
在方法中获取路由器,通过路由器跳转到指定页面
<!--导入方法【vue提供的】--> import {useRouter} from "vue-router" <!--这个方法可以拿到路由器--> const let router =useRouter(); function login(){ alert("登陆成功"); <!--调用路由器的push方法可以跳转--> <!--参数就是路由地址--> router.push("/user/2/profile"); }
5.5 导航守卫
可以在路由器跳转指定页面之前,进行拦截。这个时候加上一定的业务逻辑判断,就可以控制是否继续跳转,这里以全局前置守卫为例
全局前置守卫:在每次跳转之前进行拦截,而且全局使用
使用方法:在router的js文件中调用router的beforeEach方法,传入to和from
//to:代表要跳转的地址【这里就是to,不写具体的地址】
//from:代表跳转之前的地址【这里就是from,不写具体的地址】
router.beforeEach((to, from) => {
console.log("守卫:to:", to)
console.log("守卫:from:", from)
//。。一系列判断。。
//如果返回 false 则取消跳转
//如果返回 true 则进行跳转
//如果返回字符串 'xxx' 则跳转到字符串指定的地址
return true;
})
六、Axios
1.基本使用
-
下载依赖
npm install axios
-
发送get请求【请求参数可以直接用?拼接到里面,也可以用params属性】
//方式一:?拼接参数 axios.get('/user?ID=12345') .then(res=>{ person=res.data; }) .catch(function (error) { // 处理错误情况 console.log(error); }) .finally(function () { // 总是会执行 });
//方式二:使用params属性 axios.get('/user', { params: { ID: 12345 } }) .then(res=>{ person=res.data; }) .catch(function (error) { console.log(error); }) .finally(function () { // 总是会执行 });
-
发送post请求
//发送多个单独的参数 axios.post('/user', { firstName: 'Fred', lastName: 'Flintstone' }) .then(res=>{ person=res.data; }) .catch(function (error) { console.log(error); });
//发送一个对象 axios.post('/user',person) .then(res=>{ person=res.data; }) .catch(function (error) { console.log(error); });
2.路径抽取
axios.create可以将公共路径抽取出来,等到下次发送的时候直接拼接上后面的路径即可
-
在页面或者js文件中抽取路径
const instance = axios.create({ //baseURL是公共路径 baseURL: 'https://some-domain.com/api/', timeout: 1000, headers: {'X-Custom-Header': 'foobar'} });
-
发送请求时使用抽取出来的对象发送
function getInfo(){ //这里的instance就是上面抽取出来的公共路径对象 instance.get("/get",{ params:{ id:1, username:'zhangsan' } }).then(resp=>{ console.log(resp.data) }) }
七、Pinia
1.介绍
Pinia是Vue的存储库,允许跨组件/页面共享数据,就如同后端的Redis,多个项目可以访问同一个数据。
使用Pinia后,就跟java的Pojo一样,想要修改属性的值,只能使用暴露出来的get、set方法。
Pinia中一个store就相当于java中的一个类
2.基本使用
-
导入依赖
npm install pinia
-
在main.js中导入函数,然后创建pinia对象,让vue使用
//导入函数 import {createPinia} from 'pinia' //创建pinia对象 const pinia =createPinia(); //vue使用 app.use(pinia)
-
创建一个包stores,所有的store都放到这里,创建一个js文件
//这就使用一个store //引入方法 import {defineStore} from 'pinia' //定义store【里面的第一个参数是唯一标识】 const useMoneyStore = defineStore('money', { //定义了一个属性salary,值是10000 state: () => ({salary: 10000}), //getters是获取的方法,也就是所有的get方法 getters: { //eur是一个get方法 eur: (state) => state.salary*0.13, //dolla是要给get方法 dollar: (state) => state.salary * 0.14 }, //actions是所有的set方法 actions: { //pay是一个set方法 pay() { this.salary -= 100; }, //win是要给set方法 win() { this.salary += 5000; } } }); //将方法导出 export default useMoneyStore;
-
在组件中使用
//从useMoneyStore获取store对象 const moneyStore=useMoneyStore(); //修改的方法 const guaguale=(arg)=>{ moneyStore.win(arg)//调用set方法修改值 } const buyAirPlan=(arg)=>{ moneyStore.pay(arg)//调用set方法修改值 } //通过调用对象的方法,获取具体的值 <div> 欧元:{{moneyStore.eur}}</br> 美元:{{moneyStore.dollar}}</br> </div> //调用对象的方法修改值 <button @click="guaguale(100)">刮刮乐</button> <button @click="buyAirPlan(100)">买飞机</button>
3.简化使用
简化使用方法中不再出现state,getters、actions,而是用ref、computed、function替代
//定义store【里面的第一个参数是唯一标识】
const useMoneyStore = defineStore('money', {
// ref()就是state属性,里面的值就是status的值
const salary = ref(1000);
//computed() 代替了原来的get方法
const dollar = computed(() => salary.value * 0.14);
const eur = computed(() => salary.value * 0.13);
//里面定义的方法就是原来的actions,就是java中的set方法
const pay = () => {
salary.value -= 100;
}
const win = () => {
salary.value += 1000;
}
//重要:只有将可用的对象返回,其他组件里面才可以使用
return {salary,dollar,eur,pay,win}
});
八、Ant Design Vue
Ant Design Vue是要给样式框架,就和ElementUI差不多
文档地址:Ant-Design-Vue
1.基本使用
-
安装依赖
npm install [email protected] --save
-
在main.js中将Ant Design Vue组件导入
import Antd from 'ant-design-vue'; import 'ant-design-vue/dist/reset.css'; app.use(Antd).mount('#app');
-
然后参照文档地址,将里边的组件写入到vue文件中即可
九、后台系统案例
案例要求:
做一个后台管理系统,进入网站之后就会展示登录页面,登录页面的布局是上中下型,上边系统名,中间输入框和登录按钮,下方是版权信息。登录系统之后会进入主界面,主界面是侧边栏布局,点击侧边按钮内容会相应的显示到中间。点击退出按纽之后系统会跳转到登录页面。
-
使用vite脚手架创建一个vue项目
npm create vite
-
安装所需依赖
#1.安装项目自带依赖 npm install #2.再安装组件库Ant-Design-Vue依赖 npm install [email protected] --save #3.再安装路由vue-router依赖 npm install vue-router@4
-
按照Ant-Design-Vue的文档,修改main.js的内容
如果后面系统布局显示不完整,就可能是这里引用了原本项目自带的js文件,因此这里的内容需要全部替换为文档中的
import { createApp } from 'vue'; import Antd from 'ant-design-vue'; import App from './App.vue'; import 'ant-design-vue/dist/reset.css'; const app = createApp(App); app.use(Antd) app.mount('#app');
-
创建一个文件夹router,然后在里面创建文件index.js,编写路由信息
const routes = [ ] //导入依赖,这样可以直接调用下面的方法 import {createRouter, createWebHistory} from 'vue-router' //路由器 const router = createRouter({ history: createWebHistory(), routes, }); //路由器的名字router export default router;
-
在main.js中使用router
import { createApp } from 'vue'; import Antd from 'ant-design-vue'; import App from './App.vue'; import 'ant-design-vue/dist/reset.css'; import router from "./router/index.js"; const app = createApp(App); app.use(Antd) app.use(router) app.mount('#app');
-
找到App.vue界面,将里面的内容全部删除,然后添加
template标签
,里面添加一个router-view
标签说明:App.vue会被首先加载,我们这样设置就说明渲染位置是整个页面。后面跳转之后会将页面渲染到整个页面
<template> <router-view></router-view> </template>
-
创建一个views文件夹用来存放vue页面
-
在views文件夹中创建login.vue文件,进入Ant-Design-Vue的文档,找到Layout布局,选择上中下布局,复制案例到login.vue中
<template> <a-layout class="layout"> <a-layout-header> <div class="logo" /> </a-layout-header> <a-layout-content style="padding: 0 50px; min-height: 400px;"> <!-- 登录表单开始 --> <div class="login-form"> <h2>Login</h2> <a-input placeholder="Username" /> <a-input placeholder="Password" type="password" style="margin-top: 16px;" /> <a-button type="primary" style="width: 100%; margin-top: 16px;" @click="login">Login</a-button> </div> <!-- 登录表单结束 --> </a-layout-content> <a-layout-footer style="text-align: center; margin-top: 40px;"> ©2024 Your Company. All rights reserved. </a-layout-footer> </a-layout> </template>
-
然后在router/index.js中配置路由信息,因为最先展示的是登录页面,所以登录页面的路径配置为
/
import Home from "../views/home.vue"; const routes = [ { path: '/', component:Login} ] //导入依赖,这样可以直接调用下面的方法 import {createRouter, createWebHistory} from 'vue-router' //路由器 const router = createRouter({ history: createWebHistory(), routes, }); //路由器的名字 export default router;
-
然后启动项目,查看是否成功展示登录页面
#项目启动命令可以在package.json文件中的scripts中查看 npm run dev
-
然后添加系统主面板,在views中创建home.vue文件,在Ant-Design-Vue的文档,找到侧边栏布局,将代码复制到vue文件中
<template> <a-layout style="min-height: 100vh"> <a-layout-sider v-model:collapsed="collapsed" collapsible> <div class="logo" /> <a-menu v-model:selectedKeys="selectedKeys" theme="dark" mode="inline"> <a-menu-item key="1"> <pie-chart-outlined /> <span>Option 1</span> </a-menu-item> <a-menu-item key="2"> <desktop-outlined /> <span>Option 2</span> </a-menu-item> <a-menu-item key="3"> <desktop-outlined /> <span>退出</span> </a-menu-item> </a-menu> </a-layout-sider> <a-layout> <a-layout-content style="margin: 0 16px"> <div :style="{ padding: '24px', background: '#fff', minHeight: '360px' }"> home页面 </div> </a-layout-content> </a-layout> </a-layout> </template>
-
然后在router/index.js中配置home页面的路由信息
import Home from "../views/home.vue"; import Login from "../views/login.vue"; const routes = [ //当请求路径为:/,就会跳转到Home页面 【上面import导入页面决定的】 { path: '/', component:Login}, { path: '/home', component:Home} ] //导入依赖,这样可以直接调用下面的方法 import {createRouter, createWebHistory} from 'vue-router' //路由器 const router = createRouter({ history: createWebHistory(), routes, }); export default router;//路由器的名字
-
然后给登录页面的登录按钮绑定方法,要求点击之后跳转到home页面
<script setup> //导入编程式路由的方法 import { useRouter } from 'vue-router'; const router = useRouter(); function login() { //调用编程式路由的push方法跳转到指定页面 router.push("/home") } </script>
-
然后启动项目测试
-
然后编写home中的组件,要求点击home页面左侧的按钮,屏幕中间会显示对应的页面信息
-
在views中创建两个vue页面,名字随便。这里命名为childone.vue和childtwo.vue
-
然后给这两个页面随便写点信息,方便后面查看是否真的进行了展示
-
然后将这两个页面的信息,添加到路由中
想让页面渲染在哪个页面下,就配置到哪个页面的子路由中
import Home from "../views/home.vue"; import Login from "../views/login.vue"; import Childone from "../views/childone.vue"; import Childtwo from "../views/childtwo.vue"; const routes = [ {path: '/', component: Login}, { path: '/home', component: Home, children: [ { //子路由直接写路径就行,系统知道该怎么访问 //这里的访问路径就是/home/childone path: 'childone', component: Childone, }, { path: 'childtwo', component: Childtwo }, ] } ] import {createRouter, createWebHistory} from 'vue-router' const router = createRouter({ history: createWebHistory(), routes, }); export default router;
-
然后修改home页面,将页面需要展示的地方添加
router-view
标签<template> <a-layout style="min-height: 100vh"> <a-layout-sider v-model:collapsed="collapsed" collapsible> <div class="logo" /> <a-menu v-model:selectedKeys="selectedKeys" theme="dark" mode="inline"> <a-menu-item key="1"> <pie-chart-outlined /> <span>Option 1</span> </a-menu-item> <a-menu-item key="2"> <desktop-outlined /> <span>Option 2</span> </a-menu-item> <a-menu-item key="3"> <desktop-outlined /> <span>退出</span> </a-menu-item> </a-menu> </a-layout-sider> <a-layout> <a-layout-content style="margin: 0 16px"> <div :style="{ padding: '24px', background: '#fff', minHeight: '360px' }"> <router-view></router-view> </div> </a-layout-content> </a-layout> </a-layout> </template>
-
然后添加方法,当点击标签之后会自动跳转
<script setup> import {onMounted, ref, watch} from 'vue'; import { useRouter } from 'vue-router'; const router = useRouter(); const collapsed = ref(false); const selectedKeys = ref(['1']); watch(selectedKeys,(newValue, oldValue)=>{ if (newValue.includes('1')){ //这里有三种写法 //第一种:绝对路径写法【个人建议】:/home/childone //第二种:相对路径写法:childone //第三种:路由文件中添加name属性,这里使用name值访问 //router.push({name:'childone'}) router.push('childone'); }else if(newValue.includes('2')){ router.push('childtwo'); }else if(newValue.includes('3')){ router.push('/'); } }) onMounted(()=>{ router.push('/home/childone') }) </script>
十、Vue路由总结
-
App.vue是系统的总页面,所有的一级路由页面都会渲染到他这里。
解释:
这也就是为什么上面的login和home页面布局不一样,但是都可以被渲染。
系统请求
/
路径,然后/
路径会将login返回渲染到这里,系统请求/home
路径,它会将home页面渲染到这里替换原来的渲染 -
二级路由页面会渲染到一级路由页面里面
这也就是为什么我们访问/home/childone页面之后,页面会渲染到指定的地方,而不是渲染到整个屏幕