赞
踩
前端工程师“Front-End-Developer”源自于美国。大约从2005年开始正式的前端工程师角色被行业所认可,到了2010年,互联网开始全面进入移动时代,前端开发的工作越来越重要。
最初所有的开发工作都是由后端工程师完成的,随着业务越来越繁杂,工作量变大,于是我们将项目中的可视化部分和一部分交互功能的开发工作剥离出来,形成了前端开发。
开发流程如下:
2.1下载地址如下:
vscode官网地址: code.visualstudio.com
2.2插件安装:
为方便后续开发,建议安装如下插件
插件安装的有:chines ,live server, vetur, vue-helper
2.4开启完整的Emmet语法支持
Emmet一个Web开发工具,用于加快HTML和CSS代码的编写速度。使用Emmet能够通过简短的表达式生成HTML或CSS代码片段。另外,截至2022年,主流的编辑器工具如Visual Studio Code、WebStorm都已经集成了Emmet工具,无需手动安装即可使用。
如在Visual Studio Code中新建index.html,输入div,可以看到Emmet Abbreviation说明这是一个Emmet语法规则,如下图所示:
设置Emmet:
文件->首选项->设置中搜索 Emmet:启用如下选项,必要时重启vs
2.5创建项目:
vscode本身没有新建项目的选项,所以要先创建一个空的文件夹,如project_xxxx。
然后打开vscode,再在vscode里面选择 File -> Open Folder 打开文件夹,这样才可以创建项目。
2.6保存工作区:
打开文件夹后,选择“文件 -> 将工作区另存为…”,为工作区文件起一个名字,存储在刚才的文件夹下即可
2.7新建文件夹和网页和网页的打开:
在文件夹下新建文件即可;
1.1什么是 ECMAScript 6
ECMAScript 6.0(简称 ES6)是 JavaScript 语言的下一代标准, 2015 年 6 月正式发布。它的目标,是使得 JavaScript 语言可以用来编写复杂的大型应用程序,成为企业级开发语言。
1.2 ECMAScript 和 JavaScript 的关系
一个常见的问题是,ECMAScript 和 JavaScript 到底是什么关系?
要讲清楚这个问题,需要回顾历史。1996 年 11 月,JavaScript 的创造者 Netscape 公司,决定将 JavaScript 提交给标准化组织 ECMA,希望这种语言能够成为国际标准。次年,ECMA 发布 262 号标准文件(ECMA-262)的第一版,规定了浏览器脚本语言的标准,并将这种语言称为 ECMAScript,这个版本就是 1.0 版。
因此,ECMAScript 和 JavaScript 的关系是,前者是后者的规格,后者是前者的一种实现(另外的 ECMAScript 方言还有 Jscript 和 ActionScript)
ES6相对之前的版本语法更严格,新增了面向对象的很多特性以及一些高级特性。本部分只学习项目开发中涉及到ES6的最少必要知识,方便项目开发中对代码的理解
2.1 let声明变量
// 1.var 声明的变量没有局部作用域
// let 声明的变量 有局部作用域
// 2.var 可以声明多次
// let 只能声明一次
2.2 const声明常量(只读变量)
// 1、const声明之后不允许改变
const PI = "3.1415926"
PI = 3 // TypeError: Assignment to constant variable.
// 2、const一但声明必须初始化,否则会报错
const MY_AGE // Missing initializer in const declaration
2.3 解构赋值:
创建一个文件: 03-解构赋值-数组解构.js
解构赋值是对赋值运算符的扩展。
他是一种针对数组或者对象进行模式匹配,然后对其中的变量进行赋值。
在代码书写上简洁且易读,语义更加清晰明了;也方便了复杂对象中数据字段获取。
//1、数组解构 let a = 1, b = 2, c = 3 //console.log(a, b, c) // ES6 let [x, y, z] = [1, 2, 3] //console.log(x, y, z) //2、对象解构 let user = {name: 'Helen', age: 18} // 传统 let name1 = user.name let age1 = user.age console.log(name1, age1) // ES6 let { name, age } = user //注意:结构的变量必须是user中的属性 console.log(name, age)
2.4 模板字符串:
模板字符串相当于加强版的字符串,用反引号 `,除了作为普通字符串,还可以用来定义多行字符串,还可以在字符串中加入变量和表达式。
//字符串插入变量和表达式。变量名写在 ${} 中,
//${} 中可以放入 JavaScript 表达式。
let name = "lucy"
let age = 20
let info = `My name is ${name} ,I am ${age+1}`
console.log(info)
2.5声明对象简写:
{}中声明的是对象。
const name = "lucy"
const age = 20
//传统方式定义对象
const user1 = {name:name,age:age}
//console.log(user1)
//es6
const user2 = {name,age}
console.log(user2)
2.6对象拓展运算符
拓展运算符(…)用于取出参数对象所有可遍历属性然后拷贝到当前对象:
//对象复制
let person1 = {name: "Amy", age: 15}
let someone1 = { ...person1}
//console.log(someone1)
//对象合并
let age = {age: 15}
let name = {name: "Amy"}
let person2 = {...age, ...name}
console.log(person2)
2.7箭头函数:
箭头函数提供了一种更加简洁的函数书写方式。
基本语法是:
参数 => 函数体
箭头函数多用于匿名函数的定义
即函数得简化版本:
这里的函数体即 返回值;
//传统方式定义函数
var f1 = function(a) {
return a
}
//console.log(f1(3))
//es6使用箭头函数定义
//参数 => 函数体
var f2 = a => a
//=>后是输出 a
//console.log(f2(4))
使用箭头函数:
// 当箭头函数没有参数或者有多个参数,要用 () 括起来。
// 当箭头函数函数体有多行语句,用 {} 包裹起来,表示代码块,
// 当只有一行语句,并且需要返回结果时,可以省略 {} , 结果会自动返回。
// 当箭头函数没有参数或者有多个参数,要用 () 括起来。
// 当箭头函数函数体有多行语句,用 {} 包裹起来,表示代码块,
// 当只有一行语句,并且需要返回结果时,可以省略 {} , 结果会自动返回。
var f3 = function(m,n) {
return m+n
}
//es6
var f4 = (m,n) => m+n
console.log(f4(4,5))
左边是参数,右边是返回值
vue.js的下载:
官网地址:https://cn.vuejs.org/
1.1 Vue.js 是什么:
Vue.js 是一款流行的 JavaScript 前端框架,目的是简化 Web 开发.
在为 AngularJS 工作之后,Vue 的作者尤雨溪开发出了这一框架。他声称自己的思路是提取 Angular 中为自己所喜欢的部分,构建出一款相当轻量的框架。Vue 最早发布于 2014 年 2 月。作者在 Hacker News、Echo JS 与 Reddit 的 javascript 版块发布了最早的版本。一天之内,Vue 就登上了这三个网站的首页。Vue 是 Github 上最受欢迎的开源项目之一。同时,在 JavaScript 框架/函数库中,Vue 所获得的星标数已超过 React,并高于 Backbone.js、Angular 2、jQuery 等项目。
Vue.js 是一款流行的 JavaScript 前端框架,目的是简化 Web 开发。Vue 所关注的核心是 MVC 模式中的视图层,同时,它也能方便地获取数据更新,实现视图与模型的交互。
官方网站:https://cn.vuejs.org
1.2初识Vue.js
创建文件夹vue_pro
创建文件夹vuejs,将vue.min.js引入文件夹
创建 hello.html
<body>
<script src="vue.min.js"></script>
<div id="app">
<!-- 插值表达式-->
{{message}}
</div>
<script>
new Vue({
el:'#app',
data: {
message:'hello vue'
}
})
</script>
</body>
这就是声明式渲染:Vue.js 的核心是一个允许采用简洁的模板语法来声明式地将数据渲染进 DOM 的系统.
这里的核心思想就是没有繁琐的DOM操作,例如jQuery中,我们需要先找到div节点,获取到DOM对象,然后进行一系列的节点操作.
插值表达式:
使用vue.js的时候,先将vue.js放到工作区文件夹内,
然后在html中引入即可,如下:
1.3创建代码片段:
文件 => 首选项 => 用户片段 => 新建全局代码片段文件:
vue-html.code-snippets
自己网上百度一个片段即可;
2.1 基本数据渲染和指令:
渲染:
<script>
new Vue({
el: '#app',
data: {
msg:'color:green;'
}
})
</script>
指令:
<div v-bind:style="msg">单向绑定</div>
<div :style="msg">单向绑定</div>
你看到的 v-bind 特性被称为指令。指令带有前缀 v-
除了使用插值表达式{{}}进行数据渲染,也可以使用 v-bind指令,它的简写冒号(:)
2.2单向数据绑定:
格式:v-bind:style
或者简写成 :style
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="vue.min.js"></script> </head> <body> <div id="app"> {{msg}} <div :style="color1">单向绑定</div> </div> <script> new Vue({ el: '#app', data: { msg: '你好,vue', color1:'color:red' } }) </script> </body> </html>
2.3双向数据绑定:
双向同步改变,任何一个改变,另一个绑定的也会跟着改变。
什么是双向数据绑定?
即使用内置的v-model指令 完成 数据在view和model之间的双向绑定;
当数据发生变化的时候,视图也会跟着发生变化
数据模型发生了改变,会直接显示在页面上
当视图发生变化的时候,数据也会跟着同步变化
用户在页面上的修改,会自动同步到数据模型中去
格式:v-model=“”
:value=“” #是单向数据绑定的简化版本;
v-model=“” #是双向数据绑定的格式
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="vue.min.js"></script> </head> <body> <div id="div1"> {{str}} <br/> <h2>单向数据绑定</h2> <input type="text" :value="str"></input> <br> <h2>双向数据绑定</h2> <input type="text" v-model="str"></input> </div> <script> new Vue({ el:"#div1", data:{ str:"你好vue" } }) </script> </body> </html>
2.3事件:
使用 v-on 进行数件处理,v-on:click 表示处理鼠标点击事件,事件调用的方法定义在 vue 对象声明的 methods 节点中
事件绑定格式:
方式一如下:
v-on: 事件名称=“调用方法”
简写的方式二如下:
@事件名称=“调用方法”
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="vue.min.js"></script> </head> <body> <div id="id1"> <button @click="show()">事件绑定简化版</button> <button v-on:click="show()">事件绑定</button> </div> <script> new Vue({ el:"#id1", data:{ str:"你好,vue" }, //所有的方法定义在methods这里面 methods:{ //定义方法 show(){ console.log("show------"); alert("事件绑定ok"); } } }) </script> </body> </html>
2.4条件渲染:
v-if 指令用于条件性地渲染一块内容。这块内容只会在指令的表达式返回 true 值的时候被渲染。
v-else 元素必须紧跟在带 v-if 或者 v-else-if 的元素的后面,否则它将不会被识别。
官网案例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="vue.min.js"></script> </head> <body> <div id="app1"> <div v-if="msg">你好vue</div> </div> <script> new Vue({ el:"#app1", data:{ msg:true //改成false试试 } }) </script> </body> </html>
案例二:
<body>
<div id="app1">
<div v-if="a>0">大于0</div>
<div v-else>小于0</div>
</div>
<script>
new Vue({
el:"#app1",
data:{
a:-2
}
})
</script>
</body>
案例三:
<body> <div id="app1"> <input type="checkbox" v-model="ok"></input> <br> <div v-if="ok">选中了</div> <div v-else>没有选中</div> </div> <script> new Vue({ el:"#app1", data:{ ok:false } }) </script> </body> </html>
2.5列表渲染:
格式:
<div v-for="item in items ">
{{item.text}}
</div>
//1.其中items是源数据数组,而item则是被迭代的数组元素的别名;
//2.可以使用of 替代in 作为分隔符,item of items
v-for指令的第二个参数: index;
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="vue.min.js"></script> </head> <body> <div id="app"> <div v-for="(user,index) in userList"> {{index}},{{user.name}} --- {{user.age}} </div> </div> <script> new Vue({ el: '#app', data: { userList:[ {"name":"lucu","age":20}, {"name":"tom","age":12} ] } }) </script> </body> </html>
2.6vue实例生命周期
写完代码后重新刷新一下:点前进调试程序:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="vue.min.js"></script> <script src="axios.min.js"></script> </head> <body> <div id="app"> <div>{{msg}}</div> </div> <script> new Vue({ el:"#app", data : { msg:"hehe" }, created(){ debugger; console.log("页面渲染之前执行"); }, mounted(){ debugger; console.log("页面渲染之后执行"); } }) </script> </body> </html>
地址:
https://github.com/
搜索:axios
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="vue.min.js"></script> <script src="axios.min.js"></script> </head> <body> <div id="app"> <table> <tr v-for="user in userList"> <td>{{user.name}}</td> <td>{{user.age}}</td> </tr> </table> </div> <script> new Vue({ el:'#app', data:{userList:[]}, created(){//在页面渲染之前执行 //调用方法,得到饭hi的json数据 this.getList(); }, methods:{ //定义一个方法 getList(){ //使用axios方式ajax请求 axios.get("user.json") //请求的路径 .then(response => {//请求成功 console.log(response); this.userList = response.data.data.items; console.log(this.userList); }) //请求的回调函数 .catch(error =>{ console.log(error);//请求失败 }) } } }) </script> </body> </html>
https://element.eleme.cn/#/zh-CN
1、element-ui
element-ui 是饿了么前端出品的基于 Vue.js的 后台组件库,方便程序员进行页面快速布局和构建
官网: http://element-cn.eleme.io/#/zh-CN
官网地址:https://nodejs.org/zh-cn/
1.1 JavaScript引擎
浏览器的内核包括两部分核心:
DOM渲染引擎
JavaScript解析引擎
Chrome浏览器内置V8引擎,V8引擎执行Javascript的速度非常快,性能非常好。
1.2 什么是Node.js
脱离浏览器环境也可以运行JavaScript,只要有JavaScript引擎就可以。
Node.js是一个基于Chrome V8引擎的JavaScript运行环境:即Node.js内置了Chrome的V8 引擎,可以在Node.js环境中直接运行JavaScript程序。
在Node.js中写JavaScript和在Chrome浏览器中写JavaScript基本没有什么不一样。哪里不一样呢?
Node.js没有浏览器API,即document,window的等。
加了许多Node.js 专属API,例如文件系统,进程,http功能。
1.3 Node.js有什么用
如果你想开发类似JavaWeb的简单的后端程序,那么学习Node.js是一个非常好的选择。
如果你想部署一些高性能的服务,那么学习Node.js也是一个非常好的选择。
通常他会被用来作一个BFF层,即 Backend For Frontend(服务于前端的后端),通俗的说是一个专门用于为前端业务提供数据的后端程序
2.1 BFF 解决什么问题
一个前端页面向 Service A、Service B 以及 Service C发送请求,不同的微服务返回的值用于渲染页面中不同的组件。此时,每次访问该页面都需要发送 3 个请求。我们需要一个服务来聚合Service A、Service B 以及 Service C响应的数据,这个服务层叫做BFF。
手机、平板端、PC机等用户终端都需要向每个Service,例如Service A发送请求。对于同一个功能,不同的终端需要的数据格式和内容会有不同。此时 Service A 的一个接口,不能同时满足三个客户端的不同需求。我们可以在Service A中开发三个接口,也可以增加一个数据裁剪服务,将数据按照不同终端的不同要求进行裁剪,这个服务层叫做BFF。
BFF层的作用是让前端有能力自由组装后台数据,减少大量的业务沟通成本,加快业务的迭代速度。
无论是数据聚合还是数据剪裁,这类程序的特点是不需要太强大的服务器运算能力,但是对程序的灵活性有较高的要求,这两个特点都正好和Node.js的优势相吻合。
2.2什么是BFF
BFF是用户体验适配器
3.1下载
下载安装:
建议和老师版本一样,不然后面一大堆麻烦;
历史版本下载:
https://nodejs.org/zh-cn/download/releases/
2、安装
打开安装,傻瓜式下一步即可:
3.测试是否安装成功:cmd 输入node -v
使用前端开发工具:VSCode
4.1控制台查询
创建 01-控制台程序.js
console.log(‘Hello Node.js’)
运行js的方式一:
打开命令行终端:Ctrl + Shift + y
进入到程序所在的目录,输入
node 01-控制台程序.js
1.编写一个js文件:
测试一:
在当前js的文件下cmd中打开运行:node 01.js
测试二:
执行js方式2:
终端报错的,先关掉vscode,然后设置兼容性–>以管理员身份运行,然后重启软件即可
vscode设置文件的自动保存:文件–>首选项–>设置–搜索save,然后打开自动保存
测试js的运行:
停止服务:ctrl + c
node已经集成了npm 不用再单独去装npm
什么是NPM
NPM全称Node Package Manager,是Node.js包管理工具,是全球最大的模块生态系统,里面所有的模块都是开源免费的;也是Node.js的包管理工具,相当于前端的Maven 。
#在命令提示符输入 npm -v 可查看当前npm版本
npm-v
2.1项目初始化
#建立一个空文件夹,在命令提示符进入该文件夹 执行命令初始化
npm init
#按照提示输入相关信息,如果是用默认值则直接回车即可。
#name: 项目名称
#version: 项目版本号
#description: 项目描述
#keywords: {Array}关键词,便于用户搜索到我们的项目
#最后会生成package.json文件,这个是包的配置文件,相当于maven的pom.xml
#我们之后也可以根据需要进行修改。
#如果想直接生成 package.json 文件,那么可以使用命令
npm init -y
安装npm:
版本遇到的问题:
npm WARN config global --global
, --local
are deprecated. Use --location=global
instead
解决方法:
打开nodejs安装位置的文件夹。并打开两个文件 npm.cmd 和 npm
找到那2个文件里面的prefix -g替换为prefix --location=global
23行左右一个:
12行左右一个:
修改完之后、关闭之前的命令行窗口。重新打开一个新的命令行窗口,检查一下。
最后打开cmd,查询npm版本即可!!!
二、其次还有变更npm版本
①打开命令提示符,WIN+R 输入cmd,输入以下代码,我选择的是8.12.1。
npm install -g npm-windows-upgrade
npm-windows-upgrade
②测试一下,npm -v
然后设置镜像:
2.2修改npm镜像:
NPM官方的管理的包都是从 http://npmjs.com下载的,但是这个网站在国内速度很慢。
这里推荐使用淘宝 NPM 镜像 http://npm.taobao.org/ ,淘宝 NPM 镜像是一个完整 npmjs.com 镜像,同步频率目前为 10分钟一次,以保证尽量与官方服务同步。
设置镜像地址:
#经过下面的配置,以后所有的 npm install 都会经过淘宝的镜像地址下载
npm config set registry https://registry.npm.taobao.org
#查看npm配置信息
npm config list
注意:npm 切换,当遇到npm高版本不能用的时候建议切换低版本,不行去掉sudo:
sudo npm -g install npm@6.4.1
遇到的错误:
npm WARN npm npm does not support Node.js v16.16.0
npm WARN npm You should probably upgrade to a newer version of node as we
npm WARN npm can't make any promises that npm will work with this version.
npm WARN npm Supported releases of Node.js are the latest release of 6, 8, 9, 10, 11.
npm WARN npm You can find the latest version at https://nodejs.org/
npm ERR! cb.apply is not a function
npm ERR! A complete log of this run can be found in:
npm ERR! C:\Users\fan\AppData\Roaming\npm-cache\_logs\2022-07-29T04_42_05_867Z-debug.log
npm版本过旧,安装对应版本,
在此网址查找对应版本:https://nodejs.org/zh-cn/download/releases/
vscode中的终端执行:
npm -g install npm@8.11.0
还不行的话,使用8.12.1版本
还是不行的话,就是缓存问题:
这说明npm存在旧的npm缓存,还是旧的npm 环境。
我将 C:\Users\user\AppData\Roaming下的 npm、npm-cache两个文件删除
删除后重新执行 npm -g install npm@8.11.0,低版本6.4.1
最后完美解决
根据依赖下载安装包:
#npm管理的项目在备份和传输的时候一般不携带node_modules文件夹
#安装会自动在项目目录下添加 package-lock.json文件,这个文件帮助锁定安装包的版本
npm install #根据package.json中的配置下载依赖,初始化项目
2.4其它命令
#更新包(更新到最新版本)
npm update 包名
#全局更新
npm update -g 包名
#卸载包
npm uninstall 包名
#全局卸载
npm uninstall -g 包名
1.先创建一个文件夹:npmdemo
2.设置淘宝镜像:
跳转到需要添加的项目路径, 安装npm淘宝镜像:
npm config set registry https://registry.npm.taobao.org
npm config list
npm初始化:
npm init
或者如下一步到位:
npm init -y
npm基本命令:
npm 下载文件:如
npm install jquery
或者下载指定的版本:
npm install jquery@2.1.x
npm install -g webpack
webpack -v 测试是否安装成功
自己创建文件夹src:
01.js:
export default {
list(){
console.log("ilst---")
},
save(){
console.log("save---")
}
}
02.js:
import user from './01.js'
//调用
user.list()
user.save()
然后执行js:在src下执行:node 02.js
执行报错:
第一步:
npm install -g babel-cli ,这里不行的话,要删除缓存,警告不用管
这里报错:是npm版本过高导致,我们又得退回低版本6.4.1,npm -g install npm@6.4.1
babel --version
报错问题解决方案:https://blog.csdn.net/m0_59751822/article/details/125229851
或者直接PowerShell中执行:Set-ExecutionPolicy RemoteSigned
第二步:
.babelrc ,此文件和src平齐
文件内写入:
{
"presets": ["es2015"],
"plugins": []
}
第三步:
安装转码器:
npm install -D babel-preset-es2015
在根目录执行:
npm install -D babel-preset-es2015
第四步:
创建一个输出文件:dist
目的:将src中的内容转成es5输出到dist中
babel src -d dist
然后执行调用js,在dist下: node 02.js
另一种js调用写法:
第一步:安装
创建一个单独的文件夹:webpackdemo
然后初始化此文件夹:npm init -y
然后做全局安装:
npm install -g webpack webpack-cli
webpack -v 查看版本号
第二步:
01.js内容:
exports.info=function(str){
document.write(str)
}
02.js内容:
exports.add=function(a,b){
return a+b;
}
在src下创建main.js文件:把要打包的文件进行引入
main:js:
const a= require("./01.js")
const b= require("./02.js")
a.info("hello--: " + b.add(1,2))
第三步:js打包
在根目录下创建文件:webpack.config.js:
const path=require("path"); //Node.js内置模块
module.exports= {
entry:"./src/main.js", //配置入口文件
output:{
//其他配置
path: path.resolve(__dirname,"./dist"),//输出路径
filename: "bundle.js" //输出文件
}
}
并在根目录下创建dist输出文件夹
第四步:打包:
webpack --mode=development
测试:01.html:
01.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script src="./dist/bundle.js"></script>
</body>
</html>
打开页面成功显示;
css打包:
安装css打包工具:
npm install -D style-loader css-loader
module: {
rules: [
{
test: /\.css$/, //打包规则应用到以css结尾的文件上
use: ['style-loader', 'css-loader']
}
]
}
5.3在src文件夹创建style.css
5.4修改main.js
在第一行引入style.css
require(‘./style.css’)
删掉绑定文件,重新打包:
5.5重新打包
webpack --mode=development
然后浏览器刷新看:
1.1简介:
vue-element-admin是基于element-ui 的一套后台管理系统集成方案。
注意:springboot使用2.2.1
https://panjiachen.github.io/vue-element-admin-site/zh/guide
1.2安装
# 解压压缩包
# 进入目录
cd vue-element-admin-master
# 安装依赖
npm install
# 启动。执行后,浏览器自动弹出并访问http://localhost:9527/
npm run dev
则先执行下面的命令,再install
npm i -g node-sass --sass_binary_site=https://npm.taobao.org/mirrors/node-sass/
npm install
下载失败的,先用npm cache clean --force命令清除一下缓存!然后再重新下载一遍
注意官网下载下来的文件有两层外包装,要复制里面的;
node版本高的问题:
报错的可以试试,npm install -g node-gyp ,再重新安装
启动项目:
npm run dev
2、vue-admin-template
2.1简介
vueAdmin-template是基于vue-element-admin的一套后台管理系统基础模板(最少精简版),可作为模板进行二次开发。
GitHub地址:https://github.com/PanJiaChen/vue-admin-template
建议:你可以在 vue-admin-template 的基础上进行二次开发,把 vue-element-admin当做工具箱,想要什么功能或者组件就去 vue-element-admin 那里复制过来。
新版本的脚手架vue-admin-template可以直接成功进入页面:
但是旧版的不行:
1、前端登录问题
默认情况下,前端项目已经实现了登录功能,后端连接到远程Mock平台的模拟数据接口进行登录,而Mock平台地址无效,导致前端的登录功能无法执行
修改部分文件:
修改的地方一:
修改的地方二:
获取用户信息的方法// get user info
头像地址: ‘https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif’
import { login, logout, getInfo } from '@/api/login' import { getToken, setToken, removeToken } from '@/utils/auth' const user = { state: { token: getToken(), name: '', avatar: '', roles: [] }, mutations: { SET_TOKEN: (state, token) => { state.token = token }, SET_NAME: (state, name) => { state.name = name }, SET_AVATAR: (state, avatar) => { state.avatar = avatar }, SET_ROLES: (state, roles) => { state.roles = roles } }, actions: { // 登录 Login({ commit }, userInfo) { const data = {'token':'admin'} setToken(data.token) commit('SET_TOKEN', data.token) // const username = userInfo.username.trim() // return new Promise((resolve, reject) => { // login(username, userInfo.password).then(response => { // const data = response.data // setToken(data.token) // commit('SET_TOKEN', data.token) // resolve() // }).catch(error => { // reject(error) // }) // }) }, // 获取用户信息 GetInfo({ commit, state }) { const data = {'roles':'admin','name':'admin','avatar':'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif'} if (data.roles && data.roles.length > 0) { // 验证返回的roles是否是一个非空数组 commit('SET_ROLES', data.roles) } else { reject('getInfo: roles must be a non-null array !') } commit('SET_NAME', data.name) //设置名字 commit('SET_AVATAR', data.avatar) //设置头像 // return new Promise((resolve, reject) => { // getInfo(state.token).then(response => { // const data = response.data // if (data.roles && data.roles.length > 0) { // 验证返回的roles是否是一个非空数组 // commit('SET_ROLES', data.roles) // } else { // reject('getInfo: roles must be a non-null array !') // } // commit('SET_NAME', data.name) // commit('SET_AVATAR', data.avatar) // resolve(response) // }).catch(error => { // reject(error) // }) // }) }, // 登出 LogOut({ commit, state }) { commit('SET_TOKEN', '') commit('SET_ROLES', []) removeToken() // return new Promise((resolve, reject) => { // logout(state.token).then(() => { // commit('SET_TOKEN', '') // commit('SET_ROLES', []) // removeToken() // resolve() // }).catch(error => { // reject(error) // }) // }) }, // 前端 登出 FedLogOut({ commit }) { //return new Promise(resolve => { commit('SET_TOKEN', '') removeToken() resolve() //}) } } } export default user
修改完之后保存,从新启动项目 npm run dev
测试登录登出功能;
1.设置增加一个漏由:
{ path: '/hospSet', component: Layout, redirect: '/hospSet/list', name: '医院设置管理', meta: { title: '医院设置管理', icon: 'example' }, children: [ { path: 'list', name: '医院设置列表', component: () => import('@/views/hospset/list'), meta: { title: '医院设置列表', icon: 'table' } }, { path: 'add', name: '医院设置添加', component: () => import('@/views/hospset/add'), meta: { title: '医院设置添加', icon: 'tree' } } ] },
2.增加视图页面:修改视图的跳转路径
修改页面:list.vue:
<template>
<div class = "app-container">
医院设置列表
</div>
</template>
3.修改api中的请求:
复制一个模板:
最终的:
import request from '@/utils/request'
export default {
getHospSetList (current ,limit,searchObj){
return request({
url:`/admin/hosp/hospitalSet/findPageHospSet/${current}/${limit}`,
mothod:'post',
data : searchObj //使用json传输
})
}
}
hospset.js:
import request from '@/utils/request'
//定义接口路径的
export default {
//医院设置列表
getHospSetList(current,limit,searchObj) {
return request ({
url: `/admin/hosp/hospitalSet/findPageHospSet/${current}/${limit}`,
method: 'post',
data: searchObj //使用json
})
}
}
修改项目端口号:config.dev.env.js中:
继续修改页面:list.vue:
最后的list.vue:
<template> <div class = "app-container"> 医院设置列表 </div> </template> <script> //引入接口定义的js文件 import hospset from '@/api/hospset' export default ({ //定义变量和初始值 data() { return { current: 1, //当前页 limit: 3, //每页显示的记录数 searchObj: {}, //条件封装对象 list: [] , //每页的数据集合 total: 0 //总记录数 }; }, created() { //在页面渲染之前执行 //一般调用methods定义的方法,得到数据 this.getList() }, methods: { getList(){ hospset.getHospSetList(this.current,this.limit,this.searchObj) .then(response => { console.log(response) //返回结合数据 this.list = response.data.records //总记录数 this.total = response.data.total }) .catch(error => { console.log(error) }) } } }) </script>
数据库增加几个数据:
/**
* 分页插件
* @return 分页插件的实例
*/
@Bean
public PaginationInnerInterceptor paginationInterceptor() {
return new PaginationInnerInterceptor();
}
测试分页的后端,ok;
重新启动前端的项目:
打开 config/index.js,配置是否开启语法检查
useEslint: false,
list.vue中的div中使用表格模板:
完整的代码:
<template> <div class = "app-container"> 医院设置列表 <!-- --> <el-table :data="list" stripe style="width: 100%"> <el-table-column type="index" width="50" label="序号" ></el-table-column> <el-table-column prop="hosname" label="医院名称" ></el-table-column> <el-table-column prop="hoscode" label="医院编号" ></el-table-column> <el-table-column prop="apiUrl" label="api基础路径" width="200"></el-table-column> <el-table-column prop="contactsName" label="联系人姓名" ></el-table-column> <el-table-column prop="contactsPhone" label="联系人手机" ></el-table-column> <el-table-column type="状态" width="80" > <template slot-scope="scope"> {{scope.row.status === 1 ? '可用' : '不可用'}} </template> </el-table-column>、 </el-table> <!-- --> </div> </template>
注意。这里测试的时候需要开启一个service_hosp即可,不需要开启redis,redis只是在数据字典那里使用了。
然后刷新页面:
分页插件:放在el-table外的紧邻下边
<!-- 分页 -->
<el-pagination
:current-page="current"
:page-size="limit"
:total="total"
style="padding: 30px 0; text-align: center;"
layout="total, prev, pager, next, jumper"
@current-change="getList"/>
查询框放在table上面:
<!-- -->
<el-form :inline="true" class="demo-form-inline">
<el-form-item>
<el-input v-model="searchObj.hosname" placeholder="医院名称"/>
</el-form-item>
<el-form-item>
<el-input v-model="searchObj.hoscode" placeholder="医院编号"/>
</el-form-item>
<el-button type="primary" icon="el-icon-search" @click="getList()">查询</el-button>
</el-form>
<!-- -->
<el-table-column label="操作" width="280" align="center">
<template slot-scope="scope">
<el-button type="danger" size="mini"
icon="el-icon-delete" @click="removeDataById(scope.row.id)">删除 </el-button>
</template>
</el-table-column>
删除的接口路径的定义:
删除的页面js:
//删除医院设置的方法 removeDataById(id){ // alert(id); //hospset.deleteHospSet(id) this.$confirm('此操作将永久删除该医院设置信息, 是否继续?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => { //调用删除接口 hospset.deleteHospSet(id) .then(res =>{ //1.提示 this.$message({ type: 'success', message: '删除成功!' }); //2.刷新页面 this. getList(1) //默认查询第一页数据 }) }).catch(() => { this.$message({ type: 'info', message: '已取消删除' }); }); }
到此的list.vue完整代码:
<template> <div class = "app-container"> 医院设置列表 <!-- --> <el-form :inline="true" class="demo-form-inline"> <el-form-item> <el-input v-model="searchObj.hosname" placeholder="医院名称"/> </el-form-item> <el-form-item> <el-input v-model="searchObj.hoscode" placeholder="医院编号"/> </el-form-item> <el-button type="primary" icon="el-icon-search" @click="getList()">查询</el-button> </el-form> <!-- --> <el-table :data="list" stripe style="width: 100%"> <el-table-column type="index" width="50" label="序号" ></el-table-column> <el-table-column prop="hosname" label="医院名称" ></el-table-column> <el-table-column prop="hoscode" label="医院编号" ></el-table-column> <el-table-column prop="apiUrl" label="api基础路径" width="200"></el-table-column> <el-table-column prop="contactsName" label="联系人姓名" ></el-table-column> <el-table-column prop="contactsPhone" label="联系人手机" ></el-table-column> <el-table-column type="状态" width="80" > <template slot-scope="scope"> {{scope.row.status === 1 ? '可用' : '不可用'}} </template> </el-table-column> <el-table-column label="操作" width="280" align="center"> <template slot-scope="scope"> <el-button type="danger" size="mini" icon="el-icon-delete" @click="removeDataById(scope.row.id)">删除 </el-button> </template> </el-table-column> </el-table> <!-- --> <!-- 分页 --> <el-pagination :current-page="current" :page-size="limit" :total="total" style="padding: 30px 0; text-align: center;" layout="total, prev, pager, next, jumper" @current-change="getList"/> </div> </template> <script> //引入接口定义的js文件 import hospset from '@/api/hospset' export default ({ //定义变量和初始值 data() { return { current: 1, //当前页 limit: 3, //每页显示的记录数 searchObj: {}, //条件封装对象 list: [] , //每页的数据集合 total: 0 //总记录数 }; }, created() { //在页面渲染之前执行 //一般调用methods定义的方法,得到数据 this.getList() }, methods: { getList(page = 1){ this.current = page; hospset.getHospSetList(this.current,this.limit,this.searchObj) .then(response => { console.log(response) //返回结合数据 this.list = response.data.records //总记录数 this.total = response.data.total }) .catch(error => { console.log(error) }) }, //删除医院设置的方法 removeDataById(id){ // alert(id); //hospset.deleteHospSet(id) this.$confirm('此操作将永久删除该医院设置信息, 是否继续?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => { //调用删除接口 hospset.deleteHospSet(id) .then(res =>{ //1.提示 this.$message({ type: 'success', message: '删除成功!' }); //2.刷新页面 this. getList(1) //默认查询第一页数据 }) }).catch(() => { this.$message({ type: 'info', message: '已取消删除' }); }); } } }) </script>
增加页面的复选框和批量删除按钮:
绑定事件:
方法定义:
methods: { //获取选择复选框的id值,并传递给方法的参数中selection handleSelectionChange(selection) { console.log(selection) }, //批量删除 removeRows(){ }, //医院设置列表 getList(page = 1){ this.current = page; hospset.getHospSetList(this.current,this.limit,this.searchObj) .then(response => { console.log(response) //返回结合数据 this.list = response.data.records //总记录数 this.total = response.data.total }) .catch(error => { console.log(error) }) }, //删除医院设置的方法 removeDataById(id){ // alert(id); //hospset.deleteHospSet(id) this.$confirm('此操作将永久删除该医院设置信息, 是否继续?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => { //调用删除接口 hospset.deleteHospSet(id) .then(res =>{ //1.提示 this.$message({ type: 'success', message: '删除成功!' }); //2.刷新页面 this. getList(1) //默认查询第一页数据 }) }).catch(() => { this.$message({ type: 'info', message: '已取消删除' }); }); } }
批量删除的api:
//批量删除医院设置,传给后端的参数都在request中
batchRomeveHospSet(idList){
return request ({
url: `/admin/hosp/hospitalSet/batchRemove`,
method: 'delete',
data : idList //传给后端接口的数据,json形式传递
})
}
批量删除代码:
<template> <div class = "app-container"> 医院设置列表 <!-- --> <el-form :inline="true" class="demo-form-inline"> <el-form-item> <el-input v-model="searchObj.hosname" placeholder="医院名称"/> </el-form-item> <el-form-item> <el-input v-model="searchObj.hoscode" placeholder="医院编号"/> </el-form-item> <el-button type="primary" icon="el-icon-search" @click="getList()">查询</el-button> </el-form> <!-- --> <!-- 批量删除工具条 --> <div> <el-button type="danger" size="mini" @click="removeRows()">批量删除</el-button> </div> <el-table :data="list" stripe style="width: 100%" @selection-change="handleSelectionChange"> <el-table-column type="selection" width="55"/> <el-table-column type="index" width="50" label="序号" ></el-table-column> <el-table-column prop="hosname" label="医院名称" ></el-table-column> <el-table-column prop="hoscode" label="医院编号" ></el-table-column> <el-table-column prop="apiUrl" label="api基础路径" width="200"></el-table-column> <el-table-column prop="contactsName" label="联系人姓名" ></el-table-column> <el-table-column prop="contactsPhone" label="联系人手机" ></el-table-column> <el-table-column type="状态" width="80" > <template slot-scope="scope"> {{scope.row.status === 1 ? '可用' : '不可用'}} </template> </el-table-column> <el-table-column label="操作" width="280" align="center"> <template slot-scope="scope"> <el-button type="danger" size="mini" icon="el-icon-delete" @click="removeDataById(scope.row.id)">删除 </el-button> </template> </el-table-column> </el-table> <!-- --> <!-- 分页 --> <el-pagination :current-page="current" :page-size="limit" :total="total" style="padding: 30px 0; text-align: center;" layout="total, prev, pager, next, jumper" @current-change="getList"/> </div> </template> <script> //引入接口定义的js文件 import hospset from '@/api/hospset' export default ({ //定义变量和初始值 data() { return { current: 1, //当前页 limit: 3, //每页显示的记录数 searchObj: {}, //条件封装对象 list: [] , //每页的数据集合 total: 0 ,//总记录数 multipleSelection : [] }; }, created() { //在页面渲染之前执行 //一般调用methods定义的方法,得到数据 this.getList() }, methods: { //获取选择复选框的id值,并传递给方法的参数中selection //每次点击复选框,触发这个事件,得到id值 handleSelectionChange(selection) { console.log(selection) this.multipleSelection = selection;//赋值 }, //批量删除 removeRows(){ //batchRomeveHospSet this.$confirm('此操作将永久删除该医院设置信息, 是否继续?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => { var idList = []; //遍历数组得到每个id值,设置到idList中,multipleSelection是一个数组,数组中每一个元素是一个对象obj, //此对象中包含id属性 for(var i =0 ;i<this.multipleSelection.length;i++){ var obj = this.multipleSelection[i]; var id = obj.id; idList.push(id); } //调用删除接口 hospset.batchRomeveHospSet(idList) //将idList传进来 .then(res =>{ //1.提示 this.$message({ type: 'success', message: '删除成功!' }); //2.刷新页面 this. getList(1) //默认查询第一页数据 }) }).catch(() => { this.$message({ type: 'info', message: '已取消删除' }); }); }, //医院设置列表 getList(page = 1){ this.current = page; hospset.getHospSetList(this.current,this.limit,this.searchObj) .then(response => { console.log(response) //返回结合数据 this.list = response.data.records //总记录数 this.total = response.data.total }) .catch(error => { console.log(error) }) }, //删除医院设置的方法 removeDataById(id){ // alert(id); //hospset.deleteHospSet(id) this.$confirm('此操作将永久删除该医院设置信息, 是否继续?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => { //调用删除接口 hospset.deleteHospSet(id) .then(res =>{ //1.提示 this.$message({ type: 'success', message: '删除成功!' }); //2.刷新页面 this. getList(1) //默认查询第一页数据 }) }).catch(() => { this.$message({ type: 'info', message: '已取消删除' }); }); } } }) </script>
修改接口api:
//锁定和取消锁定
lockHospSet(id,status){
return request({ //返回请求
url: `/admin/hosp/hospitalSet/lockHospSet/${id}/${status}`,
method: 'put',
})
}
碎丁和取消锁定按钮:
按钮组件:
<el-button v-if="scope.row.status==1" type="primary" size="mini"
icon="el-icon-delete" @click="lockHostSet(scope.row.id,0)">锁定 </el-button>
<el-button v-if="scope.row.status==0" type="danger" size="mini"
icon="el-icon-delete" @click="lockHostSet(scope.row.id,1)">取消锁定 </el-button>
//锁定和取消锁定
lockHostSet(id,status){
hospset.lockHospSet(id,status)
.then(response => {
//刷新到当前页
this.getList(this.current)
})
},
这个页面后面设计,现在写后台;
api: 注意:url一定要和后端的controller中的接口的路径一样;
//添加医院设置
saveHospitalSet(hospitalSet){
return request({
url: `/admin/hosp/hospitalSet/saveHospitalSet`,
method: 'post',
data: hospitalSet //json参数,即给resonpnsbody的
})
},
重新定义一个add页面:
add.vue
form组件:
<template> <div class = "app-container"> 医院设置添加 <el-form label-width="120px"> <el-form-item label="医院名称"> <el-input v-model="hospitalSet.hosname"/> </el-form-item> <el-form-item label="医院编号"> <el-input v-model="hospitalSet.hoscode"/> </el-form-item> <el-form-item label="api基础路径"> <el-input v-model="hospitalSet.apiUrl"/> </el-form-item> <el-form-item label="联系人姓名"> <el-input v-model="hospitalSet.contactsName"/> </el-form-item> <el-form-item label="联系人手机"> <el-input v-model="hospitalSet.contactsPhone"/> </el-form-item> <el-form-item> <el-button type="primary" @click="saveOrUpdate">保存</el-button> </el-form-item> </el-form> </div> </template>
add页面的js方法:
总的add.vue:
<template> <div class = "app-container"> 医院设置添加 <el-form label-width="120px"> <el-form-item label="医院名称"> <el-input v-model="hospitalSet.hosname"/> </el-form-item> <el-form-item label="医院编号"> <el-input v-model="hospitalSet.hoscode"/> </el-form-item> <el-form-item label="api基础路径"> <el-input v-model="hospitalSet.apiUrl"/> </el-form-item> <el-form-item label="联系人姓名"> <el-input v-model="hospitalSet.contactsName"/> </el-form-item> <el-form-item label="联系人手机"> <el-input v-model="hospitalSet.contactsPhone"/> </el-form-item> <el-form-item> <el-button type="primary" @click="saveOrUpdate">保存</el-button> </el-form-item> </el-form> </div> </template> <script> import hospset from '@/api/hospset' export default { //data方法定义数据; data(){ return { hospitalSet:{} } }, created(){ }, methods: { //添加 saveOrUpdate(){ hospset.saveHospSet(this.hospitalSet) //调用api接口 .then(res=>{ //提示 this.$message({ type: 'success', message: '添加成功!' }) //跳转到列表页面,使用漏由跳转方式实现 this.$router.push({path:'/hospSet/list'}) }) } } } </script>
1.隐藏漏由的设置,进行页面的跳转,从list到add页面,此跳转是隐藏的。
//隐藏漏由
{
path: 'edit/:id', //:id相当于原先的?参数
name: 'EduTeacherEdit',
component: () => import('@/views/hospset/add'),
meta: { title: '编辑', noCache:true },
hidden: true //隐藏
}
2.修改按钮组件:router-link 是漏由跳转标签,注意修改成自己的路径
<!-- 修改按钮 -->
<router-link :to="'/hospSet/edit/'+scope.row.id">
<el-button type="primary" size="mini" icon="el-icon-edit"></el-button>
</router-link>
存放位置:
漏油跳转过程:
修改api的定义:hospset.js:
//以下两个是修改的api //数据回显的api,医院设置id查询 getHospSet(id){//getHospSet return request({ url: `/admin/hosp/hospitalSet/getHospSet/${id}`, method: 'get', }) }, //修改医院设置 updateHospSet(hospitalSet){ return request({ url: `/admin/hosp/hospitalSet/updateHospSet`, method: 'post', data: hospitalSet //json参数,即给resonpnsbody的 }) }
3.add.vue页面:
add.vue页面js:
注意这里是route:
created(){ //页面渲染之前执行 //获取漏由id值 //调用接口得到医院设置信息 if(this.$route.params && this.$route.params.id){ const id = this.$route.params.id; alert(id); this.getHostSet(id);//调用methods中的getHospSet进行根据id查询 } }, methods: { //根据id查询 getHostSet(id){ hospset.getHospSet(id) .then(response =>{ //回调函数 //alert(response.data.id) this.hospitalSet = response.data; //将data数据赋值给双向数据绑定的模型hospitalSet }) }, //添加
成功页面:这里是编辑页面的跳转:edit:
增加两个单独的方法:
第一个方法:
第二个方法
判断修改还是添加:
import request from '@/utils/request' //定义接口路径的, //特别注意,这里前端接口的定义,一定要和后端接口一样,参数也一样 export default { //医院设置列表 getHospSetList(current,limit,searchObj) { return request ({ url: `/admin/hosp/hospitalSet/findPageHospSet/${current}/${limit}`, method: 'post', data: searchObj //使用json }) }, //逻辑删除医院设置 deleteHospSet(id){ return request ({ url: `/admin/hosp/hospitalSet/${id}`, method: 'delete', }) }, //批量删除医院设置,传给后端的参数都在request中 batchRomeveHospSet(idList){ return request ({ url: `/admin/hosp/hospitalSet/batchRemove`, method: 'delete', data : idList //传给后端接口的数据,json形式传递 }) }, //锁定和取消锁定,注意,这里要和后端定义相同的接口 lockHospSet(id,status){ return request({ //返回请求 url: `/admin/hosp/hospitalSet/lockHospitalSet/${id}/${status}`, method: 'put', }) }, //添加医院设置 saveHospitalSet(hospitalSet){ return request({ url: `/admin/hosp/hospitalSet/saveHospitalSet`, method: 'post', data: hospitalSet //json参数,即给resonpnsbody的 }) }, //以下两个是修改的api //数据回显的api,医院设置id查询 getHospSet(id){//getHospSet return request({ url: `/admin/hosp/hospitalSet/getHospSet/${id}`, method: 'get', }) }, //修改医院设置 updateHospSet(hospitalSet){ return request({ url: `/admin/hosp/hospitalSet/updateHospSet`, method: 'post', data: hospitalSet //json参数,即给resonpnsbody的 }) } }
特别注意后台controller接口maping路径方法和前台api接口的方法名字要一致。
一般network错误都是这两边不一致导致的,还有页面中的js调用前端api方法的时候要注意方法名字要写正确;
<template> <div class = "app-container"> 医院设置添加 <el-form label-width="120px"> <el-form-item label="医院名称"> <el-input v-model="hospitalSet.hosname"/> </el-form-item> <el-form-item label="医院编号"> <el-input v-model="hospitalSet.hoscode"/> </el-form-item> <el-form-item label="api基础路径"> <el-input v-model="hospitalSet.apiUrl"/> </el-form-item> <el-form-item label="联系人姓名"> <el-input v-model="hospitalSet.contactsName"/> </el-form-item> <el-form-item label="联系人手机"> <el-input v-model="hospitalSet.contactsPhone"/> </el-form-item> <el-form-item> <el-button type="primary" @click="saveOrUpdate">保存</el-button> </el-form-item> </el-form> </div> </template> <script> import hospset from '@/api/hospset' export default { //data方法定义数据; data() { return { hospitalSet:{} //定义一个空对象用来存放要保存的对象 } }, created() { //页面渲染之前执行 //获取漏由id值, //调用接口得到医院设置信息 if(this.$route.params && this.$route.params.id){ const id = this.$route.params.id; //alert(id); this.getHostSet(id);//调用methods中的getHospSet进行根据id查询 }else{ //表单数据清空 this.hospitalSet = {} } }, methods: { //1.根据id查询的方法,这个方法用于数据回显 getHostSet(id){ hospset.getHospSet(id) //调用后台根据id查询的方法 .then(response => { //回调函数 //alert(response.data.id) //将查询到的实体类返回赋值 给 前台的 hospitalSet对象,则此对象是有id的对象 this.hospitalSet = response.data; //将data数据赋值给双向数据绑定的模型hospitalSet }) }, //以下三个方法是修改或者增加的 /* --------------------- */ //2.定义添加save save(){ hospset.saveHospitalSet(this.hospitalSet) //调用api接口的后台保存方法 .then( res => { //提示 this.$message({ type: 'success', message: '添加成功!' }) //跳转到列表页面,使用漏由跳转方式实现,跳转到router页面的redirect: '/hospSet/list' this.$router.push({path:'/hospSet/list'}) }) }, //3.定义 修改update update(){ hospset.updateHospSet(this.hospitalSet) //调用api接口-》调用后台修改医院设置 .then( res => { //调用后台返回的结果放在res中 //提示 this.$message({ type: 'success', message: '修改成功!' }) //跳转到列表页面,使用漏由跳转方式实现 this.$router.push({path:'/hospSet/list'}) }) }, //4.定义 添加或者修改的判断方法 saveOrUpdate(){ //由于修改 和新增 用的是同一个页面,所以要判断走哪个方法 //判断是添加还是修改,判定依据是否带id,带id的是修改,不带id是新增 if(!this.hospitalSet.id ){ //没有带id,新增 this.save() }else{ //带id的实体类,则是修改 this.update() } } /* ---------------------------- */ } } </script>
@RestController @RequestMapping("/admin/hosp/hospitalSet") @Api("医院设置的控制器") @CrossOrigin //解决跨域问题的 public class HospitalSetController { //注入service接口 @Resource private HospitalSetService hospitalSetService; @GetMapping("findAll") @ApiOperation(value = "findAllHospital查找所有") public Result findAllHospital(){ List<HospitalSet> list = hospitalSetService.list(); return Result.ok(list); } @DeleteMapping("{id}") @ApiOperation("逻辑删除") public Result removeHospSet(@PathVariable Long id){ boolean b = hospitalSetService.removeById(id); if(b){ return Result.ok(); }else{ return Result.fail(); } } //3.条件查询带分页 @PostMapping("findPageHospSet/{current}/{limit}") public Result findPageHospSet(@PathVariable long current , @PathVariable long limit, @RequestBody(required = false) HospitalSetQueryVo hospitalSetQueryVo ){ //创建page对象,传递当前页,每页的记录数 Page<HospitalSet> page = new Page<>(current, limit); //构造条件 QueryWrapper<HospitalSet> hospitalSetQueryWrapper = new QueryWrapper<>(); String hosname = hospitalSetQueryVo.getHosname();//医院名称 String hoscode = hospitalSetQueryVo.getHoscode();//医院编号 if(!StringUtils.isEmpty(hosname)){ hospitalSetQueryWrapper.like("hosname",hospitalSetQueryVo.getHosname()); } if(!StringUtils.isEmpty(hoscode)){ hospitalSetQueryWrapper.eq("hoscode",hospitalSetQueryVo.getHoscode()); } //调用方法实现分页查询 Page<HospitalSet> hospitalSetPage = hospitalSetService.page(page, hospitalSetQueryWrapper); return Result.ok(hospitalSetPage); } //4.添加医院设置,@RequestBody主要用来接收前端传递给后端的json字符串中的数据的 @PostMapping("saveHospitalSet") public Result saveHospitalSet(@RequestBody(required = true) HospitalSet hospitalSet){ //手动设置状态,1使用,0表示不能使用 hospitalSet.setStatus(1); //签名秘钥 Random random = new Random(); hospitalSet.setSignKey(MD5.encrypt(System.currentTimeMillis()+""+ random.nextInt(1000))); //调用保存方法 boolean b = hospitalSetService.save(hospitalSet); if(b){ return Result.ok(); }else{ return Result.fail(); } } //5.根据id获取医院设置 信息 @GetMapping("getHospSet/{id}") public Result<HospitalSet> getHospSet(@PathVariable Long id ){ /*try { int a = 1/0; } catch (Exception e) { throw new YyghException("失败",201);//爆出自定义异常 }*/ HospitalSet byId = hospitalSetService.getById(id); return Result.ok(byId); } //6.修改医院设置的接口 @PostMapping("/updateHospSet") //@RequestBody获取前端封装的参数 public Result updateHospSet(@RequestBody HospitalSet hospitalSet){ //修改的话应该更新 修改时间 hospitalSet.setUpdateTime(new Date()); boolean b = hospitalSetService.updateById(hospitalSet); if(b){ return Result.ok(); }else{ return Result.fail(); } } //7.批量删除 医院设置的接口 @DeleteMapping("batchRemove") public Result batchRemove(@RequestBody List<Long> idList){ boolean b = hospitalSetService.removeByIds(idList); return Result.ok(); } //@PutMapping 更新请求 /* * 如果执行添加操作, 后面的添加请求不会覆盖前面的请求, 所以使用@Postmapping 如果执行修改操作, 后面的修改请求会把前面的请求给覆盖掉, 所以使用@PutMapping*/ //8 医院设置锁定和解锁 @PutMapping("lockHospitalSet/{id}/{status}") public Result lockHospitalSet(@PathVariable Long id, @PathVariable Integer status) { //根据id查询医院设置信息 HospitalSet hospitalSet = hospitalSetService.getById(id); //设置状态 hospitalSet.setStatus(status); //调用方法 hospitalSetService.updateById(hospitalSet); return Result.ok(); } //9 发送签名秘钥 @PutMapping("sendKey/{id}") public Result lockHospitalSet(@PathVariable Long id) { HospitalSet hospitalSet = hospitalSetService.getById(id); String signKey = hospitalSet.getSignKey(); String hoscode = hospitalSet.getHoscode(); //TODO 发送短信 return Result.ok(); } }
bug:组件重用问题:
设置漏由跳转刷新:
链接: https://blog.csdn.net/weixin_38568503/article/details/126085610?spm=1001.2014.3001.5501
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。