先搭建一个轮廓,慢慢的在填补
一、ajax
源生ajax
代码语言:javascript复制<script type="text/javascript">
function doAjax1() {
//1、创建异步对象
var xmlHttp = new XMLHttpRequest();
//2、绑定事件
xmlHttp.onreadystatechange = function () {
if(xmlHttp.readyState ==4 && xmlHttp.status ==200){
//显示后端传来的数据
alert(xmlHttp.responseText);
// 赋值给页面
var data = xmlHttp.responseText;
//更新dom对象更新页面数据
document.getElementById("mydata").innerText = data;
}
}
//3、初始化请求数据
xmlHttp.open("get","xx",true);
//4、发起请求
xmlHttp.send();
}
</script>
1、创建异步对象
代码语言:javascript复制var xmlHttp = new XMLHttpRequest();
2、属性说明:
代码语言:javascript复制readyState属性:一个js函数名或直接定义函数,每当readyState属性改变时,就会调用该函数
readyState属性:表示异步对象请求的状态变化
存有XMLHttpRequest的状态:从0到4发生变化
0:创建异步请求对象 var xmlHttp = new XMLHttpRequest()
1:初始化异步请求对象。xmlHttp.open(请求方式,请求地址,true)
2:发送请求,xmlHttp.send()
3:从服务端返回数据 XMLHttpRewuest内部处理,获取了原始的数据(我们不用)
4:异步请求对象已经将数据解析完毕,此时才可以读取数据(开发人员使用)更新当前页面
status属性:表示网络请求的状况
200:“OK”
404:未找到页面
500:服务器代码出错
当status==200时,表示网络请求是成功的
3、初始异步请求对象 异步的方法open()
代码语言:javascript复制xmlHttp.open(请求方式get|post,"服务器端的访问地址",同步|异步请求(默认true,表示异步))
4、使用异步对象发送请求
代码语言:javascript复制xmlHttp.send()
一个使用案例:
代码语言:javascript复制 function doAjax() {
//1、创建异步对象
var xmlHttp = new XMLHttpRequest();
//2、绑定事件
xmlHttp.onreadystatechange = function () {
//处理服务器端返回的数据,更新当前页面
// 1 -- 2 -- 4
//alert("readyState==>" xmlHttp.readyState "--->status" xmlHttp.status)
if(xmlHttp.readyState == 4&& xmlHttp.status ==200){
// alert(xmlHttp.responseText);
var data = xmlHttp.responseText;
//更新dom对象更新页面数据
document.getElementById("mydata").innerText = data;
}
}
//3、初始化请求数据
//获取dom对象的value属性值
var name = document.getElementById("name").value;
var w = document.getElementById("w").value;
var h = document.getElementById("h").value;
// http://localhost:8080/bmiServlet?name=张三&w=71&h=1.76
var param ="name=" name "&w=" w "&h=" h;
// alert("param====>" param)
xmlHttp.open("get","bmiAjax?" param,true);
//4、发起请求
xmlHttp.send();
}
json
代码语言:javascript复制使用Jackson把对象转换为json格式
//使用Jackson把p转换为json
ObjectMapper om =new ObjectMapper();
//writeValueAsString 把参数的Java对象转为json格式的字符串
String json = om.writeValueAsString(p);
前端解析json
代码语言:javascript复制//eval是执行括号中的代码,把json字符串转为json对象
var jsonobj = eval( data );
基于jQuery的ajax
代码语言:javascript复制ajax:
局部刷新
异步请求 async: true 默认 异步
代码语言:javascript复制$.ajax 该形式是基于jQuery的ajax的最标准的表现形式,该形式功能齐全,使用方便,实际开发中应用广泛。
$.get/post 该形式是基于上述$.ajax的简写形式,使用更加方便。但是在保留了核心ajax功能的同时,也去除了一些扩展功能。如果要使用额外的扩展功能,需要在ajax体外额外写代码。虽然功能不全,但是使用非常方便,实际开发中使用也很普遍。
get 以查询为主,设计到密码使用post
post 以添加,修改,删除操作为目的,安全
二、jQuery
基础
代码语言:javascript复制选择器
$("#id") id选择器
$(".class名") class选择器
$("标签名") 标签选择器
$("#id, .class, 标签名") 组合选择器
$("*") 选取当前页面中所有dom对象
存取值
html() html:相当于原生js的document.getElementById("").innerHTML
针对于标签*中的内容的存取值操作,该形式对于HTML元素,随着内容可以动态的赋予
html(值):存值
html():取值
text() text:与html()方法非常相似,也是针对于标签对中的内容的存取值操作
不同的是,text()方法值针对于内容本身,不注重html元素的动态赋予
text(值):
text():
val(值):存值
val():取值 val:相当于原生js的document.getElementById("").value
例如:获得值: $("#main").html()
其他常用的小结:
$(选择器).attr("属性名"):获取dom数组第一个对象的属性值
$(选择器).attr("属性名","值"):对数组中所有dom对象的属性设为新值
$(选择器).remove():将数组中所有dom对象及其子对象一并删除
$(选择器).empty():将数组中所有dom对象的子对象删除
$(选择器).append("<div>我动态添加的div</div>") 为数组中所有dom对象添加子对象
each是对数组,json和dom数组等的遍历,对每个元素调用一次处理函数
$.each(循环的内容,处理函数):表示使用jQuery的each,循环数组,每个数组成员都会执行后面的处理函数一次
$ 相当于Java的一个类名
.each 就是类中的静态方法
语法1:$.each(要遍历的对象,function(index,element){处理程序})
语法2:jQuery对象.each(function(index,element){处理程序})
index:数组的下标 都是自定义的形参,名称自定义
element:数组的对象
dom对象和jQuery对象
代码语言:javascript复制dom对象:使用JavaScript的语法创建的对象叫做dom对象,也就是js对象
var obj = document.getElementById("txt1"); obj是dom对象,也叫做js对象
jQuery对象:使用jQuery语法表示对象叫做jQuery对象,注意:jQuery表示的对象都是数组
var jobj = $("#txt1") jobj就是使用jQuery语法表示的对象,是jQuery对象,也是数组,现在数组中就一个值
dom对象可以和jquery对象互相转换
dom对象转jquery 语法:$(dom对象)
jquery对象转dom对象 语法:从数组中获得第一个对象,第一个对象就是dom对象,使用[0]或者get(0)
为什么要进行dom和jQuery的转换
目的是要使用对象的方法或者属性
当dom对象时,可以使用dom对象的属性或者方法,要想使用jQuery提供的函数,必须要是jQuery对象才行
命名建议:在命名jQuery对象时,为了与dom对象区分,习惯以$开头(建议)
示例:
代码语言:javascript复制function btnClick(){
//使用js获取dom对象
var obj = document.getElementById("btn");
//使用dom对象value属性获取值
alert("使用dom对象的属性:--->" obj.value);
//把dom转为jQuery,使用jQuery库的函数
var $jobj = $(obj);
//调用jQuery的函数,获取value的值
alert("jquery的函数--->" $jobj.val())
}
function btnClick2(){
//使用jQuery的语法获取页面的dom对象
// var obj = $("#txt")[0] //从数组中获取下标是0的dom对象 .get(0) 也可以
var obj = $("#txt").get(0);
// alert(obj.value);
var num = obj.value;
obj.value = num*num;
}
使用jQuery的函数,实现ajax请求的处理
没有jQuery之前,使用XMLHttpRequest做ajax,有4个步骤。
jQuery简化了ajax请求的处理,使用三个函数可以实现ajax请求处理
代码语言:javascript复制$.ajax()的使用 参数是json结构 $.post()和$.get()在内部都是调用$.ajax()
主要使用data、url、dateType、success
$.ajax({
data: "",为后台传递的参数 传统方式k=v&k2=v2和json方式 可以是字符串、数组、json,表示请求的参数和参数值
url: "",后台地址
type:"", 请求方式 post、get 不区分大小写,默认get
dataType :"", 从后台接受数据的方式text json 可不写
async: true, 默认就是true 异步刷新 使用最多 提升用户体验 可不写
contentType:一个字符串,表示从浏览器发送服务器的参数的类型,可不写
例如请求参数是json格式:application/json
error: function(){
一个function,表示当请求发生错误时,执行的函数
},
success : function(data){ 回调函数,后台执行完毕,该函数才执行
data 从后台响应回来的数据 相当于之前readyState==4 && status ==200
data就是responseText,是jQuery处理后的数据
$("msg").html(data); //案例
}
})
案例关键代码
代码语言:javascript复制$.get(url,data,function(data),dataType)
$.post(url,data,function(data),dataType)
用法,直接写值
// 做一个ajax请求,获取省份的所有城市信息
$.post("queryCityServlet",{proid:provinceId},function(resp) {
console.log(resp);
// alert(resp);
var city = $("#city");
city.empty();
$.each(resp,function (i,n) {
city.append("<option value='" i "'>" n.name "</option>")
})
}, "json")
代码语言:javascript复制 $(function () {
//做ajax请求,使用ajax的$.ajax()
$.ajax({
url:"queryProvinceServlet",
dataType:"json",
success:function (data) {
// alert(data);
//删除旧的数据,把已经存在的数据清空
$("#province").empty();
//便于前台查看
console.log(data);
$.each(data,function (i,n) {
//获取select这个dom对象
$("#province").append("<option value='" n.id "'>" n.name "</option>")
})
}
})
})
举例子
代码语言:javascript复制<script>
$(function () {
//默认加载完页面自动赋值
$("#msg").html(123);
//鼠标点击事件
$("#djBtn").click(function () {
// 局部刷新 但是没有从数据库取数据
// $("#msg").html(1234567890);
// 使用ajax
$.ajax({
url : "myservlet.do", //访问后台地址
// data : { // 传统形式"key1=value1&key2=value2" 或者 json形式 {“key1":"value1","key2":"value2"..}
// "key1":"value1" //为后台传递的参数
// },
type : "get" , //请求方式 get/post
// async: true, //默认为true 异步请求
dataType : "json" , //从后台接受数据的方式,text:接受普通文本 json:接受json格式的文件
success : function (data) { //回调函数(该函数的执行时机是后台执行完毕,该函数才去执行)
// data 从后台响应回来的数据
$("#msg").html(data);
// 赋值
$("#id1").html(data.s1.id);
$("#name1").html(data.s1.name);
}
})
})
})
</script>
三、vue
cdn
代码语言:javascript复制<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
<script src="https://cdn.staticfile.org/axios/0.18.0/axios.min.js"></script>
使用示例:
代码语言:javascript复制<div id="app">
<!-- 前端页面元素的内容,以差值表达式的形式来呈现 -->
{{message}}
</div>
<script>
var app = new Vue({
el:'#app', //指定要为哪个标签进行操作
data:{ //以json格式呈现
message:'Hello,world'
}
});
</script>
demo
代码语言:javascript复制<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>首页</title>
<link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
<script src="https://cdn.staticfile.org/axios/0.18.0/axios.min.js"></script>
<style>
table td{
width: 130px;
}
</style>
</head>
<body>
<a href="/dept/findAll">部门信息查询所有</a>
<a href="/dept/findById/10">部门根据id查询</a>
<a href="/goTest">测试部门页面</a>
<a href="/emp/findAll">员工信息查询所有</a>
<a href="/emp/findById/1001">员工根据id查询</a>
<a href="/goEmp">测试员工页面</a>
<div id="app">
<h1>员工信息</h1>
<!-- 按钮触发模态框 -->
<button class="btn btn-primary" data-toggle="modal" data-target="#myModal" onclick="dept_add_model()">
新增
</button>
<div style="height: 380px">
<table border="1px" style="border-collapse: collapse;text-align: center;">
<tr>
<td>员工编号</td>
<td>员工姓名</td>
<td>job编号</td>
<td>mgr编号</td>
<td>入职日期</td>
<td>薪水</td>
<td>奖金</td>
<td>部门id</td>
<td>部门名称</td>
<td>操作</td>
</tr>
<tr v-for="d in emp" :key="d.id">
<td>{{d.id}}</td>
<td>{{d.ename}}</td>
<td>{{d.jobId}}</td>
<td>{{d.mgr}}</td>
<td>{{d.joindate}}</td>
<td>{{d.salary}}</td>
<td>{{d.bonus}}</td>
<td>{{d.deptId}}</td>
<td>{{d.dept.name}}</td>
<td>
<button class="btn btn-danger" @click="deleteById(d.id)">删除</button>
|
<button class="btn btn-success" data-toggle="modal" data-target="#myModal1" onclick="dept_update_model()">修改</button>
</td>
</tr>
</table>
</div>
<div style="margin-left: 480px">
<input type="button" value="上一页" @click="lastPage">
<input type="button" value="下一页" @click="nextPage">
</div>
<!-- 模态框(Modal) -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"
aria-hidden="true" onclick="modal_hide()">×
</button>
<h4 class="modal-title" id="myModalLabel">
新增
</h4>
</div>
<form action="/emp/addEmp" method="post">
<div class="modal-body">
员工编号:<input type="number" name="id" required><br/>
员工姓名:<input type="text" name="ename" required><br/>
job编号:<input type="number" name="jobId" required><br/>
mgr编号:<input type="number" name="mgr" required><br/>
薪水:<input type="number" name="bonus" required><br/>
奖金:<input type="number" name="salary" required><br/>
部门id:<input type="number" name="deptId" required>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default"
data-dismiss="modal">关闭
</button>
<input type="submit" value="提交" class="btn btn-primary">
</div>
</form>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
<!--修改-->
<!-- 模态框(Modal) -->
<div class="modal fade" id="myModal1" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"
aria-hidden="true" onclick="modal_hide1()">×
</button>
<h4 class="modal-title" id="myModalLabel2">
修改
</h4>
</div>
<form action="/emp/updateEmp" method="post">
<div class="modal-body">
员工编号:<input type="number" name="id" required><br/>
员工姓名:<input type="text" name="ename" required><br/>
job编号:<input type="number" name="jobId" required><br/>
mgr编号:<input type="number" name="mgr" required><br/>
薪水:<input type="number" name="bonus" required><br/>
奖金:<input type="number" name="salary" required><br/>
部门id:<input type="number" name="deptId" required>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default"
data-dismiss="modal">关闭
</button>
<input type="submit" value="提交" class="btn btn-primary">
</div>
</form>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
</div>
</body>
</html>
<script type="text/javascript">
</script>
<script>
// 新增
//显示模态窗口
function dept_add_model() {
$("#dept_add_model").modal();
}
//隐藏模态窗口
function modal_hide() {
if (confirm("是否取消操作?")) {
//隐藏模态窗口
$("#dept_add_modal").modal('hide');
//$("input").val("");
$("#dept_add_form")[0].reset();
} else {
return false;
}
}
// 修改
//显示模态窗口
function dept_update_model() {
$("#dept_update_model").modal();
}
//隐藏模态窗口
function modal_hide1() {
if (confirm("是否取消操作?")) {
//隐藏模态窗口
$("#dept_update_model").modal('hide');
//$("input").val("");
$("#dept_update_form")[0].reset();
} else {
return false;
}
}
var vm = new Vue({
el: "#app",
data: {
emp: [],
offset: 0,
size: 10,
counts: 0,
ename:'',
mgr:'',
jobId:'',
bonus:'',
salary:'',
deptId:''
},
methods: {
nextPage() {
if (this.counts < this.offset 10) {
axios.get("emp/loadData?offset=" this.offset "&size=" this.size).then(res => {
this.emp = res.data.data;
console.log("nextPage()-->")
console.log(res.data)
})
} else {
this.offset = 10;
}
axios.get("emp/loadData?offset=" this.offset "&size=" this.size).then(res => {
this.emp = res.data.data;
console.log("nextPage()-->")
console.log(res.data)
})
},
//loadRows
lastPage() {
if (this.offset > 0) {
this.offset -= 10;
}
axios.get("emp/loadData?offset=" this.offset "&size=" this.size).then(res => {
this.emp = res.data.data;
console.log("lastPage()-->")
console.log(res.data)
})
},
deleteById(index){
axios.get("emp/deleteEmp?id=" index).then(res=>{
this.emp = res.data.data;
this.emp.splice(index,1)
})
}
// updateById(index){
// let data = new FormData();
// data.append('id',index);
// data.append('ename',this.ename);
// data.append('jobId',this.jobId);
// data.append('mgr',this.mgr);
// data.append('bonus',this.bonus);
// data.append('salary',this.salary);
// data.append('deptId',this.deptId);
// axios.post("emp/updateEmp",data).then(res=>{
// this.emp = res.data.data;
// })
// }
},
mounted() {
axios.get("emp/loadData?offset=" this.offset "&size=" this.size).then(res => {
this.emp = res.data.data;
}),
axios.get("emp/loadRows").then(res => {
this.counts = res.data.data
console.log(res.data)
console.log(res.data.data)
})
}
})
</script>
语法
代码语言:javascript复制<style>
[v-cloak]{
display: none;
}
</style>
v-cloak 解决差值表达式的闪烁问题(页面加载过程中,{{}}差值表达式,若网络较卡,首先展示{{}},一闪而过,最后出现我们想要的数据)
v-bind 绑定元素 简化 : 需要加在绑定属性的前面 :value="msg" :title="msg2"
v-on 绑定事件 简化 @ 使用场合:鼠标单击、键盘事件、下拉框等
v-model 实现双向数据绑定
差值表达式和v-text和v-html的区别
v-html 让变量变成html元素
v-text 就相当于{{msg}}
页面赋值有三种方式:差值表达式、v-html和v-text
对于已经存在的值,只有使用差值表达式可以保留原有数据,添加新值
v-html和v-text会先清空原有内容,然后在赋予新值
差值表达式会出现页面闪烁的效果,但是v-html和v-text不会
v-model 表单输入绑定
v-if:true,创建条件元素,false,删除该元素 v-if v-else-if else
v-show:true,展现条件元素,false,隐藏元素 false的相当于注释
v-for :key="index或者value.id" 作为唯一标识
语法:元素 in 数组
遍历字符串数组
遍历对象数组
遍历对象的属性和属性值
遍历整型数字
示例:
<li v-for="(item,index) in items">
{{item.message}}------->{{index}}
</li>
v-bind:属性="值" 动态绑定 缩写 :href="url" 响应式的更新HTML属性
class与style动态绑定 :class
内联样式 :style
v-on:click="doSomething" 缩写 @click="doSoemthing" 事件绑定
修饰符 v-on:submit.prevent="onSubmit"
.stop 阻止事件传播 语法:@click.stop="fun2"
.prevent 阻止超链接默认的行为
.capture 实现捕获触发事件的机制
.self 阻止的是自身的冒泡,不影响冒泡继续向外扩散,stop阻止的是向外扩散的冒泡
e.once 只触发一次事件处理函数
this.books.splice(index,1)//删除自身 实现删除效果
实现新增效果
var s ={id:this.id,name:this.name,age:this.age,gender:this.gender};
this.sList.push(s);
vue追加对象:this.courseList=this.courseList.concat(res.data.data);
方法的写法:
方法名(){
}
或者
方法名 : function(){
}
// import Component1 from './ComponentA'
//局部组件注册
components:{
// 组件名 test1
test1:{
template:"<div><h2>h2.{{m1}}.</h2></div>",
data:function(){
return{
m1:"小可爱"
}
}
}
}
//全局组件
Vue.component('button-counter2', {
props: ['title'],
data: function() {
return {
msg: 0
}
},
template: '<button @click="msg ">{{title}}点击了 {{msg}} 次</button>'
})
需要注意的
代码语言:javascript复制 mounted(){ //钩子函数 链式编程
axios.get('data.json').then(response=>(this.info=response.data));
}
computed:定义计算属性,调用的时候无须括号,有缓存功能
计算出来的结果,保存在属性中,内存中运行,虚拟Dom
计算属性的特点就是将不经常变化的结算结果进行缓存,节省开销
computed:{
currentTime2:function () {
this.message;
return Date.now();
}
}
使用 <p>{{currentTime2}}</p>
静态案例
代码语言:javascript复制<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="../lib/vue.js"></script>
<style>
a{
text-decoration: none;
}
.Fontcolor{
color: salmon;
}
.hAlign{
text-align: center;
}
td{
text-align: center;
}
</style>
</head>
<body>
<!--
案例:搭建学生管理系统
student
id name age gender
添加、删除按钮
-->
<div id="app">
<h3 :class="hstyle">学生信息管理系统</h3>
<hr width="100%">
<br/>
<!-- A001 -->
编号:<input type="text" v-model="id" /><br/>
姓名:<input type="text" v-model="name"/><br/>
年龄:<input type="text" v-model="age"/><br/>
性别:<input type="text" v-model="gender"/><br/>
<input type="button" value="保存学员" @click="save" /><br/>
<!-- 搜索的方式可以通过触发按钮,也可以通过如下方式 在触发敲键盘之后就搜索 -->
<input type="text" v-model="sname" @keyup="search" />
<input type="button" value="搜索学员" @click="search" />
<table border="1" width="100%" align="center" cellpadding="5px" cellspacing="0">
<tr>
<td>序号</td>
<td>编号</td>
<td>姓名</td>
<td>年龄</td>
<td>性别</td>
<td>操作</td> <!-- 为删除超链接提供入口-->
</tr>
<tr v-for="(student,i) in sList" :key="student.id">
<td>{{i 1}}</td>
<td>{{student.id}}</td>
<td>{{student.name}}</td>
<td>{{student.age}}</td>
<td>{{student.gender}}</td>
<!-- javascript:void(0) 禁用href行为,只能以绑定事件的行为触发行为 -->
<!-- 根据id来删除 -->
<td><a href="javascript:void(0)" @click="del(student.id)">删除</td>
</tr>
</table>
</div>
</body>
</html>
<script>
var vm = new Vue({
el:'#app',
data:{
sList:[
{id:"A001",name:"张三",age:23,gender:"男"},
{id:"A002",name:"李四",age:15,gender:"女"},
{id:"A003",name:"王五",age:28,gender:"男"},
{id:"A004",name:"六二",age:20,gender:"女"},
{id:"A005",name:"老王",age:19,gender:"男"},
{id:"A006",name:"小哥",age:26,gender:"男"},
{id:"A007",name:"小哥哥",age:26,gender:"男"},
{id:"A008",name:"李二牛",age:26,gender:"男"},
{id:"A009",name:"张三丰",age:26,gender:"男"}
],
serachList:[
{id:"A001",name:"张三",age:23,gender:"男"},
{id:"A002",name:"李四",age:15,gender:"女"},
{id:"A003",name:"王五",age:28,gender:"男"},
{id:"A004",name:"六二",age:20,gender:"女"},
{id:"A005",name:"老王",age:19,gender:"男"},
{id:"A006",name:"小哥",age:26,gender:"男"},
{id:"A007",name:"小哥哥",age:26,gender:"男"},
{id:"A008",name:"李二牛",age:26,gender:"男"},
{id:"A009",name:"张三丰",age:26,gender:"男"}
],
id:'',
name:'',
age:'',
gender:'',
sname:'',
hstyle:{Fontcolor:true,hAlign:true}
},
methods:{
save(){
var s ={id:this.id,name:this.name,age:this.age,gender:this.gender};
console.log(s);
this.sList.push(s);
},
del(id){
//需要删除记录的id,
// alert(id);
//遍历sList中所有对象,从每一对象中获取id,将每一个id与参数进行比较
//如果id值相等,证明找到了我们要删除的记录,将记录从sList删除
for(var i=0;i<this.sList.length;i ){
if(this.sList[i].id==id){
this.sList.splice(i,1);
}
}
},
search(){
//将sList备份一份searchList
//将sList清空掉(等到搜索出来的对象),对sList进行重新装配的过程
//遍历searchList 如果名字中,包含关键字,则证明对象搜索到了
//将对象装配到sList中,最终展现的是最新搜索的sList
//注意,使用其他数组是不能展现信息的,v-for写好了。需要遍历的就是sList
//用来遍历对象信息用的
//serachList=this.sList;
//用来装配新对象用的
this.sList=[];
for(var i=0;i<this.serachList.length;i ){
//使用indexOf方法判断,如果>=0,说明名称是有效的搜索项
if(this.serachList[i].name.indexOf(this.sname)>=0){
//将搜索到的对象重新装配到sList中
this.sList.push(this.serachList[i]);
}
}
}
}
})
</script>
样式
代码语言:javascript复制使用class样式
<style>
.style1{
color: red;
}
.style2{
font-size: 50px;
}
.style3{
background-color: aquamarine;
}
</style>
代码语言:javascript复制传递一个class样式的数组,通过v-bind样式绑定
方式1
:class="[样式1,样式2]" 与传统使用样式基本一致
例如: <span :class="['style1','style2']">Hello,My World!</span><br/>
方式2
三元运算符操作数组 ? : (boolean?true执行:false执行)
例如:<span :class="['style3', flag?'style1':'']">Hello,My World!</span>
方式3
使用对象(json)来表达三元运算符 {样式:flag} 使用多
<span :class="['style3',{'style2':flag}]">Hello,My World!</span>
方式4
以对象引用样式 :class="{}"
<span :class="{'style1':true,'style2':false}">Hello,My World!</span>
方式5 建议使用
直接M模型的形式做样式渲染(必须直接将具体的boolean值赋值,不能以this.模型的形式来引用)
<span :class="myStyle">Hello,My World!</span>
代码语言:javascript复制<script>
var vm = new Vue({
el:'#app',
data:{
flag:true,
myStyle:{'style1':true,'style2':true},
myStyle1:{color:'blue','font-size':'50px'},
myStyle2:{'background-color':'red','font-style':'italic'}
}
})
</script>
style样式补充
style属性,仅仅只是对个别指定样式的一个补充,使用的很少
代码语言:javascript复制方式1:引用样式对象
<span :style="myStyle1">Hello</span>
方式2:引用样式对象数组
:style="[样式对象引用1,样式对象引用2]"
<span :style="[myStyle1,myStyle2]">Hello</span>
vue-cli
代码语言:javascript复制前置:需要安装node.js和vue-cli
安装Node.js淘宝镜像加速器(cnpm) -g 全局变量
npm install cnpm -g
安装 -g 代表全局安装
npm install -g vue-cli
验证node
node -v
npm -version
设置镜像
npm config set registry https://registry.npm.taobao.org
验证镜像
npm config get registry
配置npm下载依赖位置
查看下载的位置
npm config ls
修改配置(先下载一个全局缓存,在下载全局位置)
npm config set cache "F:environmentnpm_repositorynpm_cache"
npm config set prefix "F:environmentnpm_repositorynpm_global"
C:UsersAdministrator 的 .npmrc 可以看到配置
检查,验证,nodejs环境
npm config ls
vue-cli通过命令方式下载相关依赖,类似月java的maven
例如:
安装element-ui
npm i element-ui -s
安装SASS加载器
cnpm install sass-loader node-sass --save-dev
代码语言:javascript复制通过命令行创建项目
vue init webpack 项目名
运行
npm start (或npm run dev 均可)
停止的话:Ctrl C
修改默认启动端口
config下index.js 第17行 port:8080
打包和部署,在项目根路径下执行
npm run build 会出现一个
注意:vue脚手架必须在服务器(Tomcat之类的)运行,不能直接双击运行
打包后,当前项目的变化
项目中出现dist目录,就是vue脚手架就是直接部署目录
运行下拉下来的vue脚手架项目
第一步:安装依赖
npm install
第二步:启动(在package.json的上级目录)
npm run dev
代码语言:javascript复制标签和配置
vue-cli里一切皆组件
最需要注意的
asserts下面放的是静态文件
components 里面是自己写的组件
router的index.js里面配置路由信息
App.vue 项目中根文件
main.js项目中主入口
页面跳转(a标签和router-link的区别就是a标签必须写#号)
<a href="#/home">主页模块</a>
<router-link to="/student"> 学生模块</router-link>
<!--用来展示路由组件-->
<router-view/>
后面就是定义组件,注册路由即可
不注册路由的话,页面引入组件也行
import Footer from "./Footer";
components:{
Footer, // 组成组件
}
去掉地址栏的#号(在router下的index.js加入这一句即可)
mode: 'history',
详细:
代码语言:javascript复制import Vue from 'vue'
import Router from 'vue-router'
import Main from "../components/Main";
import Student from "../components/Student";
Vue.use(Router)
export default new Router({
mode: 'history',
routes: [
{
path: '/',
redirect: '/main'
},
{
path: '/main',
name: 'Main',
component: Main
},{
path: '/student',
name: 'Student',
component: Student
}
]
})
代码语言:javascript复制路由
// 重定向,当访问项目根路径的时候执行
{
path: '/',
redirect: '/home'
},
{
path: '/home',
name: 'Home',
component: Home
},
{
path: '/user',
name: 'User',
component: User,
children:[ // 子路由 也称为嵌套路由
{
path: 'add',
component: UserAdd // 用户添加路由
},{
path: 'edit',
component: UserEdit
}
]
}
代码语言:javascript复制参数传递和重定向
Main.vue
<router-link :to="{ name: 'UserProfile',params:{id: 1}}">个人信息</router-link>
profile.vue
<template>
<div>
<h1>个人信息</h1>
{{ id }}
</div>
</template>
<script>
export default {
props:['id'],
name: "UserProfile"
}
</script>
index.js
export default new Router({
routes: [
{
path: '/main',
component: Main, //嵌套路由
children: [
{
path: '/user/profile/:id',
name:'UserProfile',
component:UserProfile,
props:true},
{path: '/user/list',component:UserList}
]
},
{
path: '/login',
component: Login,
},
{
path: '/goHome',
redirect: '/main'
}
]
});
代码语言:javascript复制配置404页面
创建NotFound页面
<template>
<div>
<h2>404 你的页面走丢了。。。</h2>
</div>
</template>
<script>
export default {
name: "NotFound"
}
</script>
<style scoped>
</style>
配置路由
{
path: '*',
component:NotFound
}
代码语言:javascript复制钩子函数
//过滤器 在进入路由前执行 钩子函数
beforeRouteEnter:(to,from,next)=>{
console.log("进入路由之前……");
next();
},
//在进入路由后执行
beforeRouteLeave:(to,from,next)=>{
console.log("进入路由之后……");
next();
}
代码语言:javascript复制vue-cli目录结构如下
创建第一个项目hello,项目结构如下
hello ------------------------>项目名
build ------------------------>用来使用webpack打包使用build依赖
config ------------------------>用来做整个项目的配置目录
node_modules ------------------->管理项目中使用的依赖
src ------------------------>写vue代码【重点】
assets -------------------->存放静态资源文件【重点】
components------------------>写vue组件【重点】
router --------------------->用来配项目的路由【重点】
App.vue -------------------->项目中根文件【重点】
main.js -------------------->项目中主入口【重点】
static ------------------------>其他静态
.babelrc -------------------->将es6语法转为es5运行
.editorconfig------------------->项目编辑配置
.gitignore---------------------->git版本控制 忽略文件
.postcssrc.js------------------->使用源码相关js
index.html---------------------->项目主页
package.json-------------------->类似于pom文件,依赖管理
package-lock.json--------------->对package.json加锁
README.md----------------------->项目说明文件
后缀是 .vue 的文件组成
代码语言:javascript复制类似以前的html、CSS、JavaScript
<template>
<div>
<table border="1">
<tr>
<td>id</td>
<td>name</td>
<td>age</td>
<td>操作</td>
</tr>
<tr v-for="stu in students">
<td>{{stu.id}}</td>
<td>{{stu.name}}</td>
<td>{{stu.age}}</td>
<td><a href="javascript:;">修改</a> | <a href="javascript:void(0)">删除</a></td>
</tr>
</table>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: "Student",
data(){
return{
students:[]
}
},
methods:{
selectAll(){
this.$http.get("http://localhost:8088/studet/listAll").then(res=>{
this.students=res.data.data;
})
}
},created() {
this.selectAll();
}
}
</script>
<style scoped>
</style>
代码语言:javascript复制axios
安装
npm install axios --save-dev
配置 main.js引入
import axios from "axios";
//修改内部的$http为axios $http 是vue内部的异步 $http.get("") $http.post("")
Vue.prototype.$http=axios;
使用axios,在需要发送异步请求的位置:
this.$http.get("url").then((res)=>{})
待-------------------------------------------------------------测
全局配置baseURL(后面如果接口base改了,可直接修改),baseURL 将自动加在url前面,除非url是绝对路径
Vue.prototype.$http.default.baseURL=''
使用
_this.$http.post(url)
.then(function(res){
})
.cache(function(e){
})
另一种使用方式
安装
cnpm install axios -s
引用
import axios from 'axios';
import VueAxios from 'vue-axios';
Vue.use(VueAxios,axios);
使用
methods:{
getData: function () {
this.axios({
method: 'get',
url: 'http://localhost:8080/static/mock/data.json'
}).then(function (response) {
console.log(response);
})
}
}
在其他地方调用 vm.getData();
四、element UI
总结:
注意:在element UI中所有的组件都存在 属性、事件、方法
- 属性 直接写在对应的组件标签上 使用方式 属性名=属性值
- 事件 直接使用vue绑定事件方式写在对应的组件标签上 使用方式 @事件名=vue中事件处理函数
- 方法
- 1、在对应组件标签上使用 ref=组件别名
- 2、通过使用this.$refs.组件别名.方法名()进行调用
记录:
获取路由传参id:
this.$route.params.id
路由传参:
this.$router.push('updAuth/' id)
缓存中取数据
let info = JSON.parse(localStorage.getItem('user'));
前端分页默认传参:
page = page ? page : this.pageNow;
size = size ? size : this.size;
1、安装
代码语言:javascript复制vue init webpack element(项目名)
1、下载elementui的依赖
npm i element-ui -S
2、指定当前项目中使用element UI
去main.js配置(src下),进行全局注册
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
// 在vue脚手架里面使用element UI
Vue.use(ElementUI);
启动
npm strat 或者 npm run dev
2、配置
代码语言:javascript复制 mode:'history', # 去掉地址栏的引号
首页的页面跳转
<div id="app">
<a href="/button">点我显示Button</a>
<router-link to="/">返回首页</router-link>
<router-view/>
</div>
element ui 所有组件都是el组件名的形式
3、按钮组件
代码语言:javascript复制显示在一行
<el-row>
<el-button type="danger" round>危险按钮</el-button>
<el-button type="warning" round>警告按钮</el-button>
</el-row>
按钮组
<el-button-group>
<el-button type="primary" icon="el-icon-arrow-left">上一页</el-button>
<el-button type="primary">下一页<i class="el-icon-arrow-right el-icon--right"></i></el-button>
</el-button-group>
4、文字链接
代码语言:javascript复制就类似于原来的a标签超级链接
el-link
target="_blank" 打开新的标签页
href="/link" 地址
:underline="false" 鼠标悬浮无下划线
<el-link href="https://element.eleme.io" target="_blank">默认链接</el-link>
<el-link :underline="false" type="warning" icon="el-icon-edit">警告链接</el-link>
<el-link>查看<i class="el-icon-view el-icon--right"></i> </el-link>
5、layout布局
代码语言:javascript复制通过基础的 24 分栏,迅速简便地创建布局。
在element UI中布局组件将页面划分为多个行row,每行最多分为24栏(列)
bootstrap每行最多12栏
el-row和el-col 行和列
一个布局是由行和列组成的,row属性和col属性
为什么分成24份?
相对于更好的计数,2 3 4 6都行
<el-row>
<el-col :span="8">占用8份</el-col>
</el-row>
:span 用在列上,占几份
:offset 偏移,偏移几份,会导致下一列移动,浮动 margin
:push 向右偏移,仅浮动
<el-row tag="span"> 行,默认渲染出来是div,使用tag属性可以更改
:gutter="50" 之间的间隔,栅格间隔
6、container布局容器
代码语言:javascript复制<el-header>:顶栏容器。
<el-aside>:侧边栏容器。
<el-main>:主要区域容器。
<el-footer>:底栏容器。
容器的嵌套使用
<el-container>
<el-header>Header</el-header>
<el-container>
<el-aside width="200px">Aside</el-aside>
<el-main>Main</el-main>
</el-container>
</el-container>
样式
.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: 200px;
}
body > .el-container {
margin-bottom: 40px;
}
7、Form相关组件
1、radio 总结:
- 在使用radio单选按钮时至少加入v-model和label俩个属性
- 属性使用还是直接写在对应的组件标签上 属性名=属性值
- 事件的使用也是和属性使用一致,直接写在对应的组件标签上
- 事件在使用时必须使用Vue绑定事件的方式进行使用 如 @事件名=事件处理函数(绑定在vue组件中的)
创建按钮
<el-radio v-model="radio" label="1">备选项</el-radio>
<el-radio v-model="radio" label="2">备选项</el-radio>
radio:'1'
v-model="radio" label="1" 成对使用
属性的使用
v-model 绑定值
lable radio的value
disabled 禁用
border 加了边框
size 按钮尺寸 mediun small mini
name 源生name属性
事件
change 绑定值变化时触发
事件的使用:
<el-radio v-model="radio" @change="aa" label="男">男</el-radio>
<el-radio v-model="radio" @change="aa" label="女">女</el-radio>
aa(){
alert("值变化了 " this.radio)
}
2、CheckBox
代码语言:javascript复制创建
<el-checkbox v-model="checked">11</el-checkbox>
复选框组
<el-checkbox-group v-model="checkList">
<el-checkbox label="复选框 A"></el-checkbox>
<el-checkbox label="复选框 B"></el-checkbox>
<el-checkbox label="复选框 C"></el-checkbox>
<el-checkbox label="禁用" disabled></el-checkbox>
<el-checkbox label="选中且禁用" disabled></el-checkbox>
</el-checkbox-group>
checkList: ['选中且禁用','复选框 A']
3、input
代码语言:javascript复制 <el-input v-model="input" placeholder="请输入内容"></el-input>
input: '',
方法
<el-input v-model="input" ref="inputs" clearable placeholder="请输入内容" size="mini"></el-input>
<el-button @click="getInputs">获取focus</el-button>
getInputs(){
this.$refs.inputs.focus();
}
上面定义 ref="inputs"
这样的形式 this.$refs.inputs.focus();
4、select
代码语言:javascript复制 动态获取数据
:key="item.value"
:label="item.label" 选项的标签,不设置默认与value相同
:value="item.value" 选项的值,一般可以放id
<el-select v-model="value" placeholder="请选择">
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
options: [{
value: '选项1',
label: '黄金糕'
}, {
value: '选项2',
label: '双皮奶'
}, {
value: '选项3',
label: '蚵仔煎'
}, {
value: '选项4',
label: '龙须面'
}, {
value: '选项5',
label: '北京烤鸭'
}],
value: ''
获取下拉列表选中的值
v-model="value"
可清除
clearable
启动多选
multiple
5、switch
代码语言:javascript复制 <el-switch v-model="flag" active-color="#13ce66"
inactive-color="red" active-text="打开"
inactive-text="关闭">
</el-switch>
flag:true,
v-model="flag" 控制打开关闭的状态
active-color="#13ce66" 默认选中时的颜色,激活颜色
inactive-color="red" 在点一下,关闭后的颜色
active-text="打开" 打开状态的文字,右侧
inactive-text="关闭" 关闭状态的文字,左侧
6、DatePicker组件
代码语言:javascript复制<el-date-picker v-model="newDate" type="date" placeholder="选择日期">
</el-date-picker>
newDate:'',
type 显示类型
year/month/date/dates/ week/datetime/datetimerange/ daterange/monthrange
使用日期配置
:picker-options="pickerOptions"
Shortcuts 是用来增加日期组件的快捷面板
Picker Options 用来对日期控件做自定义配置
<div class="block">
<span class="demonstration">默认</span>
<el-date-picker
v-model="value1"
type="date"
placeholder="选择日期">
</el-date-picker>
</div>
<div class="block">
<span class="demonstration">带快捷选项</span>
<el-date-picker
v-model="value2"
align="right"
type="date"
placeholder="选择日期"
:picker-options="pickerOptions" @change="bbb">
</el-date-picker>
</div>
<script>
export default {
name: "DataPickerDetail",
data() {
return {
pickerOptions: {
disabledDate(time) { // 对日期进行的控制
return time.getTime() > Date.now();
},
shortcuts: [{
text: '今天',
onClick(picker) {
picker.$emit('pick', new Date());
}
}, {
text: '昨天',
onClick(picker) {
const date = new Date();
date.setTime(date.getTime() - 3600 * 1000 * 24);
picker.$emit('pick', date);
}
}, {
text: '一周前',
onClick(picker) {
const date = new Date();
date.setTime(date.getTime() - 3600 * 1000 * 24 * 7);
picker.$emit('pick', date);
}
}]
},
value1: '',
value2: '',
};
}
},
methods:{
bbb(value){ // 发生change事件
console.log(value);
}
}
</script> }
代码解读
disabledDate(time) {
return time.getTime() > Date.now();
}
时间大于现在的时间被禁用了,所以只能选择以前的时间
7、Form表单
代码语言:javascript复制最外成使用el-form
<el-form ref="form" :model="form" label-width="80px">
每一行的标签使用el-form-item,表单元素正常使用
<el-form-item label="活动名称">
<el-input v-model="form.name"></el-input>
</el-form-item>
:inline="true" 行内表单样式
label-position 设置对其方式 right/left/top 默认right
label-suffix 表单域标签的后缀
rules 表单验证规则:rules="rules",表单属性上面加prop属性
示例
<el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">
<el-form-item label="活动名称" prop="name">
<el-input v-model="ruleForm.name"></el-input>
</el-form-item>
<el-form-item label="活动区域" prop="region">
<el-select v-model="ruleForm.region" placeholder="请选择活动区域">
<el-option label="区域一" value="shanghai"></el-option>
<el-option label="区域二" value="beijing"></el-option>
</el-select>
</el-form-item>
<el-form-item label="活动时间" required>
<el-col :span="11">
<el-form-item prop="date1">
<el-date-picker type="date" placeholder="选择日期" v-model="ruleForm.date1" style="width: 100%;"></el-date-picker>
</el-form-item>
</el-col>
<el-col class="line" :span="2">-</el-col>
<el-col :span="11">
<el-form-item prop="date2">
<el-time-picker placeholder="选择时间" v-model="ruleForm.date2" style="width: 100%;"></el-time-picker>
</el-form-item>
</el-col>
</el-form-item>
<el-form-item label="即时配送" prop="delivery">
<el-switch v-model="ruleForm.delivery"></el-switch>
</el-form-item>
<el-form-item label="活动性质" prop="type">
<el-checkbox-group v-model="ruleForm.type">
<el-checkbox label="美食/餐厅线上活动" name="type"></el-checkbox>
<el-checkbox label="地推活动" name="type"></el-checkbox>
<el-checkbox label="线下主题活动" name="type"></el-checkbox>
<el-checkbox label="单纯品牌曝光" name="type"></el-checkbox>
</el-checkbox-group>
</el-form-item>
<el-form-item label="特殊资源" prop="resource">
<el-radio-group v-model="ruleForm.resource">
<el-radio label="线上品牌商赞助"></el-radio>
<el-radio label="线下场地免费"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="活动形式" prop="desc">
<el-input type="textarea" v-model="ruleForm.desc"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm('ruleForm')">立即创建</el-button>
<el-button @click="resetForm('ruleForm')">重置</el-button>
</el-form-item>
</el-form>
<script>
export default {
data() {
return {
ruleForm: {
name: '',
region: '',
date1: '',
date2: '',
delivery: false,
type: [],
resource: '',
desc: ''
},
rules: {
name: [
{ required: true, message: '请输入活动名称', trigger: 'blur' },
{ min: 3, max: 5, message: '长度在 3 到 5 个字符', trigger: 'blur' }
],
region: [
{ required: true, message: '请选择活动区域', trigger: 'change' }
],
date1: [
{ type: 'date', required: true, message: '请选择日期', trigger: 'change' }
],
date2: [
{ type: 'date', required: true, message: '请选择时间', trigger: 'change' }
],
type: [
{ type: 'array', required: true, message: '请至少选择一个活动性质', trigger: 'change' }
],
resource: [
{ required: true, message: '请选择活动资源', trigger: 'change' }
],
desc: [
{ required: true, message: '请填写活动形式', trigger: 'blur' }
]
}
};
},
methods: {
submitForm(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
alert('submit!');
} else {
console.log('error submit!!');
return false;
}
});
},
resetForm(formName) {
this.$refs[formName].resetFields();
}
}
}
</script>
8、Upload组件
代码语言:javascript复制<el-upload action="https://jsonplaceholder.typicode.com/posts/">
<el-button type="primary">上传图片</el-button>
<div slot="tip" class="el-upload__tip">只能上传jpg/png图片</div>
</el-upload>
在使用upload组件时,必须设置action属性
<script>
export default {
name: "UploadDetail",
data() {
return {
fileList: [{
name: 'food.jpeg',
url: 'https://img.yuanmabao.com/zijie/pic/2023/10/17/jsydehtvk3l.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100'
}, {
name: 'food2.jpeg',
url: 'https://img.yuanmabao.com/zijie/pic/2023/10/17/jsydehtvk3l.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100'
}]
};
},
methods: {
handleRemove(file, fileList) {
console.log(file, fileList);
},
handlePreview(file) {
console.log(file);
}
}
}
</script>
拖拽上传
<el-upload
class="upload-demo"
drag
action="https://jsonplaceholder.typicode.com/posts/"
multiple>
<i class="el-icon-upload"></i>
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
<div class="el-upload__tip" slot="tip">只能上传jpg/png文件,且不超过500kb</div>
</el-upload>
方法的使用
方法名 说明 参数
clearFiles 清空已上传的文件列表(该方法不支持在 before-upload 中调用) —
abort 取消上传请求 ( file: fileList 中的 file 对象 )
submit 手动上传文件列表
9、消息组件
alert消息组件
代码语言:javascript复制 <el-alert
title="成功提示的文案"
type="success"
effect="dark">
</el-alert>
Alert 组件提供四种主题,由type属性指定,默认值为info。
success、info、warning、error
通过设置effect属性来改变主题,默认为light。
light和dark。明亮和黑暗
在 Alert 组件中,你可以设置是否可关闭,关闭按钮的文本以及关闭时的回调函数。closable属性决定是否可关闭,接受boolean,默认为true。你可以设置close-text属性来代替右侧的关闭图标,注意:close-text必须为文本。设置close事件来设置关闭时的回调。
close-text="关闭" 右侧的的x就变为了关闭
:closable="false" 不可以关闭
@close="hello" 定义hello函数,设置回调
通过设置show-icon属性来显示 Alert 的 icon,这能更有效地向用户展示你的显示意图。
直接加 show-icon
文字居中center
除了必填的title属性外,你可以设置description属性来帮助你更好地介绍,我们称之为辅助性文字。辅助性文字只能存放单行文本,会自动换行显示。
message组件
注意:这个组件的创建无需在页面中书写任何标签,是一个js插件,在需要展示消息提示的位置直接调用提供的js插件方法即可。
代码语言:javascript复制它是js插件,无需指定的标签。
打开消息提示
this.$message('这是一条消息提示');
<el-button :plain="true" @click="open">打开消息提示</el-button>
methods: {
open() {
this.$message('这是一条消息提示');
}
}
H6 是显示的html标签的样式
span 是加粗
i 是加了一个样式
<el-button :plain="true" type="primary" @click="open2">打开消息提示2</el-button>
open2() {
const h = this.$createElement;
this.$message({
message: h('H6',null,[
h('span', null, '展示的信息可以是: '),
h('i', { style: 'color: teal' }, '张三')
])
});
}
# 不同主题的消息提示
this.$message({
message:'这是消息提示',
type:'success',
})
# 主题样式 success info warning error
# 方法的使用
this.$message.closeAll();
10、表格组件
代码语言:javascript复制表格上的属性
:data 绑定数据
border 在el-table加上,然后就有边框,可以拖动列
:fit="false" 列的宽度是否自适应,默认是true
列上的属性
sortable 可排序
resizable 对应的列上不想被拖动,即改变宽度,设为false
:formatter="showDept" 渲染数据
组价事件的使用
<el-table @事件名="函数名"></el-table>
组件方法
<el-table ref="myTable" ... > .... </el-table>
调用
this.$refs.myTable.clearSelection();
<el-table :data="tableData" ref="myTable" :fit="false" border @select="selectAll">
<el-table-column type="selection"></el-table-column>
<el-table-column prop="name" label="姓名"></el-table-column>
<el-table-column prop="age" sortable label="年龄"></el-table-column>
<el-table-column prop="dept.name" :formatter="showDept" sortable label="部门"> </el-table-column>
</el-table>
<el-button type="primary" @click="clearSelect">清空选择</el-button>
<script>
export default {
name: "TableDetail",
data(){
return {
tableData:[
{name:'张三',age:18,dept:{id:1,name:'研发部'}},
{name:'李四',age:19,dept:{id:2,name:'市场部'}},
{name:'王五',age:20,dept:{id:3,name:'运营部'}},
{name:'王五',age:20,dept:{id:3,name:''}}
]
}
},
methods:{
showDept(row, column, cellValue, index){
// 行 列 列的值 索引
console.log(row);
if(cellValue){
return cellValue;
}else{
return "暂无部门";
}
},
selectAll(selection,row){
console.log(selection);
console.log(row);
},
clearSelect(){
this.$refs.myTable.clearSelection();
}
}
// 日后这里的数据为数据库查询到的数据
created(){
this.axios.get("/findAll")
}
}
</script>
自定义表头
把操作的label删掉,下面加一个template
<template slot="header" slot-scope="scope">
<el-input
v-model="search"
size="mini"
placeholder="输入关键字搜索"/>
</template>
遍历数据的data改变一下,才可以调用到搜索
:data="tableData.filter(data => !search || data.name.toLowerCase().includes(search.toLowerCase()))"
详细使用
<el-table-column
align="right">
<template slot="header" slot-scope="scope">
<el-input
v-model="search"
size="mini"
placeholder="输入关键字搜索"/>
</template>
<template slot-scope="scope">
<el-button
size="mini"
@click="handleEdit(scope.$index, scope.row)">Edit</el-button>
<el-button
size="mini"
type="danger"
@click="handleDelete(scope.$index, scope.row)">Delete</el-button>
</template>
</el-table-column>
组件方法的使用
总结:
- 在使用组件的方法时需要在对应的组件中加入 ref=“组件别名”
- 在调用方法时直接使用this.$refs.组件别名.方法名();
<el-input v-model="input" ref="inputs" clearable placeholder="请输入内容" size="mini"></el-input>
<el-button @click="getInputs">获取focus</el-button>
调用focus方法
getInputs(){
this.$refs.inputs.focus();
}
demo
后端
实体类
代码语言:javascript复制@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
@Accessors(chain = true) // 链式调用
public class User implements Serializable {
private String id;
private String name;
@JsonFormat(pattern = "yyyy-MM-dd")
private Date bir;
private String sex;
private String address;
}
dao层
代码语言:javascript复制@Mapper
public interface UserDao {
// 查询所有用户信息
List<User> findAll();
// 保存用户信息
void save(User user);
// 更新用户信息
void update(User user);
// 根据id删除用户
void delete(String id);
// 分页查询
List<User> findByPage(@Param("start") Integer start, @Param("rows") Integer rows);
// 查询总条数
Long findTotals();
}
mapper文件
代码语言:javascript复制<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.myfdc.dao.UserDao">
<select id="findAll" resultType="User">
select id,name,bir,sex,address from t_users
</select>
<!-- 主键id 自动生成-->
<insert id="save" parameterType="User" useGeneratedKeys="true" keyProperty="id">
insert into t_users values (#{id},#{name},#{bir},#{sex},#{address})
</insert>
<!--根据id删除用户信息-->
<delete id="delete" parameterType="String">
delete from t_users where id = #{id}
</delete>
<!--根据用户信息编辑-->
<update id="update" parameterType="User">
update t_users set name = #{name}, bir=#{bir},sex=#{sex},address=#{address}
where id = #{id}
</update>
<!--分页查询-->
<select id="findByPage" resultType="User">
select id,name,bir,sex,address from t_users limit #{start},#{rows}
</select>
<!--查询总条数-->
<select id="findTotals" resultType="Long">
select count(id) from t_users
</select>
</mapper>
service层
代码语言:javascript复制public interface UserService {
List<User> findAll();
void save(User user);
// 更新用户信息
void update(User user);
// 根据id删除用户
void delete(String id);
// 分页查询
List<User> findByPage( Integer pageNow, Integer rows);
// 查询总条数
Long findTotals();
}
实现类
代码语言:javascript复制@Service
@Transactional // 控制事务
public class UserServiceImpl implements UserService {
@Resource
private UserDao userDao;
@Override
@Transactional(propagation = Propagation.SUPPORTS)
public List<User> findAll() {
return userDao.findAll();
}
@Override
public void save(User user) {
userDao.save(user);
}
@Override
public void update(User user) {
userDao.update(user);
}
@Override
public void delete(String id) {
userDao.delete(id);
}
@Override
public List<User> findByPage(Integer pageNow, Integer rows) {
int start = (pageNow-1)*rows;
return userDao.findByPage(start, rows);
}
@Override
public Long findTotals() {
return userDao.findTotals();
}
}
vo
封装结果集
代码语言:javascript复制@Data
@Accessors(chain = true) // 链式调用
public class Result {
private Boolean status = true;
private String msg;
}
controller层
代码语言:javascript复制@RestController
@RequestMapping("user")
@CrossOrigin
public class UserController {
@Autowired
private UserService userService;
@GetMapping("findAll")
public List<User> findAll(){
return userService.findAll();
}
@PostMapping("saveOrUpdate")
public Result saveOrUpdate(@RequestBody User user){
Result result = new Result();
try{
if(StringUtils.isEmpty(user.getId())){
userService.save(user);
result.setMsg("用户保存成功");
}else{
userService.update(user);
result.setMsg("用户编辑成功");
}
}catch (Exception e){
result.setStatus(false).setMsg("保存用户信息失败");
}
return result;
}
@GetMapping("delete")
public Result delete(String id){
Result result = new Result();
try{
userService.delete(id);
result.setMsg("删除用户信息成功");
}catch (Exception e){
result.setStatus(false).setMsg("删除用户信息失败,请稍后在试!");
}
return result;
}
// 分页查询方法
@GetMapping("findByPage")
public Map<String,Object> finfByPage(Integer pageNow,Integer pageSize){
Map<String,Object> result = new HashMap<>();
// 默认第一次访问的时候 可能没有传值
pageNow = pageSize==null?1:pageNow;
pageSize = pageSize==null?4:pageSize;
List<User> users = userService.findByPage(pageNow, pageSize);
Long totals = userService.findTotals();
result.put("users",users);
result.put("total",totals);
return result;
}
}
配置文件
代码语言:javascript复制server.servlet.context-path=/
server.port=8089
spring.application.name=elementUsers
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/xyxy?characterEncoding=UTF8&serverTime=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=145263
spring.web.resources.static-locations=classpath:/static/
mybatis.mapper-locations=classpath:mapper/*.xml
mybatis.type-aliases-package=com.myfdc.entity
前端
安装axios
代码语言:javascript复制安装
npm install axios --save-dev
配置 main.js引入
import axios from "axios";
//修改内部的$http为axios $http 是vue内部的异步 $http.get("") $http.post("")
Vue.prototype.$http=axios;
后面使用axios,在需要发送异步请求的位置:
this.$http.get("url").then((res)=>{})
笔记
代码语言:javascript复制// 路由切换
this.$router.push(key);
App.vue
代码语言:javascript复制<template>
<div id="app">
<el-container>
<el-header>
<!--导航菜单-->
<el-menu :default-active="activeIndex" class="el-menu-demo" mode="horizontal" @select="handleSelect">
<el-menu-item index="/index">主页</el-menu-item>
<el-menu-item index="/list">用户管理</el-menu-item>
<el-menu-item index="/msg">消息中心</el-menu-item>
<el-menu-item index="/order">订单管理</el-menu-item>
</el-menu>
</el-header>
<el-main>
<router-view/>
</el-main>
</el-container>
</div>
</template>
<script>
export default {
name: 'App',
data() {
return {
activeIndex: this.$route.path,
};
},
methods: {
handleSelect(key, keyPath) {
console.log(key, keyPath);
// 路由切换
this.$router.push(key);
}
}
}
</script>
<style>
</style>
Index.vue
代码语言:javascript复制<template>
<div>
<el-carousel indicator-position="outside" >
<el-carousel-item v-for="item in img" :key="item">
<el-image :src="item" style="height:600px;width: 100%" fit="contain"></el-image>
</el-carousel-item>
</el-carousel>
</div>
</template>
<script>
import img1 from "../assets/imgs/1.jpg";
import img2 from "../assets/imgs/2.jpg";
import img3 from "../assets/imgs/3.jpg";
import img4 from "../assets/imgs/4.jpg";
export default {
name: "Index",
data() {
return {
img:[img1,img2,img3,img4],
// activeIndex: '/index', 本来是写死的激活路径 使用 this.$route.path 就可以拿到当前的路径
activeIndex: this.$route.path,
};
},
methods: {
handleSelect(key, keyPath) {
console.log(key, keyPath);
// 路由切换
this.$route.push(key);
}
}
}
</script>
<style scoped>
</style>
路由 index.js
代码语言:javascript复制import Vue from 'vue'
import Router from 'vue-router'
import Index from "../components/Index";
import List from "../components/user/List";
import Msg from "../components/msg/Msg";
import OrderList from "../components/order/OrderList";
Vue.use(Router)
export default new Router({
mode:'history',
routes: [
{
path:'/',
redirect: '/index'
},
{
path: '/index',
name: 'index',
component: Index
},
{
path:'/list',
component: List
},
{
path:'/msg',
component: Msg
},
{
path:'/order',
component: OrderList
}
]
})
List.vue
代码语言:javascript复制<template>
<div>
<h1>显示用户列表</h1>
<el-table :height="500"
:data="tableData.filter(data => !search || data.name.toLowerCase().includes(search.toLowerCase()))"
style="width: 100%">
<el-table-column
label="编号"
width="180">
<template slot-scope="scope">
<span style="margin-left: 10px">{{ scope.row.id }}</span>
</template>
</el-table-column>
<el-table-column
label="姓名"
width="180">
<template slot-scope="scope">
<el-popover trigger="hover" placement="top">
<p>姓名: {{ scope.row.name }}</p>
<p>住址: {{ scope.row.address }}</p>
<div slot="reference" class="name-wrapper">
<el-tag size="medium">{{ scope.row.name }}</el-tag>
</div>
</el-popover>
</template>
</el-table-column>
<el-table-column label="生日" prop="bir"></el-table-column>
<el-table-column label="性别" prop="sex"></el-table-column>
<el-table-column label="地址" prop="address"></el-table-column>
<el-table-column align="center">
<template slot="header" slot-scope="scope">
<el-input
clearable
v-model="search"
size="mini"
placeholder="输入姓或名搜索"/>
</template>
<template slot-scope="scope">
<el-button
size="mini"
@click="handleEdit(scope.$index, scope.row)">编辑
</el-button>
<el-popconfirm
confirm-button-text='好的'
cancel-button-text='不用了'
icon="el-icon-info"
icon-color="red"
title="确定要删除当前用户信息吗?"
@Confirm="handleDelete(scope.$index, scope.row)">
<el-button slot="reference"
size="mini"
type="danger"
>删除
</el-button>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
<el-row>
<el-col :span="10" :offset="14">
<!--分页组件 prev, pager, next,jumper,total,sizes 上一页 分页 下一页 跳转到第几页 总条数,每页显示多少数据-->
<el-pagination
background
prev-text="上一页"
next-text="下一页"
layout="prev, pager, next,jumper,total,sizes"
:page-size="size"
:current-page="pageNow"
:page-sizes="[2,4,6,8,10]"
@current-change="findPage"
@size-change="findSize"
:total="total">
</el-pagination>
</el-col>
</el-row>
<el-button type="primary" size="small" @click="saveUserInfo">添加</el-button>
<transition name="el-zoom-in-center">
<div v-show="show" class="transition-box">
<!-- label-suffix=":" 每个字段名称后面都加上了: -->
<el-form :model="form" :rules="rules" ref="userForm" label-width="80px" label-suffix=":">
<el-form-item label="姓名" prop="name">
<el-input v-model="form.name"></el-input>
</el-form-item>
<el-form-item label="生日" prop="bir">
<el-date-picker value-format="yyyy-MM-dd" placeholder="选择日期" v-model="form.bir" style="width: 100%;"></el-date-picker>
</el-form-item>
<el-form-item label="性别">
<el-radio-group v-model="form.sex">
<el-radio label="男"></el-radio>
<el-radio label="女"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="详细地址" prop="address">
<el-input type="textarea" v-model="form.address"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit('userForm')">保存信息</el-button>
<el-button @click="saveUserInfo">重置</el-button>
</el-form-item>
</el-form>
</div>
</transition>
</div>
</template>
<script>
export default {
name: "List",
data() {
return {
show: false,
search: '',
total: 0,
pageNow: 1,
size: 4,
tableData: [],
form: {
name: '',
sex: '男',
bir: '',
address: ''
},
rules: {
name: [
{required: true, message: '请输入用户姓名', trigger: 'blur'}
],
bir: [
{required: true, message: '请输入用户生日', trigger: 'blur'}
],
address: [
{required: true, message: '请输入用户地址', trigger: 'blur'}
]
}
}
},
methods: {
// 用来处理每页显示的记录发生变化的方法
findSize(size) {
console.log(size);
// 当发生变化的时候,把变化的值修改了
this.size=size;
this.findAllUser(this.page,size);
},
// 处理分页 page 传了当前页
findPage(page) {
this.page=page;
this.findAllUser(page, this.size);
console.log(page);
},
// 点击添加按钮时 清空表单数据
saveUserInfo() {
this.show = true;
this.form = {sex: '男'};
},
handleEdit(index, row) {
console.log(index, row);
// 编辑数据的时候 和新增调用同一个表单 先将数据回显
// 显示form表单
this.show = true;
// 回填数据
this.form = row;
},
handleDelete(index, row) {
console.log(index, row);
// 发送axios请求,删除数据
this.$http.get("http://localhost:8089/user/delete?id=" row.id).then(res => {
if (res.data.status) {
this.$message({
message: res.data.msg,
type: 'success'
});
// 删除成功 刷新表格数据
this.findAllUser()
} else {
this.$message.error(res.data.msg);
}
})
},
onSubmit(userForm) {
this.$refs[userForm].validate((valid) => {
// 如果验证通过的话
if (valid) {
// 发送一个ajax请求
this.$http.post("http://localhost:8089/user/saveOrUpdate", this.form).then(res => {
console.log(res.data);
// 保存成功
if (res.data.status) {
this.$message({
message: res.data.msg,
type: 'success'
});
// 清空表单信息
this.form = {sex: '男'};
// 隐藏表单
this.show = false;
// 渲染数据
this.findAllUser()
// 保存失败
} else {
this.$message.error(res.data.msg);
}
})
} else {
this.$message.error("当前输入数据不合法!");
return false;
}
});
console.log('submit!');
},
findAllUser(page, size) {
// 如果没有值的话,初始化默认值
page = page ? page : this.pageNow;
size = size ? size : this.size;
this.$http.get("http://localhost:8089/user/findByPage?pageNow=" page "&pageSize=" size).then(res => {
this.tableData = res.data.users;
this.total = res.data.total;
})
}
},
created() {
// 初始化数据
this.findAllUser()
}
}
</script>
<style scoped>
.transition-box {
margin-bottom: 10px;
width: 100%;
height: 500px;
border-radius: 4px;
padding: 40px 20px;
box-sizing: border-box;
margin-right: 20px;
}
</style>
小结
代码语言:javascript复制打包部署
npm run build
本地会出现一个dist文件夹(static文件夹和index.html)
复制到后端static文件夹下即可
配置静态资源文件的位置
spring.web.resources.static-locations=classpath:/static/
这样就无需启动前端,增删改查所有功能正常,前后端分离的部署
五、echarts
1、vue安装echarts
代码语言:javascript复制关键:
// 基于准备好的dom,初始化echarts实例
let myChart = this.$echarts.init(document.getElementById('myChart'))
代码语言:javascript复制1、下载依赖
npm install echarts -S
npm install echarts --save
2、main.js引入
// 引入echarts
import * as echarts from 'echarts';
Vue.prototype.$echarts = echarts
3、使用 在Echarts.vue中 示例:
<div id="myChart" :style="{width: '500px', height: '300px'}"></div>
export default {
name: 'hello',
data () {
return {
msg: 'Welcome to Your Vue.js App'
}
},
mounted(){
this.drawLine();
},
methods: {
drawLine(){
// 基于准备好的dom,初始化echarts实例
let myChart = this.$echarts.init(document.getElementById('myChart'))
// 绘制图表
myChart.setOption({
title: { text: '在Vue中使用echarts' },
tooltip: {},
xAxis: {
data: ["衬衫","羊毛衫","雪纺衫","裤子","高跟鞋","袜子"]
},
yAxis: {},
series: [{
name: '销量',
type: 'bar',
data: [5, 20, 36, 10, 10, 20]
}]
});
}
}
}
六、bootstrap
代码语言:javascript复制按钮样式
btn-primary //主要按钮
btn-secondary //次要按钮
btn-success //成功按钮
btn-info //信息按钮
btn-danger //危险
btn-outline-primary //按钮边框
btn-sm btn-lg //小大号按钮
btn-block //块级按钮
active //可用
disabled //禁用
bootstrap每行最多12栏
七、semantic UI
样式
代码语言:javascript复制class="ui inverted segment" ui 代表ui组件
inverted 颜色反转
segment 片段,白色边框
mini 小
attached 无圆角,上下俩个div,attached,连起来,无缝隙,
vertical 垂直,无圆角
center aligned 居中(代表水平方向)
centered 居中放置
middle aligned 垂直方向居中
right alighed 靠右
two column 两列布局
grid grid 把一行分为16份 bootstrap 分为12份
three wide column 代表占满3份
div.ui.inverted.section.divider 分割线
例如: <div class="ui horizontal divider header">扫码</div>
container 响应式布局,根据屏幕最好的效果
fluid 填充外层容器
颜色:
baisc 不那么明显,只留下边框和文字的颜色
inverted 黑色,反转
teal 蓝色
transparent 透明色
ui secondary segment 灰色
样式:
left pointing 小三角
<div class="ui pagination menu"> 分页
<a class=" item">上一页2</a>
<a class=" item">下一页2</a>
</div>
multiple 可多选
search 可搜索
图标
i.home.icon 即 <i class="home icon"></i>
适配移动端
代码语言:javascript复制导航:加 stackable 代表可堆叠
实例: <div class="ui inverted secondary stackable menu">
图片在上,文字在下: mobile reversed 反转
<div class="ui mobile reversed stackable grid">
底部:stackable
<div class="ui inverted divided stackable grid">
八、页面插件集成
1、集成Markdown
代码语言:javascript复制地址
https://pandao.github.io/editor.md/
使用案例,其实可以在官网直接查看
<!-- 引入Markdown的CSS文件,最下面在引入js文件 -->
<link rel="stylesheet" href="../static/lib/editormd/css/editormd.min.css">
<!-- 内容 -->
<div class="field">
<!-- style="z-index: 1 !important;" 修复全屏显示的问题 -->
<div id="md-content" style="z-index: 1 !important;">
<!-- 后期替换Markdown编辑器 -->
<textarea placeholder="博客内容" name="content" style="display: none">
@[toc]
#### Disabled options
- TeX (Based on KaTeX);
- Emoji;
- Task lists;
- HTML tags decode;
- Flowchart and Sequence Diagram;
</textarea>
</div>
</div>
<!-- 引入Markdown的js文件 -->
<script src="../static/lib/editormd/editormd.min.js"></script>
<script>
// 初始化Markdown
var contentEditor;
$(function() {
contentEditor = editormd("md-content", {
width : "100%",
height : 640,
syncScrolling : "single",
path : "../static/lib/editormd/lib/"
});
});
</script>