[toc]
一、前端工程化
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项目,可以用来初始化项目
- 创建一个项目,创建一个包
- 进入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 ant-design-vue@4.x --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 ant-design-vue@4.x --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页面之后,页面会渲染到指定的地方,而不是渲染到整个屏幕