目录
法二:内网穿透:花生壳/卓云.....(但是这种自己的电脑必须一直开着)
法三:局域网:连着同一个wife,用ipconfig查自己的ip
一. vue相关软件安装
我这里也提供了免费下载资源。
1.安装HBuilderX
是为前端开发者服务的通用 IDE,或者称为编辑器。与 vscode、sublime、webstorm 类似。
下载官网:https://www.dcloud.io/hbuilderx.html
直接解压打开就行。
2.安装nodejs
Node.js 是一个开源、跨平台的 JavaScript 运行时环境。前端的编译工具,类似于后端的JDK
下载官网:https://nodejs.org/en
解压后安装。
cmd中查看自己的node安装好了没:
用node -v 或者 npm -v
二.vue入门
1.新建项目
选择vue3项目
2.运行到终端
3.设置代理
在cmd中输入
npm config set registry=https://registry.npm.taobao.org
4.安装插件
在cmd中输入
npm install vite
此外还有:(暂时不用执行)
npm run dev
npm run build
5.vue基本语法
三.Vue网络请求+elementplus
1.网络请求
(1)安装网络依赖包
npm install axios --save
网络请求框架加载完成
(2)设置引入全局(配置main.js)
import { createApp } from 'vue'
import App from './App.vue'
import axios from 'axios'
const app = createApp(App)
app.config.globalProperties.$axios= axios
app.mount('#app')
记得按Ctrl+s保存,这样,这个项目中的每一个vue文件都可以配置网络访问了
(3)后端提供一个接口
我这里就是前面项目中的:http://localhost:8080/getpersonlist1
(4)生命周期方法
mounted(){
//生命周期方法 网络请求的方法适合放在这个里面
console.log('mounted')
var that=this
this.$axios.post("http://localhost:8080/getpersonlist1")
.then(function(res){
//res 请求成功的数据
console.log(res.data)
if(res.data.code==0){
that.personlist=res.data.data
}
}).catch(function(err){
//err 请求失败
})
},
(5)封装类Result
package com.hu.springboot1.utils;
import java.util.HashMap;
import java.util.Map;
/**
* 返回数据封装类
*/
public class Result extends HashMap<String, Object> {
private static final long serialVersionUID = 1L;
public Result() {
put("code", 0);
put("msg", "success");
}
public static Result error() {
return error(500, "未知异常,请联系管理员");
}
public static Result error(String msg) {
return error(500, msg);
}
public static Result error(int code, String msg) {
Result r = new Result();
r.put("code", code);
r.put("msg", msg);
return r;
}
public static Result ok(String msg) {
Result r = new Result();
r.put("msg", msg);
return r;
}
public static Result ok(Map<String, Object> map) {
Result r = new Result();
r.putAll(map);
return r;
}
public static Result ok() {
return new Result();
}
public Result put(String key, Object value) {
super.put(key, value);
return this;
}
}
2.UI框架-Element-Plus
vue2- Element-ui
vue3- Element-Plus
(1)安装(同上在cmd的当前目录下)
npm install element-plus --save
(2)设置引入全局(配置main.js)
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
app.use(ElementPlus)
(3)使用
源码直接去官网复制,<el-...>的形式一般是 Element-Plus的
3.入门案例:纯vue(没有后端)
app.vue
<!-- 此页面是页面入口 -->
<!-- js -->
<script >
export default{
// 放变量
data(){
return{
msg:'hello lbxx',
divstyle:'red',
username:'',
password:'',
isshow:true,
personlist:[
{
id:1,
age:20,
name:"test0"
},
{
id:2,
age:21,
name:"test1"
},
{
id:3,
age:22,
name:"test2"
}
]
}
},
mounted(){
//生命周期方法 网络请求的方法适合放在这个里面
console.log('mounted')
var that=this
this.$axios.post("http://localhost:8080/getpersonlist1")
.then(function(res){
//res 请求成功的数据
console.log(res.data)
if(res.data.code==0){
that.personlist=res.data.data
}
}).catch(function(err){
//err 请求失败
})
},
// 放方法
methods:{
myclick(){
/* var that=this
this.$axios.post("http://localhost:8080/getpersonlist1")
.then(function(res){
//res 请求成功的数据
console.log(res.data)
that.personlist=res.data
}).catch(function(err){
//err 请求失败
}) */
// alert("click")
},
// 字符串用""或者''都可以
login(){
var that=this
this.$axios.post("http://localhost:8080/login1",{
username:this.username,
password:this.password
}).then(function(res){
//res 请求成功的数据
console.log(res.data)
if(res.data.code==0){
alert("success!")
}else{
alert('fail!!')
}
}).catch(function(err){
//err 请求失败
alert('fail!!')
})
}
}
}
</script>
<!-- html -->
<template>
<h1>Vue基本语法学习</h1>
<!-- 差值语法 绑定变量 -->
<div>{{msg}}</div>
<div>{{msg.toUpperCase()}}</div>
<!-- v-on 绑定点击事件 -->
<el-button v-on:click="myclick">网络请求</el-button>
<!-- v-bind -->
<!-- <div v-bind:class="red"></div> -->
<div v-bind:class="divstyle"></div>
<!-- v-model -->
<el-input v-model="username"/><br />
<el-input v-model="password"/><br />
<el-button v-on:click="login">登录</el-button><br />
<el-button type="primary">Primary</el-button>
<!-- v-if -->
<div v-if="isshow" class="red"></div>
<!-- v-for -->
<table border="">
<tr>
<td>id</td>
<td>年龄</td>
<td>姓名</td>
</tr>
<tr v-for="person in personlist">
<td>{{person.id}}</td>
<td>{{person.age}}</td>
<td>{{person.name}}</td>
</tr>
</table>
<el-table :data="personlist" border stripe style="width: 100%">
<el-table-column prop="id" label="用户id" width="180" />
<el-table-column prop="age" label="年龄" width="180" />
<el-table-column prop="name" label="姓名" />
</el-table>
</template>
<!-- css -->
<style>
.red{
width: 100px;
height: 100px;
background: pink;
}
.blue{
width: 100px;
height: 100px;
background: skyblue;
}
</style>
4.综合案例(连着后端idea)
(1)前端App.vue
<!-- js -->
<script >
export default{
// 放变量
data(){
return{
dialogVisible:false,
dialogUpdateVisible:false,
personlist:[
],
form:{
name:'',
age:''
},
updateform:{
id:'',
name:'',
age:''
},
searchname:'',
}
},
mounted(){
//生命周期方法 网络请求的方法适合放在这个里面
console.log('mounted')
var that=this
this.$axios.post("http://localhost:8080/getpersonlist1")
.then(function(res){
//res 请求成功的数据
console.log(res.data)
if(res.data.code==0){
that.personlist=res.data.data
}
}).catch(function(err){
//err 请求失败
})
},
// 放方法
methods:{
addperson(){
// 让增加用户的输入框显示
this.dialogVisible=true
},
getdata(){//请求数据方法
var that=this
this.$axios.post("http://localhost:8080/getpersonlist1")
.then(function(res){
//res 请求成功的数据
console.log(res.data)
if(res.data.code==0){
that.personlist=res.data.data
}
}).catch(function(err){
//err 请求失败
})
},
addpersoncommit(){
var that=this
this.$axios.post("http://localhost:8080/addpersoncommit1",this.form)
.then(function(res){
//res 请求成功的数据
console.log(res.data)
if(res.data.code==0){
//隐藏对话框
that.dialogVisible=false
//清空对话框
that.form={}
that.getdata()
}
}).catch(function(err){
//err 请求失败
})
},
// 字符串用""或者''都可以
search(){
var that=this
//如果只有一个值,把该值拼到链接中,链接可以带参数,而且可以是变量
//http://localhost:8080/searchname/test1 两级
this.$axios.post("http://localhost:8080/searchname/"+this.searchname)
.then(function(res){
//res 请求成功的数据
console.log(res.data)
if(res.data.code==0){
that.personlist=res.data.data
}
}).catch(function(err){
//err 请求失败
})
},
deletePerson(row){
console.log(row)
var that=this
//如果只有一个值,把该值拼到链接中,链接可以带参数,而且可以是变量
//http://localhost:8080/searchname/test1 两级
this.$axios.post("http://localhost:8080/deletePerson/"+row.id)
.then(function(res){
//res 请求成功的数据
console.log(res.data)
if(res.data.code==0){//删除后
that.getdata()
}
}).catch(function(err){
//err 请求失败
})
},
updatePerson(row){
console.log(row)
this.dialogUpdateVisible=true
this.updateform=row
},
updatepersoncommit(){
var that=this
this.$axios.post("http://localhost:8080/updatepersoncommit1",this.updateform)
.then(function(res){
//res 请求成功的数据
console.log(res.data)
if(res.data.code==0){
//隐藏对话框
that.dialogUpdateVisible=false
//清空对话框
that.updateform={}
//再请求一遍列表数据
that.getdata()
}
}).catch(function(err){
//err 请求失败
})
}
}
}
</script>
<!-- html -->
<template>
<!--el-row是行,el-col是行中的列,去element官网复制 -->
<el-row style="margin:10px;">
<el-col :span="5">
<el-button type="primary" @click="addperson">增加用户</el-button>
</el-col>
<el-col :span="10">
<!-- 每个输入框绑定一个变量值 -->
<el-input placeholder="请输入用户名" v-model="searchname"></el-input>
</el-col>
<el-col :span="5">
<el-button type="primary" @click="search">搜索用户</el-button>
</el-col>
</el-row>
<!-- 显示列表 -->
<el-table :data="personlist" border stripe style="width: 100%" >
<el-table-column prop="id" label="用户id" width="70" />
<el-table-column prop="age" label="年龄" width="70" />
<el-table-column prop="name" label="姓名" />
<el-table-column label="操作">
<template #default="scope">
<el-row>
<el-button type="danger" @click="deletePerson(scope.row)">删除</el-button>
<el-button type="primary" @click="updatePerson(scope.row)">更新</el-button>
</el-row>
</template>
</el-table-column>
</el-table>
<el-dialog
v-model="dialogVisible"
title="增加用户"
width="80%"
:before-close="handleClose">
<el-form :model="form" label-width="120px">
<el-form-item label="用户姓名">
<el-input v-model="form.name" />
</el-form-item>
<el-form-item label="用户年龄">
<el-input v-model="form.age" />
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="addpersoncommit">
确认
</el-button>
</span>
</template>
</el-dialog>
<el-dialog
v-model="dialogUpdateVisible"
title="更新用户"
width="80%"
:before-close="handleClose">
<el-form :model="updateform" label-width="120px">
<el-form-item label="用户id">
<el-input v-model="updateform.id" disabled/>
</el-form-item>
<el-form-item label="用户姓名">
<el-input v-model="updateform.name" />
</el-form-item>
<el-form-item label="用户年龄">
<el-input v-model="updateform.age" />
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogUpdateVisible = false">取消</el-button>
<el-button type="primary" @click="updatepersoncommit">
确认
</el-button>
</span>
</template>
</el-dialog>
</template>
<!-- css -->
<style>
.red{
width: 100px;
height: 100px;
background: pink;
}
.blue{
width: 100px;
height: 100px;
background: skyblue;
}
</style>
<!-- 此页面是页面入口 -->
(2)后端控制器
package com.wangyang.springboot.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
//springMVC
//跨域请求
@Controller
@CrossOrigin //放宽请求权限
public class PersonJSONController {
//@Autowired
// PersonMapper personMapper;
@Autowired
PersonService personService;
//Controller不建议直接调用mapper层获取数据,Controller调用service层
@RequestMapping("getpersonlist1")
@ResponseBody //返回对象转成joson
public Result getpersonlist(){
//todo 根据查询值返回不同的结果
return Result.ok().put("data",personService.findAllPerson());
}
@RequestMapping("login1")
@ResponseBody //返回对象转成joson
public Result login1(@RequestBody Map<String,String> map){
String username=map.get("username");
String password=map.get("password");
//todo 根据查询值返回不同的结果
if(username.equals("admin")&&password.equals("123456")){
return Result.ok();
}
return Result.error(505,"用户名或者密码错误");
}
@RequestMapping("addpersoncommit1")
@ResponseBody //返回对象转成joson
public Result addpersoncommit1(@RequestBody Person person){
int result= personService.addPerson(person);
//todo 根据查询值返回不同的结果
if(result>0){
return Result.ok();
}
return Result.error(505,"增加失败");
}
//http://localhost:8080/searchname/test1
@RequestMapping("searchname/{name}")//()表示链接里面是带参数的
@ResponseBody //返回对象转成joson
public Result searchname(@PathVariable("name") String name){//把链接中的值取出来给name
//todo 根据查询值返回不同的结果
return Result.ok().put("data",personService.findPersonByName(name));
}
@RequestMapping("deletePerson/{id}")//()表示链接里面是带参数的
@ResponseBody //返回对象转成joson
public Result deletePerson(@PathVariable("id") int id){//把链接中的值取出来给name
int result=personService.deletePersonById(id);
if(result>0){
return Result.ok();
}
return Result.error(505,"删除失败");
}
@RequestMapping("updatepersoncommit1")
@ResponseBody //返回对象转成joson
public Result updatepersoncommit1(@RequestBody Person person){
int result= personService.updatePerson(person);
//todo 根据查询值返回不同的结果
if(result>0){
return Result.ok();
}
return Result.error(505,"更新失败");
}
//请求数据
/*var that=this
this.$axios.post("http://localhost:8080/login1",{
username:this.username,
password:this.password
})
.then(function(res){
//res 请求成功的数据
console.log(res.data)
if(res.data.code==0){
that.personlist=res.data.data
}
}).catch(function(err){
//err 请求失败
})*/
}
运行后端idea和前端vue.app
(3)运行结果
数据库中的数据:
成功显示:
搜索功能:
增加:
更新:
四.vue组件化案例
总体结构
1.创建以上vue文件
2.在App.vue中引入并注册这些文件
3.写下页面布局
4.设置其样式
4.在right.vue中设置文件上传
(1)后端
(2)前端
4.链接跳转嵌套
(1)引入路由:vue-router(安装)
npm install vue-router --save
(2)路由配置
//去掉 #
//# 前面是域名 后面是拼的地址
//http://localhost:3000/home#/news/medianews
//import {createRouter,createWebHistory} from 'vue-router'
import {createRouter,createWebHashHistory} from 'vue-router'
import Home from '../components/Home.vue'
import News from '../components/News.vue'
import HotNews from '../components/HotNews.vue'
import MediaNews from '../components/MediaNews.vue'
//路由配置
const routes =[
{//重定向到主页
path:'/',
redirect:"/home"
},{
path:'/home',
component:Home
},{
path:'/news',
component:News,
children:[ //链接跳转嵌套
{
path:'hotnews',
component:HotNews
},{
path:'medianews',
component:MediaNews
}
]
}
]
const router = createRouter({
//history:createWebHistory(),
history:createWebHashHistory(),
routes
})
export default router
(3)更改main.js
(4)更改App.vue
5.路由嵌套
最终效果:
App.vue:
<!-- js -->
<script >
//引入这里
import Top from './components/Top.vue'
import Left from './components/Left.vue'
import Right from './components/Right.vue'
import Bottom from './components/Bottom.vue'
export default{
// 放变量
data(){
return{
}
},
components:{
//注册到这
Top,Left,Right,Bottom
},
// 放方法
methods:{
}
}
</script>
<!-- html -->
<!-- 结点在这里大小写无所谓 e.g:top和Top是一样的 -->
<template>
<top class="top"> </top>
<div style="display: flex;">
<left class="left"></left>
<!-- <right class="right"></right> -->
<router-view class="right"></router-view>
</div>
<bottom class="bottom"></bottom>
</template>
<!-- css -->
<style>
.top{
width: 100%;
height: 150px;
background-color: lavender;
margin: 0px;
}
.left{
width: 30%;
height: 400px;
background-color: aliceblue;
margin: 0px;
}
.right{
width: 70%;
height: 400px;
background-color:skyblue;
margin: 0px;
}
.bottom{
width: 100%;
height: 150px;
background-color: lightcyan;
margin: 0px;
}
</style>
<!-- 此页面是页面入口 -->
Right.vue
<template>
<div>
<h1>文件上传</h1>
<!-- 上传文件会提交到这个网址 -->
<el-upload
class="upload-demo"
drag
action="http://localhost:8080/fileuploadcommit"
multiple
:on-success='handlesuccess'
>
<el-icon class="el-icon--upload"><upload-filled /></el-icon>
<div class="el-upload__text">
拖动文件 <em>点击上传文件</em>
</div>
<template #tip>
<div class="el-upload__tip">
jpg/png files with a size less than 500kb
</div>
</template>
</el-upload>
</div>
</template>
<script>
export default{
// 放变量
data(){
return{
}
},
// 放方法
methods:{
//拿到返回的东西
handlesuccess(resp){
console.log(resp)
}
}
}
</script>
<style>
</style>
五.打包发布
1.自己电脑发布:
(1)项目打包
npm run build 项目打包
项目文件包下会出现dist文件夹
里面是将.vue - > html css js
(2)web容器
apache Nginx