Vue进阶
Vue cli
一、Vue cli 概述
- CLI 全称是 Commond Line Interface,翻译为命令行界面,俗称脚手架。
- VueCLI是一个官方发布vue.js项目脚手架。
- 用VueCLI 可快速搭建Vue开发环境以及对应webpack配置。
二、环境搭建
1、下载 node.js
- 下载地址:https://nodejs.cn/download/
2、安装 node.js
(1)傻瓜式安装
一路下一步操作(安装路径按自己的意思来),安装完成后会自动添加到环境变量中,这个时候你的cmd就会多了两个命令。
- node:进入node.js环境
- npm:安装模块用
(2)测试安装成功
3、安装Vue-cli
(1)打开cmd窗口输入命令
// 速度慢
npm install -g @vue/cli
// 使用镜像,速度快
npm install -g @vue/cli --registry=https://registry.npm.taobao.org
(2)测试Vue-cli安装成功
vue -v
或者
vue --version
Vue 项目基础操作
一、创建项目
1、进入要创建项目的目录,创建项目
vue create 项目名
2、选择模板,这时候按下键,选择最后一个自定义,回车执行
3、按上下键移动(带*的),空格选择,回车键执行
4、选择版本vue3.回车键执行
5、先输入y,回车键执行后选择In package.json,回车键执行
6、再次输入y,回车键执行,再次回车键执行
7、进入项目并启动
8、使用VSCode打开day0424
项目名
├── node_modules -- 项目的依赖
├── public -- 文件夹
├ ├── favicon.ico -- 网站顶部小图标
├ └── index.html -- 单页面开发,项目唯一页面
├── src -- 文件夹,主要代码都在里面
├ ├── assets -- img,js,css,都可以放在这里
├ ├── components -- 小组件,放在页面组件中的
├ ├── store -- 安装了vuex就会生成
├ ├── router -- 安装了vue-router就会生成,配置路由
├ ├── views -- 页面组件存放在这
├ ├── App.vue -- 根组件,靠它和唯一的页面连接的
├ └── main.js -- 整个项目的入口,引入全局配置
├── .gitignore -- git版本管理
├── babel.config.js -- babel的配置,不用管
├── jsconfig.json
├── package.json -- 项目的配置,和依赖的模块都在这
├── package-lock.json
├── README.md -- 项目的介绍
└── vue.config.js -- vue的配置信息
9、开启VSCode,启动项目(关掉之前的cmd)
- 注意:这里在VSCode 中启动项目时,要先重启一下VSCode,重新打开终端。
10、VSCode安装识别vue内容的插件
- 保存后,项目自启动(热部署)
二、组件编写及使用
1、在views文件中创建自己的Vue文件,First.vue
<template>
<div id="first">
Hello World!
</div>
</template>
<style>
#id{
width: 100px;
height: 100px;
background-color: aqua;
}
</style>
<script>
// export default 的作用相当于:Vue.createApp(),默认的出口
export default {
}
</script>
2、在router的index.js中注册路由
import { createRouter, createWebHistory } from 'vue-router'
// 引入first.vue
import first from "../views/first.vue"
// 注册路由
const routes = [
{
path: '/f',
// name: 'first', 可以不要
// component的名字与import处对应
component: first
},
]
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes
})
export default router
3、在APP.vue中书写路由导航
- nav:导航标签
- to:注册路由的路径
- :to去的view页面 -
- 注意:vue的模版中只有能一个根节点,所以在
template
中插入第二个元素就会报错
<template>
<div id="first">
Hello World!
</div>
</template>
<style>
#first{
width: 100px;
height: 100px;
background-color: aqua;
}
</style>
<script>
// export default 的作用相当于:Vue.createApp(),默认的出口
export default {
}
</script>
4、测试
5、在first.vue中书写数据解析代码
<template>
<div id="first">
<table border="1" cellpadding="0" cellspacing="0" width="500" align="center">
<tr>
<th>学号</th>
<th>姓名</th>
<th>年龄</th>
<th>邮箱</th>
<th>头像</th>
<th>操作</th>
</tr>
<tr align="center" v-for="(stu,index) in students" v-bind:key="index">
<td>{{stu.stuId}}</td>
<td>{{stu.stuName}}</td>
<td>{{stu.stuAge}}</td>
<td>{{stu.stuEmail}}</td>
<td>{{stu.stuPhoto}}</td>
<td>
<a href="javascript:void(0)" >删除</a>
<a href="javascript:void(0)" >编辑</a>
</td>
</tr>
</table>
</div>
</template>
<style>
#first{
width: 500px;
margin: auto;
}
</style>
<script>
// export default 的作用相当于:Vue.createApp(),默认的出口
export default {
data() {
return {
students:[
{stuId:1,stuName:"mary",stuAge:18,stuEmail:"mary@qq.com",stuPhoto:"mary.jpg"},
{stuId:2,stuName:"tom",stuAge:18,stuEmail:"tom@qq.com",stuPhoto:"tom.jpg"},
{stuId:3,stuName:"lucy",stuAge:18,stuEmail:"lucy@qq.com",stuPhoto:"lucy.jpg"}
]
}
},
methods: {
},
};
</script>
axios的使用
1、axios的安装
npm install axios
2、VsCode项目中加载axios
3、后端代码准备
(1)引入依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!--依赖父亲maven-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.11</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.etime</groupId>
<artifactId>day0423</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>day0423</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!--在SpringBoot在引入web,由启动器 (starter) 完成-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--引入Lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.16</version>
</dependency>
<!--数据库相关-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
<scope>runtime</scope>
</dependency>
<!--单元测试相关-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!--引入热部署-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<!-- 导入Mybatis-Plus依赖-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.1</version>
</dependency>
</dependencies>
<!--构建插件-->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
(2)实体类
package com.etime.day0423.pojo;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
@NoArgsConstructor
@AllArgsConstructor
@Data
public class Student {
@TableId("sid")
private int sid;
private String sname;
private int cid;
private int sage;
private String email;
private String sphoto;
}
(3)持久层
package com.etime.day0423.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.etime.day0423.pojo.Student;
import org.springframework.stereotype.Repository;
//
@Repository
public interface StudentMapper extends BaseMapper<Student> {
/*
BaseMapper<Student>:继承父接口,并指定类型
*/
}
(4)业务逻辑层
- 实现类中
package com.etime.day0423.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.etime.day0423.mapper.StudentMapper;
import com.etime.day0423.pojo.Student;
import com.etime.day0423.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class StudentServiceImpl implements StudentService {
@Autowired
private StudentMapper studentMapper;
@Override
public int addStudent(Student student) {
return studentMapper.insert(student);
}
@Override
public int deleteStudent(int sid) {
return studentMapper.deleteById(sid);
}
@Override
public int updateStudent(Student student) {
return studentMapper.updateById(student);
}
@Override
public List<Student> getAllStudent() {
List<Student> list = studentMapper.selectList(null);
return list;
}
@Override
public Page<Student> getStudentByPage(int currentPage,int size) {
Page<Student> page = new Page<>(currentPage,size);
return studentMapper.selectPage(page,null);
}
@Override
public Page<Student> getStudentBySname(String sname, int current, int size) {
QueryWrapper<Student> wrapper = new QueryWrapper<>();
wrapper.like("sname",sname);
Page<Student> page = new Page<>(current,size);
return studentMapper.selectPage(page,wrapper);
}
}
(5)控制层
package com.etime.day0423.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.etime.day0423.pojo.Student;;
import com.etime.day0423.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@CrossOrigin
public class StudentController {
@Autowired
private StudentService studentService;
@GetMapping("/student")
public List<Student> getAllStudent() {
List<Student> list = studentService.getAllStudent();
return list;
}
@PostMapping("/student")
public boolean addStudent(Student student){
return studentService.addStudent(student) != 0 ? true:false;
}
@DeleteMapping("/student/{sid}")
public boolean deleteStudent(@PathVariable("sid") int sid){
return studentService.deleteStudent(sid) != 0 ? true:false;
}
@PutMapping("/student")
public boolean updateStudent(Student student){
return studentService.updateStudent(student) != 0 ? true:false;
}
@GetMapping("/student/page")
public Page<Student> getStudentByPage(int currentPage,int size){
return studentService.getStudentByPage(currentPage,size);
}
@GetMapping("/student/like")
public Page<Student> getStudentByName(String sname,int currentPage,int size){
return studentService.getStudentBySname(sname,currentPage,size);
}
}
4、编写前端代码,修改first.vue中代码
<template>
<div id="first">
<table border="1" cellpadding="0" cellspacing="0" width="500" align="center">
<tr>
<th>学号</th>
<th>姓名</th>
<th>年龄</th>
<th>邮箱</th>
<th>头像</th>
<th>操作</th>
</tr>
<tr align="center" v-for="(stu,index) in students" v-bind:key="index">
<td>{{stu.sid}}</td>
<td>{{stu.sname}}</td>
<td>{{stu.sage}}</td>
<td>{{stu.email}}</td>
<td>
<img :src="'http://localhost:8888/teacher/'+stu.sphoto" style="width:50px;height50px; border-radius: 50%;">
</td>
<td>
<a href="javascript:void(0)" >删除</a>
<a href="javascript:void(0)" >编辑</a>
</td>
</tr>
</table>
<div style="width: 500px; margin: auto; text-align: right">
<a href="javascript:void(0)" @click="getStudentByPage(1)">首页</a>
<a href="javascript:void(0)" @click="getStudentByPage(prevPage)">上一页</a>
{{ current }}/{{ pages }}
<a href="javascript:void(0)" @click="getStudentByPage(nextPage)">下一页</a>
<a href="javascript:void(0)" @click="getStudentByPage(pages)">尾页</a>
</div>
</div>
</template>
<style>
#first{
width: 500px;
margin: auto;
}
</style>
<script>
import axios from 'axios'
// export default 的作用相当于:Vue.createApp(),默认的出口
export default {
data() {
return {
students:"",
current: 1,
size: 5,
pages: "",
prevPage: "",
nextPage: "",
}
},
methods: {
getStudentByPage(page) {
let content = new URLSearchParams();
content.append("currentPage", page);
content.append("size", this.size);
axios({
url: "http://localhost:8888/student/page",
method: "get",
params: content,
}).then((resp) => {
console.log(resp.data);
this.students = resp.data.records;
this.pages = resp.data.pages;
this.current = resp.data.current;
if (this.current == 1) {
this.prevPage = 1;
} else {
this.prevPage = this.current - 1;
}
if (this.current == this.pages) {
this.nextPage = this.pages;
} else {
this.nextPage = this.current + 1;
}
});
},
},
created() {
this.getStudentByPage(1);
},
};
</script>
Vue路由
一、路由概述
- 路由的本质:一种对应关系,(该处的路由含义同之前nodejs的路由)。
- 路由根据不同的url请求,,返回对应不同的资源。那么url地址和真实的资源之间就有一种对应的关系,就是路由。
二、一级路由示例代码
1、创建多个vue文件
(1)FoundMusic.vue
<template>
<h1>发现音乐</h1>
</template>
<style >
</style>
(2)MyMusic.vue
<template>
<h1>我的音乐</h1>
</template>
<style >
</style>
(3)Interest.vue
<template>
<h1>关注</h1>
</template>
<style >
</style>
2、注册路由
import { createRouter, createWebHistory } from 'vue-router'
import first from "../views/first.vue"
import MyMusic from "../views/MyMusic.vue"
import Interest from "../views/Interest.vue"
// 注册路由
const routes = [
{
path: '/f',
// name: 'first', 可以不要
// component的名字与import处对应
component: first
},
{
// 方式二
path: '/found',
component: () => import(/* webpackChunkName: "about" */ '../views/FoundMusic.vue')
},
{
path: '/my',
component: MyMusic
},
,
{
path: '/interest',
component: Interest
},
]
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes
})
export default router
3、在App.vue中编写代码
<template>
<nav>
<router-link to="/f">first</router-link> |
<router-link to="/found">发现音乐</router-link> |
<router-link to="/my">我的音乐</router-link> |
<router-link to="/interest">关注</router-link>
<router-view/>
</nav>
</template>
<style>
</style>
4、结果
二、二级路由
1、childFound.vue
<template>
<h1>排行榜</h1>
</template>
2、childFound02.vue
<template>
<h1>网络热歌</h1>
</template>
3、注册二级路由,在index.js的"/found"中
{
// 方式二
path: '/found',
component: () => import(/* webpackChunkName: "about" */ '../views/FoundMusic.vue'),
children:[
{
path: '/child01',
component:() => import('../views/childFound.vue')
},
{
path: '/child02',
component:() => import('../views/childFound02.vue')
}
]
}
4、修改FoundMusic.vue中代码
<template>
<nav>
<router-link to="/child01">排行榜</router-link>> |
<router-link to="/child02">网络热歌</router-link>>
<router-view/>
</nav>
</template>
<style >
</style>
5、测试结果
VueX
一、VUeX概述
vue官方提供的独立于组件体系之外的,管理公共数据的工具。
二、vuex分块
1、state
state: 统一定义公共数据(类似于data(){return {a:1, b:2,xxxxxx}})
2、mutations
mutations : 使用它来修改数据(类似于methods)
3、getter
类似于computed(计算属性,对现有的状态进行计算得到新的数据-------派生 )
4、action
actions: 发起异步请求
5、modules
modules: 模块拆分
三、示例代码
1、在store文件夹的index.js中设计共享函数
import { createStore } from 'vuex'
export default createStore({
state: {
sid:"",
},
getters: {
},
mutations: {
},
actions: {
},
modules: {
}
})
2、在first.vue中设计数据及点击事件
(1)点击事件
<td>
<a href="javascript:void(0)" @click="deleteStudentBySid(stu.sid)">删除</a>
<a href="javascript:void(0)" @click="updateStudentBySid(stu.sid)">编辑</a>
</td>
(2)点击事件函数
updateStudentBySid(sid){
// 切换当前路由到editStudent
this.$router.replace("/edit");
// 将sid放入vuex的state中
this.$store.state.sid = sid;
},
(3)注意事项
点击事件中我们要在当前页面 加载其他组件用于替换当前组件,所以 用到了this.$router.replace(“/edit”);并且写组件需要在在router中的index.js中注册。
3、注册新组件
(1)编写新组件editStudent.vue页面
<template>
<form>
学号<input name="sid" type="text" ><br >
姓名<input name="sname" type="text" ><br >
年龄<input name="sage" type="text" ><br >
性别 <input name="sgender" type="radio" value="男">男
<input name="sgender" type="radio" value="女">女<br >
邮箱<input name="semail" type="text" ><br >
<input type="button" value="保存" >
</form>
</template>
<style >
</style>
<script>
export default {
data() {
return {
}
},
methods: {
},
created() {
// 获取vuex的state的sid的值
let sid = this.$store.state.sid;
console.log("eidtStudent中获取到的"+sid);
},
}
</script>
(2)注册editStudent.vue
{
path: '/edit',
component: editStudent
}
(3)测试
解决根目录问题
1、警告提示
2、注册路由修改,在index.js中
{
path: '/',
// name: 'first', 可以不要
// component的名字与import处对应
component: first
},
{
path: '/f',
// name: 'first', 可以不要
// component的名字与import处对应
component: first
},
3、测试
当你点击其他组件,回到上面我们修改的注册路由时,就会看到只有服务器地址,没有注册的path。
```(2)注册editStudent.vue
{
path: '/edit',
component: editStudent
}