前言
做个期末项目还得我会前端,这不是为难我嘛,本来就对前端没有太多的知识积累。导致我还得现去学习Vue。本来前端这一块是想留着小学期的时候来好好学的
目前看来只能现快速过一遍了。
Vue创建
基于Vue开发项目的环境要求
使用 Vue CLI 创建前端工程
打开一个文件夹,最好是不要有中文的
在文件夹中cmd
输入 vue create 项目名称
选择Vue2,还是Vue3
回车等待创建完成就行了
vue ui (网页界面创建:心情不好不想放图片了)
- 打开一个文件夹,最好是不要有中文的
- 在文件夹中cmd
- 输入 vue ui
- 回车后会给你一个网页连接,点进去到浏览器创建就行了很直观的创建方式
- 还可以直接在上面看见自己的依赖和插件,同时也可以安装插件
启动前端项目
- vscode中打开创建项目所生成的那个文件夹
- 在vscode中按:ctrl+j 打开终端
- 终端中输入
上面那个serve取决于package.json里面的serve,那个叫什么名字
run 后面就写什么名字。
- 回车后出现链接,点击就行了
- 停止跟linux是一样的ctrl+c
修改项目端口号
需要更改项目的端口号,在文件中找到vue.config.js文件中输入
注意空格
1 2 3 4 5 6 7
| const { defineConfig } = require('@vue/cli-service') module.exports = defineConfig({ transpileDependencies: true, devServer: { port: 7070 } })
|
Vue基础
vue组件
Vue的组件文件以.vue结尾,每个组件由三部分组成:
<template>
结构:
- 只有一个根元素
- 由它生成HTML代码
<style>
样式
- 编写CSS,控制页面展示效果
- 全局样式: 影响所有组件
- 局部样式: 只作用于当前组件
<script>
逻辑
插值
使用方式:{{}}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <template> <div class="hello"> {{name}} {{age > 60 ? '老年':'青年'}} </div> </template> <script> export default { data(){ return{ name: '张三', age: 70 } } } </script>
|
属性绑定
用法:v-bind:xxx 简写 :xxx
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| <template> <div class="hello"> {{name}} {{age > 60 ? '老年':'青年'}} <input type="text" v-bind:value="name"/> <input type="text" :value="age"/> <img :src="src"/> </div> </template> <script> export default { data(){ return{ name: '张三', age: 70, src: 'https://tse1-mm.cn.bing.net/th/id/OIP-C.00HEmqYJSK44tQgKfX9dWAHaEo?rs=1&pid=ImgDetMain' } } } </script>
|
事件绑定
用法: v-on:xxx 简写 @xxx
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
| <template> <div class="hello"> {{name}} {{age > 60 ? '老年':'青年'}} <input type="text" :value="name"/> <input type="text" :value="age"/> <img :src="src">
<input type="button" value="保存" v-on:click="handleSave"/> <input type="button" value="保存" @click="handleSave1"/>
</div> </template>
<script> export default { name: 'HelloWorld', props: { msg: String }, data() { return { name: 'zhangsan', age: '70 ', src: '../assets/logo.png' } }, methods: { handleSave() { alert('你点击了保存按钮') }, handleSave1() { alert('简写后的保存按钮') } } } </script>
|
双向绑定
- 作用:表单输入项和data方法中的属性进行绑定,任意一方改变都会同步给另一方
- 用法:
v-model
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| <template> <div class="hello"> {{name}} <input type="text" v-bind:value="name"/> <input type="text" v-model="name" /> <input type="button" value="修改name" @click="handleChange" /> </div> </template> <script> export default { data(){ return { name: '张三' } }, methods:{ handleChange(){ this.name = '李四' } } } </script>
|
条件渲染
作用:根据表达式的值来动态渲染页面元素
用法:v-if、v-else、v-else-if
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| <template> <div class="hello"> <div v-if="sex==1">男</div> <div v-else-if="sex==0">女</div> <div v-else>为止</div> </div> </template> <script> export default { data(){ return { sex: 1 } }, } </script>
|
Vue基本使用方式-axios
Axios是一个基于promise的网络请求库,作用于浏览器和node.js中
安装命令
导入命令:这个放到js里面
1
| import axios from 'axios'
|

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
| <template> <div class="hello"> {{name}} {{age > 60 ? '老年':'青年'}} <input type="text" :value="name"/> <input type="text" :value="age"/> <img :src="src">
<input type="button" value="保存" v-on:click="handleSave"/> <input type="button" value="保存" @click="handleSave1"/> <input type="text" v-model="name" /> <input type="button" value="修改name" @click="handleChange"/>
<div v-if="sex==1"> 男 </div> <div v-else-if="sex==2"> 女 </div> <div v-else> 未知 </div> <input type="button" value="发送POST请求" @click="handleSend"/> <input type="button" value="发送GET请求" @click="handleSend1"/> </div> </template>
<script> import axios from 'axios' export default { name: 'HelloWorld', props: { msg: String }, data() { return { name: 'zhangsan', age: '70 ', src: '../assets/logo.png', sex: 1 } }, methods: { handleSave() { alert('你点击了保存按钮') }, handleSave1() { alert('简写后的保存按钮') }, handleChange() { this.name = '李四' }, handleSend() { //通过axios发送请求 axios.post('/api/admin/employee/login',{ username: 'admin', password: '123456' }).then(res => { console.log(res.data) }).catch(error =>{ console.log(error.response) }) }, handleSend1() { axios.get('/api/admin/shop/status',{ headers: { token: 'eyJhbGciOiJIUzI1NiJ9.eyJlbXBJZCI6MSwiZXhwIjoxNzE2NzIwNDE2fQ.HJ-OJPpgK_87F7jWnBkdGrXHGLrw564fSzx1nR4DBq' } }).then(res =>{ console.log(res.data) }) } } } </script>
|
跨域问题
所谓跨域,就是这个Vue运行在一个容器里面,并且端口号7070,后端tomcat容器又是在8080端口
相当于就是两个容器了,要想直接访问的话是不行的。
为了解决跨域问题,可以在vue.config.js文件中配置代理。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| const { defineConfig } = require('@vue/cli-service') module.exports = defineConfig({ transpileDependencies: true, devServer: { port: 7070, proxy: { '/api': { target: 'http://localhost:8080', pathRewrite: { '^/api' : '' } } } } })
|
当前端口是7070,想往8080发送请求,解决方法是配置代理。前端请求先请求到代理,然后代理转发服务请求到后端。proxy是代理的意思。/api要求前端发送的请求都以/api开始,才进行代理。会转发到指定的target的服务上。pathRewrite会将/api配置成空串。
Vue路由
创建带有路由功能的项目
这里有两种创建的方式,第一种是在Vue ui中创建
- 在终端输入
- 进入终端中,找到项目管理器,然后创建新项目
- 在预设界面选择手动配置项目
- 找到Router打开,然后点击下一步就行了
- 创建完成后package.json中会出现相应的依赖
第二种是在已有项目中,输入
回车后效果是一样的
路由逻辑分析
VueRouter
:路由器,根据路由请求在路由视图中动态渲染对应的视图组件。简单解释就是我们点击前端按钮后,会替我们发起一个请求
<router-link>
:路由链接组件,浏览器会解析成<a>
路由接受到了以后,就会在路由表中找相应的页面
<router-view>
:路由视图组件,用来展示与路由路径匹配的视图组件。 这个就是占位的地方,要让相应的页面展示到什么地方

首先在package.json里面加入“vue-router”,然后在main.js中引入router,找到router下面有一个index.js,然后在这个文件里引入VueRouter(在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
| import Vue from 'vue' import VueRouter from 'vue-router' import HomeView from '../views/HomeView.vue'
Vue.use(VueRouter) //维护路由表,某个路由路径对应的哪个视图组件 const routes = [ { path: '/', name: 'home', component: HomeView }, { path: '/about', name: 'about', // route level code-splitting // this generates a separate chunk (about.[hash].js) for this route // which is lazy-loaded when the route is visited. component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue') }, { path: '/404', component: () => import('../views/404View.vue') },{ path: '*', redirect: '/404' } ]
const router = new VueRouter({ routes })
export default router
|
上述代码展示了两种两种导入方式:
编程式路由
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <template> <div id="app"> <nav> <input type="button" value="编程式路由跳转" @click="jump"/> </nav> <router-view/> </div> </template> <script> export default{ methods:{ jump(){ //使用编程式路由跳转 this.$router.push('/about') } } } </script>
|
this.$router是获取到路由对象。push方法是根据url进行跳转。
访问的页面没有
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
| import Vue from 'vue' import VueRouter from 'vue-router' import HomeView from '../views/HomeView.vue' Vue.use(VueRouter) const routes = [ { path: '/', name: 'home', component: HomeView }, { path: '/about', name: 'about', component: () => import('../views/AboutView.vue') }, { path: '/404', component: () => import('../views/404View.vue') }, { path: '*', redirect: '/404' } ] const router = new VueRouter({ routes }) export default router
|
嵌套路由
嵌套路由:组件内要切换内容(也就是变化的时候只改变页面的一部分,另一部分不改变),需要用到嵌套路由。
一样的,要在创建的时候要勾选路由那个选项,或者直接npm安装也行
然后会出现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 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| import Vue from 'vue' import VueRouter from 'vue-router' import HomeView from '../views/HomeView.vue'
Vue.use(VueRouter)
const routes = [ { path: '/', name: 'home', component: HomeView }, { path: '/about', name: 'about', component: () => import( '../views/AboutView.vue') }, { path: '/c', component: () => import( '../views/contaner/contanerView.vue'), redirect:'/c/p1', children: [ { path: '/c/p1', component: () => import('../views/contaner/P1View.vue') }, { path: '/c/p2', component: () => import('../views/contaner/P2View.vue') }, { path: '/c/p3', component: () => import('../views/contaner/P3View.vue') } ] } , { path: '/404', component: () => import('../views/404View.vue') }, { path: '*', redirect: '/404' } ]
const router = new VueRouter({ routes })
export default router
|
1.安装并导入elementui,实现页面布局
在vscode的控制台输入如下命令:
提供子视图组件,用于效果展示
在布局容器视图中添加,实现子视图组件展示
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
| <template> <el-container> <el-header>Header</el-header> <el-container> <el-aside width="200px"> //这边这个是左边栏,将链接放到左边栏,然后换行美化格式 <router-link to="/c/p1">p1</router-link><br> <router-link to="/c/p2">p2</router-link><br> <router-link to="/c/p3">p3</router-link><br> </el-aside> <el-main> <router-view/> </el-main> </el-container> </el-container> </template>
<script> export default {
} </script>
<style> .el-header, .el-footer { background-color: #B3C0D1; color: #333; text-align: center; line-height: 60px; }
.el-aside { background-color: #D3DCE6; color: #333; text-align: center; line-height: 200px; }
.el-main { background-color: #E9EEF3; color: #333; text-align: center; line-height: 160px; }
body>.el-container { margin-bottom: 40px; }
.el-container:nth-child(5) .el-aside, .el-container:nth-child(6) .el-aside { line-height: 260px; }
.el-container:nth-child(7) .el-aside { line-height: 320px; } </style>
|
状态管理vuex
vuex是一个专为Vue.js应用程序开发的状态管理库。
vuex可以在多个组件之间共享数据,并且共享的数据是响应式的,即数据的变更能及时渲染到模板。
简单点就是例如将未登录用户展示出来,当用户登录后,又将其展示为当前用户的名字
安装命令:
1
| npm install vuex@next --save
|
state:状态对象,集中定义各个组件共享的数据。
mutations:类似于一个事件,用于修改共享数据,要求必须是同步函数。
actions:类似于mutation,可以包含异步操作,通过调用mutation来改变共享数据。
创建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
| import Vue from 'vue' import Vuex from 'vuex' import axios from 'axios'
Vue.use(Vuex)
export default new Vuex.Store({ //共享数据 state: { name: '未登录游客' }, getters: { }, //修改共享数据只能通过mutation实现,必须是同步操作 mutations: { setName(state, newName) { state.name = newName } }, //通过actions可以调用到mutations,在actions中可以进行异步操作 actions: { setNameByAxios(context) { axios({ url: 'api/admin/employee/login', method: 'post', data: { username: 'admin', password: '123456' } }).then(res => { if (res.data.code == 1) { //异步请求后,需要修改共享数据 context.commit('setName',res.data.data.name) }
}) } }, modules: { } })
|
将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
| <template> <div id="app"> 欢迎你{{ $store.state.name }}
<input type="button" value="通过mutations修改共享数据" @click="handleUpdate" /> <input type="button" value="调用actions中定义的函数" @click="handleCallAction" /> <img alt="Vue logo" src="./assets/logo.png"> <HelloWorld msg="Welcome to Your Vue.js App" /> </div> </template>
<script> import HelloWorld from './components/HelloWorld.vue'
export default { name: 'App', components: { HelloWorld }, methods: { handleUpdate() { //mutations中定义的函数不能直接调用,必须通过这种方式来调用 //setName为mutations中定义的函数名称 this.$store.commit('setName', '李四') }, handleCallAction() { //调用函数固定写法 this.$store.dispatch('setNameByAxios') } } } </script>
<style> #app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style>
|
mutations修改变量
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
| import Vue from 'vue' import Vuex from 'vuex' import axios from 'axios'
Vue.use(Vuex)
export default new Vuex.Store({ //共享数据 state: { name: '未登录游客' }, getters: { }, //修改共享数据只能通过mutation实现,必须是同步操作 mutations: { setName(state, newName) { state.name = newName } }, //通过actions可以调用到mutations,在actions中可以进行异步操作 actions: { setNameByAxios(context) { axios({ url: 'api/admin/employee/login', method: 'post', data: { username: 'admin', password: '123456' } }).then(res => { if (res.data.code == 1) { //异步请求后,需要修改共享数据 context.commit('setName',res.data.data.name) }
}) } }, modules: { } })
|
actions修改变量含有异步操作
所谓异步感觉就是有先后顺序的操作,前一步的结果可能作为下一步的参数使用。
安装axios:
context是上下文,有了上下文就可以调用到mutations里面的方法。
在异步请求后,需要修改共享数据,只能通过mutations中的方法。
然后就是配置跨域的问题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| const { defineConfig } = require('@vue/cli-service') module.exports = defineConfig({ transpileDependencies: true, devServer:{ port:7777, proxy:{ '/api':{ target:'http://localhost:8080', pathRewrite:{ '^/api':'' } } } } })
|
TypeScript介绍
基本类型定义
字符串类型 (string
): 用于定义字符串类型的变量。
typescript
let username: string = ‘zhangsan’;
- 数字类型 (number): 用于定义数字类型的变量。
let age: number = 123;
- 布尔类型 (boolean): 用于定义布尔类型的变量。
let isTrue: boolean = true;
- 函数定义
函数类型注解: 可以为函数的参数和返回值指定类型。
function printText(s: String, alignment: ‘left’ | ‘right’) {
console.log(s, alignment);
}
- 接口定义
接口 (interface): 用于定义对象的结构。
interface Cat {
name: string,
age?: number; // 加问号表示可选
}
- 实现接口: 类可以通过 implements 关键字实现一个或多个接口。
class Bird implements Animal {
// …
}
- 类定义
类的基本使用 (class):
定义属性。
构造方法 (constructor): 初始化属性。
方法定义。
class User {
name: string;
constructor(name: string) {
this.name = name;
}
study() {
console.log(this.name + “正在学习”);
}
}
- 类的继承 (extends): 子类可以继承父类的属性和方法。
class Parrot extends Bird {
say() {
console.log(this.name + ‘say hello’);
}
}
- 实例化对象
创建对象实例: 使用 new 关键字创建类的实例。
const user = new User(‘zhangsan’);
const b1 = new Bird(‘yanzi’);
const myParrot = new Parrot(‘polly’);
- 访问属性和方法
访问属性: 通过实例访问类的属性。
console.log(user.name);
console.log(b1.name);
console.log(myParrot.name);
- 调用方法: 通过实例调用类的方法。
user.study();
b1.eat();
myParrot.say();
myParrot.eat();
TypeScript 与 Vue 的结合
Vue 类型扩展: TypeScript 可以与 Vue 一起使用,通过扩展 Vue 的类型系统来增强开发体验。
import { extend } from “vue/types/umd”;