Bootstrap

前端工程化

一、前端工程化

1.前端框架理解

image-20240423125058633

二、ES6+

速通知识点:

  1. let、const关键字
  2. 结构
  3. 链判断
  4. 参数默认值
  5. 箭头函数
  6. Promise
  7. async关键字
  8. 模块化

1.let、const关键字

let关键子用于声明变量,const关键字用于声明常量【不能修改】

1.1 let关键字

在我们学习前端语法的时候,使用var定义变量,但是使用var定义变量会有越狱、重复声明、变量提升问题。

因此以后在前端声明变量的时候再也不适用var,而是使用let

  1. 越狱

    //{}是声明的一个代码块
    {
        var a = 1;
        let b = 2;//逃不出作用域
    }
    console.log(a); // 1 问题:代码块外面也能访问
    console.log(b); // 访问不到,只在代码块中生效
    
  2. 重复声明

    // 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
    
  3. 变量提升

    // 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 模块化的步骤

  1. 编写自己的js文件
  2. 将js文件允许调用的方法暴漏出来
  3. 需要使用js的地方使用import导入js文件的功能【只能导入暴漏的方法】

8.2 基本案例

  1. 创建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>
    
  2. 编写自定义的js,并暴漏

    //定义了一个对象
    const  user = {
        username: "张三",
        age: 18
    }
    //定义了一个方法
    const isAdult = (age)=>{
        if (age > 18){
            console.log("成年人")
        }else {
            console.log("未成年")
        }
    }
    
    //暴漏哪些对象和方法【只有暴漏了,别人才能调用】
    export {user,isAdult}
    
  3. 在其他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的下载

  1. 安装包下载地址:https://github.com/coreybutler/nvm-windows/releases

  2. 如果电脑上之前已经单独安装了node,先卸载,然后解压nvm-setup.zip安装包,进入解压的文件夹,双击exe后缀文件进行安装

  3. 安装完毕后输入 nvm -v 查看版本

  4. 安装完毕后,找到安装的路径,打开setting.txt

  5. 在后面添加这两行代码

    node_mirror: https://npm.taobao.org/mirrors/node/
    npm_mirror: https://npm.taobao.org/mirrors/npm/
    
  6. 基本命令

    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环境设置

  1. 使用nvm下载好node.js,可以使用下面的命令查看版本号

    node -v
    
  2. 配置npm

    npm config set registry https://registry.npmmirror.com
    
  3. 查看是否设置成功

    npm config get registry
    
  4. 可以设置依赖下载路径【切换到管理员】

    npm config set prefix "C:\XXXXX\XXXX"
    
  5. 查看是否设置成功

    npm config get prefix
    

4.常用命令

  1. 初始化项目,会生成一个package.json,就相当于的pom.xml

    npm init
    
  2. 安装依赖

    //安装package.json中的所有依赖
    npm install
    //安装指定依赖到项目【会自动添加到package.json中】
    npm install axios
    
  3. 更新依赖版本

    npm update 依赖名
    
  4. 卸载依赖

    npm uninstall 依赖名
    
  5. 运行项目

    npm run xxx
    

5. 运行项目

项目的package.json文件中有一个scripts属性,里面有很多属性。

能够run的命令就是这些属性,例如下图可以npm run testnpm run haha,属性的值就是脚本

image-20240423163528202

例如:

  1. 创建一个js文件写入如下内容

    console.log("1234");
    
  2. 然后可以直接用node xxx.js运行这个js文件

  3. 现在我们想使用npm run运行这个文件就可以将命令写到package.json文件中的scripts里面

    scripts里面的属性名就是运行的名,属性值就是运行的脚本

    "scripts":{
    	"yfj":"node xxx.js"
    }
    
  4. 现在可以使用npm run yfj运行js文件

四、Vite

Vite是一个前端脚手架,类似于我们使用Spring Initializr快速创建一个SpringBoot项目,可以用来初始化项目

官网:https://cn.vitejs.dev

  1. 创建一个项目,创建一个包

    image-20240423164734759

    image-20240423164752226

  2. 进入cmd,输入命令创建项目

    #Vite 需要 Node.js 版本 18+,20+。
    npm create vite
    
  3. 输入项目名

  4. 选择技术栈

  5. 选择脚本语言

  6. 项目的架构

    image-20240423170215356

  7. 创建成功之后下载依赖

    npm install
    
  8. 进入package.json查看运行命令

    npm run dev
    
  9. 项目打包

    npm run build
    
  10. 打包后的文件会在dist文件中,将dist文件夹下的文件部署到nginx下的web中就可以运行

    image-20240423165628639

五、Vue3

1.vue文件的构成

  • template:用来写页面

  • script:用来写js脚本

  • style:用来写css文件

    image-20240423170603549

2.vue文件显示到主界面

  1. 在components中编写自己的vue页面

  2. 在App.vue文件的template标签中直接写文件名,script标签中会自动引用过来

    也可以先在scripte标签中导入页面,然后在template标签中写<导入的名/>

    image-20240423171144417

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挂在完成之后,可以发送请求到客户端,获取数据

image

image-20230720174028010

常用的钩子函数

  • 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 基本使用

  1. 在src目录下,编写多个vue页面

  2. 安装vue-router依赖

    npm install vue-router@4
    
  3. 在src下面创建一个route文件夹,并创建一个js文件

  4. 在创建的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 },
    ]
    
  5. 在创建的js文件中创建路由器

    //导入依赖,这样可以直接调用下面的方法
    import { createMemoryHistory, createRouter } from 'vue-router'
    //路由器
    const router = createRouter({
      history: createMemoryHistory(),
      routes,//路由表:这个是routes:routes的缩写【因为上面定义的路由表名和这里的属性名一样】
    })
    
  6. 在js文件中将router路由器导出

    export default router;//路由器的名字
    
  7. 在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下
    
  8. 在App.vue页面中的template标签中添加路由

    <template>
    	<!--to是路由表中定义的路径-->
        <router-link to="/">首页</router-link>
        <router-link to="/person">人事</router-link>
    </template>
    
  9. 然后在第8步的基础上,设置哪里显示该页面

    <template>
    	<!--to是路由表中定义的路径-->
        <router-link to="/">首页</router-link>
        <router-link to="/person">人事</router-link>
    	<!--页面需要渲染到哪里就在哪加router-view标签-->
    	<router-view></router-view>
    </template>
    
  10. 然后启动项目测试即可

5.2 路径参数

页面根据请求地址中参数的变化,动态显示数据,从而达到使用同一个页面,显示不同的数据

例如:请求地址是xxx/1,就显示用户1的信息,xxx/2,就显示用户2的信息。我们只需要再路由表中定义一个路由,就可以。

  1. 路由表的路径设置动态路径参数

    const routes = [
      //:参数就说明哪个参数是动态的
      //匹配 /user/1
      { path: '/user/:id' },
      // 匹配 /p/book
      { path: '/p/:name' },
    ]
    
  2. 在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>
    
  3. 可以在具体页面中获取路径参数

    <!--例如我们已经跳转到了/user/1页面,想要获取路径参数值-->
    <!--$router:就是当前页面的路由信息
    		params:就是路由的参数信息
    			id:就是具体的哪个参数【这里获取的是id参数】-->
    欢迎你:{{$router.params.id}}
    

5.3 嵌套路由

作用:一个页面里面,还有两个页面。也就是我们跳转到一个页面之后,页面里面还有两个页面供我们点击

例如:点击我的之后会跳转到我的页面,我的页面里面有两个链接个人信息、我的邮箱

  1. 路由文件编写路由信息

    const routes = [
      {
        path: '/user/:id',
        component: User,
        //children指定指定子路由的信息
        children: [
          {
            // 当 /user/:id/profile 匹配成功
            path: 'profile', //请求路径,不要写/,一旦写/就是从项目根路径开始了
            component: UserProfile,//渲染的组件
          },
          {
            // 当 /user/:id/posts 匹配成功
            path: 'posts',
            component: UserPosts,
          },
        ],
      },
    ]
    
  2. 页面中添加链接

    <router-link to="/user/2/profile">个人信息</router-link>
    <router-link to="/user/2/posts">个人邮箱</router-link>
    

5.4 编程式路由

作用:可以随时随地获取路由地址,进行跳转

例如:我有一个按钮【不是链接了】,要求点击之后跳转到对应的页面

  1. 给按钮绑定一个方法

    <button @click="login">登录</button>
    
  2. 在方法中获取路由器,通过路由器跳转到指定页面

    <!--导入方法【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.基本使用

  1. 下载依赖

    npm install axios
    
  2. 发送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 () {
        // 总是会执行
    });  
    
  3. 发送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可以将公共路径抽取出来,等到下次发送的时候直接拼接上后面的路径即可

  1. 在页面或者js文件中抽取路径

    const instance = axios.create({
        //baseURL是公共路径
      baseURL: 'https://some-domain.com/api/',
      timeout: 1000,
      headers: {'X-Custom-Header': 'foobar'}
    });
    
  2. 发送请求时使用抽取出来的对象发送

    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.基本使用

  1. 导入依赖

    npm install pinia
    
  2. 在main.js中导入函数,然后创建pinia对象,让vue使用

    //导入函数
    import {createPinia} from 'pinia'
    //创建pinia对象
    const pinia =createPinia();
    //vue使用
    app.use(pinia)
    
  3. 创建一个包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;
    
  4. 在组件中使用

    //从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.基本使用

  1. 安装依赖

    npm install [email protected] --save
    
  2. 在main.js中将Ant Design Vue组件导入

    import Antd from 'ant-design-vue';
    import 'ant-design-vue/dist/reset.css';
    app.use(Antd).mount('#app');
    
  3. 然后参照文档地址,将里边的组件写入到vue文件中即可

九、后台系统案例

案例要求:

做一个后台管理系统,进入网站之后就会展示登录页面,登录页面的布局是上中下型,上边系统名,中间输入框和登录按钮,下方是版权信息。登录系统之后会进入主界面,主界面是侧边栏布局,点击侧边按钮内容会相应的显示到中间。点击退出按纽之后系统会跳转到登录页面。

  1. 使用vite脚手架创建一个vue项目

    npm create vite
    
  2. 安装所需依赖

    #1.安装项目自带依赖
    npm install
    #2.再安装组件库Ant-Design-Vue依赖
    npm install [email protected] --save
    #3.再安装路由vue-router依赖
    npm install vue-router@4
    
  3. 按照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');
    
  4. 创建一个文件夹router,然后在里面创建文件index.js,编写路由信息

    const routes = [
    ]
    
    //导入依赖,这样可以直接调用下面的方法
    import {createRouter, createWebHistory} from 'vue-router'
    
    //路由器
    const router = createRouter({
        history: createWebHistory(),
        routes,
    });
    //路由器的名字router
    export default router;
    
  5. 在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');
    
  6. 找到App.vue界面,将里面的内容全部删除,然后添加template标签,里面添加一个router-view标签

    说明:App.vue会被首先加载,我们这样设置就说明渲染位置是整个页面。后面跳转之后会将页面渲染到整个页面

    <template>
      <router-view></router-view>
    </template>
    
  7. 创建一个views文件夹用来存放vue页面

  8. 在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;">
          &copy;2024 Your Company. All rights reserved.
        </a-layout-footer>
      </a-layout>
    </template>
    
  9. 然后在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;
    
  10. 然后启动项目,查看是否成功展示登录页面

    #项目启动命令可以在package.json文件中的scripts中查看
    npm run dev
    
  11. 然后添加系统主面板,在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>
    
  12. 然后在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;//路由器的名字
    
  13. 然后给登录页面的登录按钮绑定方法,要求点击之后跳转到home页面

    <script setup>
    //导入编程式路由的方法
    import { useRouter } from 'vue-router';
    
    const router = useRouter();
    function login() {
    	//调用编程式路由的push方法跳转到指定页面
      router.push("/home")
    }
    </script>
    
  14. 然后启动项目测试

  15. 然后编写home中的组件,要求点击home页面左侧的按钮,屏幕中间会显示对应的页面信息

  16. 在views中创建两个vue页面,名字随便。这里命名为childone.vue和childtwo.vue

  17. 然后给这两个页面随便写点信息,方便后面查看是否真的进行了展示

  18. 然后将这两个页面的信息,添加到路由中

    想让页面渲染在哪个页面下,就配置到哪个页面的子路由中

    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;
    
  19. 然后修改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>
    
  20. 然后添加方法,当点击标签之后会自动跳转

    <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路由总结

  1. App.vue是系统的总页面,所有的一级路由页面都会渲染到他这里。

    解释:

    这也就是为什么上面的login和home页面布局不一样,但是都可以被渲染。

    系统请求/路径,然后/路径会将login返回渲染到这里,系统请求/home路径,它会将home页面渲染到这里替换原来的渲染

  2. 二级路由页面会渲染到一级路由页面里面

    这也就是为什么我们访问/home/childone页面之后,页面会渲染到指定的地方,而不是渲染到整个屏幕

;