官网:https://cn.vuejs.org
入门文档:https://cn.vuejs.org/v2/guide/
目标
什么是vuejs以及如何下载和安装Vuejs。
概述
Vue.js是一个轻巧、高性能、可组件化的MVVM库,同时拥有非常容易上手的API;
Vue.js是一个构建数据驱动的Web界面的库。
Vue.js是一套构建用户界面的 渐进式框架。与其他重量级框架不同的是,Vue 采用自底向上增量开发的设计。Vue 的核心库只关注视图层,并且非常容易学习,非常容易与其它库或已有项目整合。另一方面,Vue 完全有能力驱动采用单文件组件和 Vue 生态系统支持的库开发的复杂单页应用。数据驱动+组件化的前端开发。
简而言之:Vue.js是一个构建数据驱动的 web 界面的渐进式框架。Vue.js 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。核心是一个响应的数据绑定系统。
尤雨溪,Vue.js 创作者,Vue Technology创始人,致力于Vue的研究开发。vue3.x / vue2.x
关于什么是MVVM模式:
基于传统的数据渲染
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Documenttitle>
head>
<body>
<div id="app">
div>
<script src="js/jquery.min.js">script>
<script>
// 入口函数调用方法进行初始化
$(function () {
// 执行初始化
IcodingCart.loadData();
})
var IcodingCart = {
loadData:function(){
// 1:这里数据
var userData = [{
id:"1",
name:"zhangsan",
age:32
},{
id:"2",
name:"lisi",
age:32
}];
// 2:拼接开始
var html = "";
//开始遍历数据
for(var i=0;i<userData.length;i++){
var user = userData[i];
html +=" \n"
+
" id:" +user.id+"\n" +
" name:" +user.name+"\n" +
" age:" +user.age+"\n" +
" ";
}
//:3:找到目标元素
$("#app").html(html);
}
};
script>
body>
html>
传统模式问题:
1:数据和视图融合在一起。出现的问题:
1. 下载安装
下载地址:https://github.com/vuejs/vue
可以下载2.6.10版本https://github.com/vuejs/vue/archive/v2.6.10.zip
下载解压,在dist
可得到vue.js文件。
2. npm安装(推荐)
在idea的左下角,有个Terminal按钮,点击打开控制台:
安装Vue,输入命令:
# save 的意思是将模块安装到项目目录下,并在package文件的dependencies节点写入依赖
npm install vue
npm install [email protected]
步骤
1、引入vue.js文件
2、定义Vuejs对象和数据
3、定义dom
4、定义视图渲染数据
小结
1: el:代表vuejs从哪个dom开始进行管辖,一旦被el定义,那么会把当前dom中的视图(dom)中存在的指令或者插值表达式
通通进行数据的渲染。
2: 而数据的来源必须一定要在data中进行定义,也就是告诉只要在el管辖的范围内需要的数据必须要data中定义,否则无效。
注意事项:
1:注意点:el :#app 必须用id,可以用class吗。不推荐
2:注意点:Vue首字母必须是大写。
语法
- 该表达式支持JS语法,可以调用js内置函数(必须有返回值)
- 表达式必须有返回结果。例如 1 + 1,没有结果的表达式不允许使用,如:var a = 1 + 1;
- 可以直接获取Vue实例中定义的数据或函数
代码
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Documenttitle>
head>
<body >
<div id="app">
<p>{{username}}p>
<p> {{age}}p>
<p>{{password}}p>
<hr>
<p>{{price + num}}p>
<p>{{price - num}}p>
<p>{{price * num}}p>
<p>{{price / num}}p>
<p>{{price % num}}p>
<hr>
<p>{{male==0?"女":"男"}}p>
<hr>
{{user.id}}
{{user.name}}
div>
<script src="js/vue.min.js">script>
<script>
var vue = new Vue({
el:"#app",
data:{
username:"张三",
age:"2",
password:"3",
price:12.1,
num:11,
male:0,
user:{id:1,name:"zhangsan"}
}
})
script>
body>
html>
插值闪烁(了解)
使用{{}}方式在网速较慢时会出现问题。在数据未加载完成时,页面会显示出原始的{{}}
,加载完毕后才显示正确数据,称为插值闪烁。类似如下的效果(最新vue是几乎没有此问题):或者使用v-cloak结合解决。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-V6vtkFl2-1595410166838)(assets/4-1567578304269.gif)]
目标:
学习和了解vuejs的生命周期和this上下文对象。
概述:
每个 Vue 实例在被创建时都要经过一系列的初始化过程 :创建实例,装载模板,渲染模板等。Vue为生命周期中的每个状态都设置了钩子函数(监听函数)。每当Vue实例处于不同的生命周期时,对应的函数就会被触发调用。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AoEK7nKk-1595410166839)(assets/lifecycle.png)]
例如:created代表在vue实例创建后;
可以在Vue中定义一个created函数,代表这个时期的构造函数:
<html>
<head>
<meta charset="utf-8" />
<title>生命周期title>
head>
<body>
<div id="app">{{message}}div>
<script src="js/vue.js">script>
<script>
//vm
var vm = new Vue({
el : "#app",
data : {
message : 'hello world'
},
beforeCreate : function() {
console.log(this);
showData('1:创建vue实例前-beforeCreate', this);
},
created : function() {
// 如果你要想获取数据必须在这里定义你要获取的业务。
showData('2:创建vue实例后-created', this);
},
beforeMount : function() {
showData('3:挂载到dom前-beforeMount', this);
},
mounted : function() {
//$(function(){})
showData('4:挂载到dom后-mounted', this);
},
beforeUpdate : function() {
showData('5:数据变化更新前-beforeUpdate', this);
},
updated : function() {
showData('6:数据变化更新后-updated', this);
},
beforeDestroy : function() {
vm.test = "3333";
showData('7:vue实例销毁前-beforeDestroy', this);
},
destroyed : function() {
showData('8:vue实例销毁后-destroyed', this);
}
});
function realDom() {
console.log('真实dom结构:' + document.getElementById('app').innerHTML);
}
function showData(process, obj) {
console.log(process);
console.log('data 数据:' + obj.message)
console.log('挂载的对象:')
console.log(obj.$el)
realDom();
console.log('------------------')
console.log('------------------')
}
//vm.message = "good...";
//vm.$destroy();
script>
body>
html>
结果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aAlnVaMq-1595410166841)(assets/1556508009196-1567577895029.png)]
生命周期目的:改变视图会改变data数据,改变数据就改变视图。提供的钩子函数可以在这些函数种去初始化一下数据。
指令对照表
https://cn.vuejs.org/v2/api/
指令名称 | 描述 | 用法 |
---|---|---|
v-on | 事件绑定 | v-on:事件 = “事件名” 缩写:@事件 = “事件名” 点击事件:click,dblclick,change,blur 键盘事件:keydown/keyupkeypress 鼠标事件:mousedown,mouseover,mousemove,mouseout |
v-text/v-html | 文本取值 | 或者 两者的区别是:v-text不支持标签解析,v-html支持标签解析。 |
v-bind | 属性取值 | v-bind:属性 = “属性值” 缩写::属性 = “属性值” 解决在标签的属性上如何获取动态的数据值的问题。 比如: 或者 |
v-model | 获取form控件值 | 用于form表单控制元素值的相关获取和同步。 |
v-for | 循环迭代 | 一般用于循环数组,对象和对象数组。c:foreEach |
v-show/v-if/v-else | 隐藏/显示 | v-show:是控制元素display:none/block的切换。v-if:是逻辑判断,控制元素的存在与不存在。 c: |
v-pre | 原样输出不解析 | 如果你不想解析插值表达式,原样输入可以使用v-pre |
v-once | 渲染一次 | 如果你想渲染一次,后面改变数据不会影响视图的变化,可以使用v-once。 |
v-cloak | 解决网络延迟 | 往往在真实的场景中,插值表达式渲染会很慢, 而造成插件表达式的外漏,可以借助v-cloak和[v-cloak]{display:none;}来解决这个问题 |
目标
掌握事件指令v-on的语法定义。
语法
事件操作是开发中用的最频繁的操作:vuejs中采用v-on指令+methods的方式来完成事件的定义和绑定。
语法如下:v-on:事件类型=“事件名称” 比如:v-on:click=“fun1”
简写:@事件类型=“事件名称”。比如:@click=“fun1”
代码
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Documenttitle>
head>
<body>
<div id="app">
<form action="">
<p>账号: <input type="text">p>
<p>密码: <input type="text">p>
<p><button v-on:click="login">登录button>p>
<p><button @click="login">@登录button>p>
form>
div>
<script src="js/vue.min.js">script>
<script>
// 第三步:初始化vuejs实例对象和数据
// 重点:事件定义在methods中,以key:value的方式存在
// 调用事件:v-on:事件类型="methods的key” 简写 @click="事件名"
var vue = new Vue({//Vm
el:"#app",
data:{//---------------------data
title:"117班所有学生,大家好,艾编程程序"
},
methods:{
login(){
alert("登录进来了......")
}
}
})
script>
body>
html>
小结:
1: 事件指令:v-on:事件类型=“事件名” ,事件名必须定义在:methods对象,定义事件:执行业务逻辑改变数据data,一旦改变就会立即重新渲染视图(div)
2:如果没有参数,事件名是可以加括号也可以不加
3:如果传递参数的时候,请求括号不要加插值表达式
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kzbstRbw-1595410166843)(assets/1566784870562.png)]
目标
掌握事件指令v-on事件操作符应用场景
概述
在事件处理程序中调***用 event.preventDefault()
或 event.stopPropagation()
是非常常见的需求。尽管我们可以在方法中轻松实现这点,但更好的方式是:方法只有纯粹的数据逻辑,而不是去处理 DOM 事件细节。
为了解决这个问题,Vue.js 为 v-on
提供了事件修饰符。之前提过,修饰符是由点开头的指令后缀来表示的。
.stop
:阻止事件冒泡.prevent
:阻止默认事件发生.capture
:使用事件捕获模式.self
:只有元素自身触发事件才执行。(冒泡或捕获的都不执行).once
:只执行一次语法
.prevent和 .once的用法:
在实际的开发中:button,submit和a连接都有各自默认的行为,比如button和submit会提交form表单,这个时候会造成业务的重复执行,所以可以使用:.prevent
来解决这个问题。
目标
Vue.js通过由点(.)表示的指令后缀来调用修饰符。
语法
Vue 允许为 v-on 在监听键盘事件时添加按键修饰符
全部的按键别名:
.enter(enter键)
.tab (Tab键)
.delete (捕获 "删除" 和 "退格" 键)
.esc (退出键)
.space(空格键)
.up (向上)
.down(向下)
.left(向左)
.right(向右)
.ctrl
.alt
.shift
.meta
注意:在 Mac 系统键盘上,meta 对应 command 键 (⌘)。在 Windows 系统键盘 meta 对应 Windows 徽标键 (⊞)。在 Sun 操作系统键盘上,meta 对应实心宝石键 (◆)。在其他特定键盘上,尤其在 MIT 和 Lisp 机器的键盘、以及其后继产品,比如 Knight 键盘、space-cadet 键盘,meta 被标记为“META”。在 Symbolics 键盘上,meta 被标记为“META”或者“Meta
”。
代码
小结
获取键盘码代码
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Documenttitle>
head>
<body>
<div id="app">
<input type="text" id="getcode">
<h1>你当前的键码是:<span id="code">span>h1>
div>
<script>
// ascii表
document.getElementById("getcode").onkeydown = function(e){
document.getElementById("code").innerText = e.keyCode
}
script>
body>
html>
目标
了解和掌握文本指令的用法,以及v-text和v-html的区别
小结
v-text和v-html 都是属于文本的值管理范畴,唯独的差别就是:
提示:v-text和插值表达式{{}}不支持标签解析,v-html支持标签解析
代码
小结
1:注意点:在指令上不要写插值表达式{{}}。
2:都可以支持算数运算。
3:v-text和插值表达式{{}}不支持标签解析,v-html支持标签解析
目标
了解和掌握属性动态绑定的v-bind的指令使用规则。
小结
插值语法:{{}} 是不能直接使用在属性上,需要借助v-bind指令来解决此问题!
语法:v-bind:属性=’'data数据key"
简写::属性=“data数据的key”,比如::src=“imgsrc”
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-htHk186C-1595410166845)(assets/1557907358338.png)]
代码
小结
如果想把data中的数据,放入到元素的属性上,那么久必须使用v-bind指令来完成。
目标
操作元素的 class 列表和内联样式是数据绑定的一个常见需求。因为它们都是属性,所以我们可以用 v-bind
处理它们:只需要通过表达式计算出字符串结果即可。不过,字符串拼接麻烦且易错。因此,在将 v-bind
用于 class
和 style
时,Vue.js 做了专门的增强。表达式结果的类型除了字符串之外,还可以是对象或数组。
步骤
对象语法
我们可以传给 v-bind:class
一个对象,以动态地切换 class:
<div v-bind:class="{ active: isActive }">div>
案例如下:
<div
class="static"
v-bind:class="{ active: isActive, 'text-danger': hasError }"
>div>
和如下 data:
data: {
isActive: true,
hasError: false
}
结果渲染为:
<div class="static active">div>
当 isActive
或者 hasError
变化时,class 列表将相应地更新。例如,如果 hasError
的值为 true
,class 列表将变为 "static active text-danger"
。
数组语法
我们可以把一个数组传给 v-bind:class
,以应用一个 class 列表:
<div v-bind:class="[activeClass, errorClass]">div>
data: {
activeClass: 'active',
errorClass: 'text-danger'
}
渲染为:
<div class="active text-danger">div>
如果你也想根据条件切换列表中的 class,可以用三元表达式:
<div v-bind:class="[isActive ? activeClass : '', errorClass]">div>
这样写将始终添加 errorClass
,但是只有在 isActive
是 truthy[1] 时才添加 activeClass
。
不过,当有多个条件 class 时这样写有些繁琐。所以在数组语法中也可以使用对象语法:
<div v-bind:class="[{ active: isActive }, errorClass]">div>
style同理。
真实案例
目标
如何获取form控件元素值。
注意
Form元素是开发中使用最多的控件,如何获取空间元素的值。就必须借助于:v-model指令
代码
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Documenttitle>
head>
<body>
<div id="app">
<form action="">
<p>账号: <input type="text" v-model="account">p>
<p>密码: <input type="text" v-model="password">p>
<p><button v-on:click.prevent="login">登录button>p>
<p><button @click.prevent="login">@登录button>p>
<hr>
<p>调试代码p>
你输入的信息是:{{account}} {{password}}
form>
div>
<script src="js/vue.min.js">script>
<script>
// 第三步:初始化vuejs实例对象和数据
// 重点:事件定义在methods中,以key:value的方式存在
// 调用事件:v-on:事件类型="methods的key” 简写 @click="事件名"
var vue = new Vue({//Vm
el:"#app",
data:{//---------------------data
account:"",
password:"",
title:"117班所有学生,大家好,艾编程程序"
},
methods:{
login(){
var account = this.account;
var password = this.password;
console.log(account,password)
//ajax
}
}
})
script>
body>
html>
小结
v-model只能用于form元素才有意义,所谓的双向数据绑定就是指:v-model
目标
数据往往存在多种形态:对象,数组,对象数组。如果将对象的key和value分别取出来,如何取出数组中的每个元素,是开发中非常常见的操作。vue提供了:v-for指令,可以轻松完成这个事情。
操作数组
html部分
{{index}}:{{value}}
js部分
var app = new Vue({
el:"#app",
data:{
title:"Hello world!",
names:["zhangsan","lisi","wangwu"]
}
}) ;
操作对象
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6Xzi3SAV-1595410166846)(assets/1557910291171.png)]
# html 部分
{{key}}:{{value}}
js部分
// 第三步:定义vuejs对象,开始进行视图和数据的渲染
var app = new Vue({
el:"#app",
data:{
title:"Hello world!",
user:{id:1,username:"徐承飞老师",age:32}
}
}) ;
操作对象数组
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Documenttitle>
head>
<body>
<div id="app">
<ul v-for="user in userData">
<li>id:{{user.id}}li>
<li>name:{{user.name}}li>
<li>age:{{user.age}}li>
ul>
<hr>
<ul v-for="(user,index) in userData">
<li>{{index + 1}}li>
<li>id:{{user.id}}li>
<li>name:{{user.name}}li>
<li>age:{{user.age}}li>
ul>
<hr>
{{friends[0]}}
{{friends[1]}}
{{friends[2]}}
<hr>
<p v-for="(f,index) in friends">{{f}}=={{friends[index]}}p>
div>
<script src="js/vue.min.js">script>
<script>
// jsp-servlet---el表达式 +作用域 ${username} ${user.name} 这里的username和user是不必须定义在作用域
// request.setAttribute session.setAttribute()
//问题:mvvm是什么?它设计开发的设计理念,目的通过一些方式能够达到类似于mvc架构模式。完整将数据和视图进行分离。
var vue = new Vue({//----------------------------------vm角色
el: "#app",
// 重点:未来所有的数据都要在这里进行定义和存放?mvc model(dao,pojo) view(jsp) controller(servlet)
data: {//----------------------------model不就我们的作用域吗?
username: "",
age: "2",
password: "3",
friends:["A","B","C"],
userData: [{
id: "1",
name: "zhangsan",
age: 32
}, {
id: "2",
name: "lisi",
age: 32
}]
}
})
script>
body>
html>
小结
索引的获取是定义 v-for=(user,index) in 对象、数组、数组对象都可以.
目标
掌握v-if/v-else和v-if/v-else-if/v-else标签的使用
需求
用户输入步同年龄阶段,显示这个阶段对应的时期。
代码
v-if/v-else-if/v-else例子
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Documenttitle>
head>
<body>
<div id="app">
<ul v-for="(user,index) in userData">
<li>{{index + 1}}li>
<li>id:{{user.id}}li>
<li>name:{{user.name}}li>
<li>age:{{user.age}}li>
<li>性别:
<span v-if="user.male==0">女span>
<span v-if="user.male==1">男span>
<span v-if="user.male==2">保密span>
:
<span v-if="user.male==0">女span>
<span v-else-if="user.male==1">男span>
<span v-else>保密span>
li>
ul>
div>
<script src="js/vue.min.js">script>
<script>
// jsp-servlet---el表达式 +作用域 ${username} ${user.name} 这里的username和user是不必须定义在作用域
// request.setAttribute session.setAttribute()
//问题:mvvm是什么?它设计开发的设计理念,目的通过一些方式能够达到类似于mvc架构模式。完整将数据和视图进行分离。
var vue = new Vue({//----------------------------------vm角色
el: "#app",
// 重点:未来所有的数据都要在这里进行定义和存放?mvc model(dao,pojo) view(jsp) controller(servlet)
data: {//----------------------------model不就我们的作用域吗?
userData: [{
id: "1",
male:2,
name: "zhangsan",
age: 32
}, {
id: "2",
male:1,
name: "lisi",
age: 32
},{
id: "3",
male:0,
name: "zhangsan",
age: 32
}]
}
})
script>
body>
html>
小结
注意点,v-if/elseif/else 指令和指令之间加标签会造成断层,否则无效。如果仅仅是文本就忽略文本。正常执行。
目标
掌握和学习v-show的使用方式,以及v-show和v-if的区别
代码
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Documenttitle>
head>
<body>
<div id="app">
<div v-show="flag">v-show显示div>
<div v-show="!flag">v-hidediv>
<div v-if="flag">v-if显示div>
div>
<script src="js/vue.min.js">script>
<script>
// jsp-servlet---el表达式 +作用域 ${username} ${user.name} 这里的username和user是不必须定义在作用域
// request.setAttribute session.setAttribute()
//问题:mvvm是什么?它设计开发的设计理念,目的通过一些方式能够达到类似于mvc架构模式。完整将数据和视图进行分离。
var vue = new Vue({//----------------------------------vm角色
el: "#app",
// 重点:未来所有的数据都要在这里进行定义和存放?mvc model(dao,pojo) view(jsp) controller(servlet)
data: {//----------------------------model不就我们的作用域吗?
flag:true
}
})
script>
body>
html>
小结
v-if是根据表达式的值来决定是否渲染元素
v-show是根据表达式的值来切换元素的display css属性
使用vuejs计算属性完成
案例需求
完成用户的查询与修改操作,
步骤
1:新建springboot工程
2:添加相关依赖配置整合sm
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-freemarkerartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<optional>trueoptional>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
<dependency>
<groupId>com.baomidougroupId>
<artifactId>mybatis-plus-boot-starterartifactId>
<version>3.3.0version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<scope>runtimescope>
<version>5.1.10version>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druid-spring-boot-starterartifactId>
<version>1.1.18version>
dependency>
定义一个pojo
3:整合mybatis-plus
package com.icoding.core;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;
//Spring boot方式
@EnableTransactionManagement
@Configuration
// 把mapper交给springioc容器管理和初始化
@MapperScan("com.icoding.mapper")
public class MybatisPlusConfig {
@Bean
public PaginationInterceptor paginationInterceptor() {
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
// 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求 默认false
// paginationInterceptor.setOverflow(false);
// 设置最大单页限制数量,默认 500 条,-1 不受限制
// paginationInterceptor.setLimit(500);
return paginationInterceptor;
}
}
3:编写一个mapper继承通用BaseMapper
package com.icoding.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.icoding.pojo.BuyCart;
/**
*
* todo:购物车管理数据层
* BuyCartMapper
* 创建人:David老师
* 时间:2019年12月25日 22:52:04
* @version 1.0.0
*
*/
public interface BuyCartMapper extends BaseMapper<BuyCart> {
}
4:建立pojo通过主键@TableName和表建立关系
package com.icoding.pojo;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
/**
*
* todo:购物车管理实体
* BuyCart
* 创建人:David老师
* 时间:2019年12月25日 22:52:04
* @version 1.0.0
*
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
@Builder
@ApiModel("购物车管理")
@TableName("im_buycart")
public class BuyCart implements java.io.Serializable{
@ApiModelProperty("")
@TableId(type = IdType.AUTO)
private Integer id;
// 登录用户id
@ApiModelProperty("登录用户id")
private String customerId;
// 未登录cookie id
private String buyId;
// 登录状态0-未登录,1-登录
@ApiModelProperty("登录状态0-未登录,1-登录")
private Integer loginStatus;
// 产品ID
@ApiModelProperty("产品ID")
private String productId;
// 产品唯一编码
@ApiModelProperty("产品唯一编码")
private String spu;
// 产品原价
@ApiModelProperty("产品原价")
private Float originalPrice;
// 售价
@ApiModelProperty("售价")
private Float salePrice;
// 购买数量
@ApiModelProperty("购买数量")
private Integer saleQty;
// 小计
@ApiModelProperty("小计")
private Float saleTotalPrice;
// 规格ID
@ApiModelProperty("规格ID")
private Integer variantsId;
// 规格名称
@ApiModelProperty("规格名称")
private String variantsTitle;
// 规格的唯一编码
@ApiModelProperty("规格的唯一编码")
private String sku;
// 属性图片src路径
@ApiModelProperty("属性图片src路径")
private String imageSrc;
// 规格的重量
@ApiModelProperty("规格的重量")
private Integer variantsWeight;
// 产品链接
@ApiModelProperty("产品链接")
private String productHandle;
// 产品名称
@ApiModelProperty("产品名称")
private String productTitle;
// 分类ID
@ApiModelProperty("分类ID")
private String collectionId;
// 添加时间
@ApiModelProperty("添加时间")
private Date createTime;
// 修改时间
@ApiModelProperty("修改时间")
private Date updateTime;
}
5:配置数据库信息
applicaiton-dev.properties
#druid
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/aicodingdb?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
applicaiton.properties
server.port=8088
# springboot profile机制
spring.profiles.active=dev
6:编写测试用例,检验mapper是否能够执行查询数据库的操作
package com.icoding;
import com.icoding.mapper.BuyCartMapper;
import com.icoding.pojo.BuyCart;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class SpringbootIcodingTmallproApplicationTests {
@Autowired
private BuyCartMapper buyCartMapper;
@Test
void contextLoads() {
BuyCart buyCart = buyCartMapper.selectById(1);
System.out.println(buyCart);
}
}
6:测试数据接口
package com.icoding;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.icoding.mapper.BuyCartMapper;
import com.icoding.pojo.BuyCart;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.List;
@SpringBootTest
class SpringbootIcodingTmallproApplicationTests {
@Autowired
private BuyCartMapper buyCartMapper;
@Test
void contextLoads() {
/*BuyCart buyCart = buyCartMapper.selectById(1);
System.out.println(buyCart);*/
//查询条件
//QueryWrapper queryWrapper = new QueryWrapper<>();
/* List buyCarts = buyCartMapper.selectList(null);
for (BuyCart buyCart : buyCarts) {
System.out.println(buyCart);
}*/
Page<BuyCart> page = new Page<>(2,10);
//QueryWrapper queryWrapper = new QueryWrapper<>();
IPage<BuyCart> buyCartIPage = buyCartMapper.selectPage(page,null);
List<BuyCart> records = buyCartIPage.getRecords();
for (BuyCart buyCart : records) {
System.out.println(buyCart);
}
}
}
7:使用vuejs完成列表查询和购物车查询
**目标:**掌握和学习异步处理组件axios.
概述
Vuejs 并没有直接处理ajax的组件,但可以使用axios或vue-resource组件实现对异步请求的操作。
vue-resource
vue-resource是Vue.js的插件提供了使用XMLHttpRequest或JSONP进行Web请求和处理响应的服务。 当vue更新
到2.0之后,作者就宣告不再对vue-resource更新,而是推荐axios。
vue-resource的github: https://github.com/pagekit/vue-resource
axios简介
Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中
new
axios的github:https://github.com/axios/axios
# 如果使用npm则可以如下安装
npm install axios
或者
npm i axios
或者也可以直接使用公共的CDN(内容分发网络)服务:
<script src="https://unpkg.com/axios/dist/axios.min.js">script>
6.3.1 方法说明
axios可以使用的方法有:
config请求配置
这些是创建请求时可以用的配置选项。只有 url
是必需的。如果没有指定 method
,请求将默认使用 get
方法。
{
// `url` 是用于请求的服务器 URL
url: '/user',
// `method` 是创建请求时使用的方法
method: 'get', // 默认是 get
// `baseURL` 将自动加在 `url` 前面,除非 `url` 是一个绝对 URL。
// 它可以通过设置一个 `baseURL` 便于为 axios 实例的方法传递相对 URL
baseURL: 'https://some-domain.com/api/',
// `transformRequest` 允许在向服务器发送前,修改请求数据
// 只能用在 'PUT', 'POST' 和 'PATCH' 这几个请求方法
// 后面数组中的函数必须返回一个字符串,或 ArrayBuffer,或 Stream
transformRequest: [function (data) {
// 对 data 进行任意转换处理
return data;
}],
// `transformResponse` 在传递给 then/catch 前,允许修改响应数据
transformResponse: [function (data) {
// 对 data 进行任意转换处理
return data;
}],
// `headers` 是即将被发送的自定义请求头
headers: {
'X-Requested-With': 'XMLHttpRequest',
'Content-Type': 'application/json'
},
// `params` 是即将与请求一起发送的 URL 参数
// 必须是一个无格式对象(plain object)或 URLSearchParams 对象
params: {
ID: 12345
},
// `data` 是作为请求主体被发送的数据
// 只适用于这些请求方法 'PUT', 'POST', 和 'PATCH'
// 在没有设置 `transformRequest` 时,必须是以下类型之一:
// - string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams
// - 浏览器专属:FormData, File, Blob
// - Node 专属: Stream
data: {
firstName: 'Fred'
},
// `timeout` 指定请求超时的毫秒数(0 表示无超时时间)
// 如果请求话费了超过 `timeout` 的时间,请求将被中断
timeout: 1000,
// `withCredentials` 表示跨域请求时是否需要使用凭证
withCredentials: false, // 默认的
// `responseType` 表示服务器响应的数据类型,可以是 'arraybuffer', 'blob', 'document', 'json', 'text', 'stream'
responseType: 'json', // 默认的
// `maxContentLength` 定义允许的响应内容的最大尺寸
maxContentLength: 2000,
// `validateStatus` 定义对于给定的HTTP 响应状态码是 resolve 或 reject promise 。如果 `validateStatus` 返回 `true` (或者设置为 `null` 或 `undefined`),promise 将被 resolve; 否则,promise 将被 rejecte
validateStatus: function (status) {
return status >= 200 && status < 300; // 默认的
},
// `maxRedirects` 定义在 node.js 中 follow 的最大重定向数目
// 如果设置为0,将不会 follow 任何重定向
maxRedirects: 5 // 默认的
}
响应结构
{
// `data` 由服务器提供的响应
data: {},
// `status` 来自服务器响应的 HTTP 状态码
status: 200,
// `statusText` 来自服务器响应的 HTTP 状态信息
statusText: 'OK',
// `headers` 服务器响应的头
headers: {},
// `config` 是为请求提供的配置信息
config: {}
}
使用 then
时,你将接收下面这样的响应:
axios.get('/user/12345')
.then(function(response) {
console.log(response.data);
console.log(response.status);
console.log(response.statusText);
console.log(response.headers);
console.log(response.config);
});
在使用 catch
时,或传递 rejection callback 作为 then
的第二个参数时,响应可以通过 error
对象可被使用。
axios方法示例
可以通过向 axios
传递相关配置来创建请求
axios(config)
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vuejs测试title>
<script src="js/vue-2.6.10.js">script>
<script src="js/axios.min.js">script>
head>
<body>
<div id="app">
<ul>
<li v-for="(user,index) in users" :key="index">
{{index}}--{{user.name}}--{{user.age}}--{{user.gender}}
li>
ul>
div>
<script>
var app = new Vue({
el:"#app",
data: {
users:[]
},
created(){
//加载数据
axios({
method:"get",
url: "data.json"
}).then((res)=>{
console.log(res);
//将获取数据设置到users属性
this.users = res.data;
}).catch(error=>{
alert(error);
});
}
});
script>
body>
html>
get方法示例
将上述示例中的axios操作部分修改为如下:
axios.get("data.json")
.then( res => {
console.log(res);
//将获取数据设置到users属性
this.users = res.data;
}).catch(error =>{
console.log(error)
});
post方法示例
将示例中的axios操作部分修改为如下:
axios.post("data.json")
.then( res => {
console.log(res);
//将获取数据设置到users属性
this.users = res.data;
}).catch(error =>{
console.log(error)
});
}
config请求配置
这些是创建请求时可以用的配置选项。只有 url
是必需的。如果没有指定 method
,请求将默认使用 get
方法。
{
// `url` 是用于请求的服务器 URL
url: '/user',
// `method` 是创建请求时使用的方法
method: 'get', // 默认是 get
// `baseURL` 将自动加在 `url` 前面,除非 `url` 是一个绝对 URL。
// 它可以通过设置一个 `baseURL` 便于为 axios 实例的方法传递相对 URL
baseURL: 'https://some-domain.com/api/',
// `transformRequest` 允许在向服务器发送前,修改请求数据
// 只能用在 'PUT', 'POST' 和 'PATCH' 这几个请求方法
// 后面数组中的函数必须返回一个字符串,或 ArrayBuffer,或 Stream
transformRequest: [function (data) {
// 对 data 进行任意转换处理
return data;
}],
// `transformResponse` 在传递给 then/catch 前,允许修改响应数据
transformResponse: [function (data) {
// 对 data 进行任意转换处理
return data;
}],
// `headers` 是即将被发送的自定义请求头
headers: {
'X-Requested-With': 'XMLHttpRequest',
'Content-Type': 'application/json'
},
// `params` 是即将与请求一起发送的 URL 参数
// 必须是一个无格式对象(plain object)或 URLSearchParams 对象
params: {
ID: 12345
},
// `data` 是作为请求主体被发送的数据
// 只适用于这些请求方法 'PUT', 'POST', 和 'PATCH'
// 在没有设置 `transformRequest` 时,必须是以下类型之一:
// - string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams
// - 浏览器专属:FormData, File, Blob
// - Node 专属: Stream
data: {
firstName: 'Fred'
},
// `timeout` 指定请求超时的毫秒数(0 表示无超时时间)
// 如果请求话费了超过 `timeout` 的时间,请求将被中断
timeout: 1000,
// `withCredentials` 表示跨域请求时是否需要使用凭证
withCredentials: false, // 默认的
// `responseType` 表示服务器响应的数据类型,可以是 'arraybuffer', 'blob', 'document', 'json', 'text', 'stream'
responseType: 'json', // 默认的
// `maxContentLength` 定义允许的响应内容的最大尺寸
maxContentLength: 2000,
// `validateStatus` 定义对于给定的HTTP 响应状态码是 resolve 或 reject promise 。如果 `validateStatus` 返回 `true` (或者设置为 `null` 或 `undefined`),promise 将被 resolve; 否则,promise 将被 rejecte
validateStatus: function (status) {
return status >= 200 && status < 300; // 默认的
},
// `maxRedirects` 定义在 node.js 中 follow 的最大重定向数目
// 如果设置为0,将不会 follow 任何重定向
maxRedirects: 5 // 默认的
}
响应结构
{
// `data` 由服务器提供的响应
data: {},
// `status` 来自服务器响应的 HTTP 状态码
status: 200,
// `statusText` 来自服务器响应的 HTTP 状态信息
statusText: 'OK',
// `headers` 服务器响应的头
headers: {},
// `config` 是为请求提供的配置信息
config: {}
}
目标
实操axios调用后台数据,实现数据的CURD。
步骤
导入axios的js
<script src="js/axios-0.18.0.js"></script>
get请求+传参 第一种方式
axios.get("http://localhost:8080/vuessm-user/get?id="+id).then(function(response){
console.log(response);
if(response.status==200){
that.$data.user = response.data;
$("#myModal").modal("show");//让模态框弹出来
}
});
get请求+传参 第二种方式
var opid = 1;
axios.get("http://localhost:8080/vuessm-user/get/",{
params:{
id:opid
}
}).then(function(response){
console.log(response);
if(response.status==200){
that.$data.user = response.data;
$("#myModal").modal("show");//让模态框弹出来
}
});
post请求+传参 第一种方式
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
或
headers:{'Content-Type':'application/x-www-form-urlencoded'}
注意后台springmvc必须设置:@RequestBody 才可以获取到值,并且只支持对象和Map
axios.post(url,_this.user).then(function (res) {
//成功之后直接刷新页面
_this.findAll();
}).catch(function (err) {
console.log(err)
});
后台代码
@PostMapping("save")
public String save(@RequestBody User user){}
@PostMapping("save")
public String save(@RequestBody Map map){}
post请求+传参 第二种方式
post请求后台参数是单个并且使用@RequestParam的时候使用如下
@PostMapping("save")
public String save(String username,String pwd){}
下面代码可以把参数注入到username和password中。
let param = new URLSearchParams()
param.append('username', 'admin')
param.append('pwd', 'admin')
axios.post('/api/lockServer/search',param);
或
axios.post('/api/lockServer/search',"userName='admin'&pwd='admin'");
参考文档:https://www.cnblogs.com/yiyi17/p/9409249.html
var person = {id:1,name:“zhangsan”};
person .id
person .name
person [“id”
]
在大型应用开发的时候,页面可以划分成很多部分。往往不同的页面,也会有相同的部分。例如可能会有相同的头部导航。
但是如果每个页面都独自开发,这无疑增加了开发的成本。所以会把页面的不同部分拆分成独立的组件,然后在不同页面就可以共享这些组件,避免重复开发。
**目标:**掌握和学习vuejs组件的定义
步骤:
通过Vue的component方法来定义一个全局组件。
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vuejs测试title>
head>
<body>
<div id="app">
<counter>counter>
div>
<script src="node_modules/vue/dist/vue.js">script>
<script>
//定义组件
const counter = {
template: "",
data(){
return {num: 0}
}
};
//全局注册组件;参数1:组件名称,参数2:组件
Vue.component("counter", counter);
var app = new Vue({
el:"#app"
});
script>
body>
html>
效果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ayc6a9tI-1595410166848)(assets/component-01-1567580815767.gif)]
**目标:**组件的调用和data数据的定义注意事项
操作
定义好的组件,可以任意复用多次:
<div id="app">
<counter>counter>
<counter>counter>
<counter>counter>
div>
效果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mh42KBX8-1595410166848)(assets/1556534115827-1567580815767.png)]
你会发现每个组件互不干扰,都有自己的num值。怎么实现的?
组件的data属性必须是函数!
当定义这个
组件时,它的data 并不是像这样直接提供一个对象:
data: {
num: 0
}
取而代之的是,一个组件的 data 选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝:
data: function () {
return {
num: 0
}
}
如果 Vue 没有这条规则,点击一个按钮就会影响到其它所有实例!
目标
一旦全局注册,就意味着即便以后你不再使用这个组件,它依然会随着Vue的加载而加载。
因此,对于一些并不频繁使用的组件,会采用局部注册。
先在外部定义一个对象,结构与创建组件时传递的第二个参数一致:
然后在Vue中使用它:
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vuejs测试title>
head>
<body>
<div id="app">
<counter>counter>
<counter>counter>
<counter>counter>
div>
<script src="node_modules/vue/dist/vue.js">script>
<script>
//定义组件
const counter = {
template: "",
data(){
return {num: 0}
}
};
//全局注册组件;参数1:组件名称,参数2:组件
//Vue.component("counter", counter);
var app = new Vue({
el:"#app",
//局部注册组件
components:{
counter: counter
}
});
script>
body>
html>
目标: 使用vuejs完成父子组件间的通讯
通常一个单页应用会以一棵嵌套的组件树的形式来组织:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MKmOdjNY-1595410166849)(assets/1525855149491-1567580815767.png)]
各个组件之间以嵌套的关系组合在一起,那么这个时候不可避免的会有组件间通信的需求。
** 父向子传递props**
比如有一个子组件:
Vue.component("introduce",{
// 直接使用props接收到的属性来渲染页面
template:'{{title}}
',
props:[title] // 通过props来接收一个父组件传递的属性
})
父组件使用子组件,同时传递title属性:
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vuejs测试title>
head>
<body>
<div id="app">
<introduce :title="msg">introduce>
div>
<script src="node_modules/vue/dist/vue.js">script>
<script>
//定义组件
const introduce = {
//使用props属性title的值渲染模版
template: "{{title}}
",
//定义接收来自父组件的属性
props:["title"]
};
//全局注册组件;参数1:组件名称,参数2:组件
Vue.component("introduce", introduce);
var app = new Vue({
el:"#app",
data:{
msg: "父组件中的msg属性的内容"
}
});
script>
body>
html>
效果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0FhgJrj7-1595410166850)(assets/06-2-1567580815767.gif)]
传递复杂数据
定义一个子组件:
const myList = {
template:'\
\
- {{item.id}} : {{item.name}}
\
\
',
props:{ // 通过props来接收父组件传递来的属性
items:{// 这里定义items属性
type:Array,// 要求必须是Array类型
default:[] // 如果父组件没有传,那么给定默认值是[]
}
}
}
页面内容:
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vuejs测试title>
head>
<body>
<div id="app">
<h2>艾编程开设的课程有:h2>
<my-list :items="lessons">my-list>
div>
<script src="node_modules/vue/dist/vue.js">script>
<script>
//定义组件
const myList = {
//可以使用双引号、单引号或者如下使用的 ` 飘号
template: `
- {{item.id}}--{{item.name}}
`,
//定义接收来自父组件的属性
props: {
//定义模版中使用的属性
items: {
//必须为数组类型
type: Array,
//默认为空数组
default: []
}
}
};
var app = new Vue({
el: "#app",
data: {
msg: "父组件中的msg属性的内容",
lessons:[
{"id":1, "name":"Java"},
{"id":2, "name":"PHP"},
{"id":3, "name":"前端"}
]
},
//注册组件
components: {
//如果组件key和value一致可以简写如下
myList
}
});
script>
body>
html>
子向父的通信
来看这样的一个案例:
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vuejs测试title>
head>
<body>
<div id="app">
<h2>num = {{num}}h2>
<counter :snum="num">counter>
div>
<script src="node_modules/vue/dist/vue.js">script>
<script>
//定义组件
const counter = {
//组件只能是一个元素里面包裹其他元素;如下面,一个div包含两个按钮
template: `
`,
props:["snum"]
};
//全局注册组件;参数1:组件名称,参数2:组件
Vue.component("counter", counter);
var app = new Vue({
el:"#app",
data:{
num:0
}
});
script>
body>
html>
尝试运行,好像没问题,点击按钮试试:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iKb4uD56-1595410166851)(assets/1556547969267-1567580815767.png)]
子组件接收到父组件属性后,默认是不允许修改的。怎么办?
既然只有父组件能修改,那么加和减的操作一定是放在父组件:
var app = new Vue({
el:"#app",
data:{
num:0
},
methods:{
//父组件中定义操作num的方法
numPlus(){
this.num++;
},
numReduce(){
this.num--;
}
}
});
但是,点击按钮是在子组件中,那就是说需要子组件来调用父组件的函数,怎么做?
可以通过v-on指令将父组件的函数绑定到子组件上:
<div id="app">
<h2>num = {{num}}h2>
<counter @plus="numPlus" @reduce="numReduce" :snum="num">counter>
div>
然后,当子组件中按钮被点击时,调用绑定的函数:
//定义组件
const counter = {
//组件只能是一个元素里面包裹其他元素;如下面,一个div包含两个按钮
template: `
`,
props:["snum"],
methods: {
//点击模板中使用的方法
incrNum(){
return this.$emit("plus");
},
decrNum(){
return this.$emit("reduce");
}
}
};
完成页面如下:
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vuejs测试title>
head>
<body>
<div id="app">
<h2>num = {{num}}h2>
<counter @plus="numPlus" @reduce="numReduce" :snum="num">counter>
div>
<script src="node_modules/vue/dist/vue.js">script>
<script>
//定义组件
const counter = {
//组件只能是一个元素里面包裹其他元素;如下面,一个div包含两个按钮
template: `
`,
props:["snum"],
methods: {
//点击模板中使用的方法
incrNum(){
return this.$emit("plus");
},
decrNum(){
return this.$emit("reduce");
}
}
};
//全局注册组件;参数1:组件名称,参数2:组件
Vue.component("counter", counter);
var app = new Vue({
el:"#app",
data:{
num:0
},
methods:{
//父组件中定义操作num的方法
numPlus(){
this.num++;
},
numReduce(){
this.num--;
}
}
});
script>
body>
html>
效果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eE3RXQM6-1595410166851)(assets/06-3-1567580815767.gif)]
子组件不能直接修改父组件传递参数的引用或者基本类型参数值。
目标
学习和掌握vuejs的过滤器的使用,实现案例人民币符号添加、和日期格式化.
过滤器案例一:人民币符号的前缀添加
<html>
<head>
<meta charset="utf-8" />
<title>title>
head>
<body>
<div id="app">
{{title}}==={{totalPrice | money}}=={{addMoeny(totalPrice)}}
div>
<script src="js/vue.min.js">script>
<script type="text/javascript">
//自定义过滤器
Vue.filter("money",function(value,prefix){
return prefix||"¥" + value;
});
//实例化对象
var vue = new Vue({
el:"#app",
data:{title:"你好"},
// 计算属性
computed:{
totalPrice:function(){
return 100;
}
},
// 事件列表
methods:{
addMoeny:function(value,prefix){
return prefix||"¥" + value;
},
parentClick:function(opid){
console.log("parent click",opid);
}
},
//入口函数
created:function(){
}
});
script>
body>
html>
过滤器案例二:–日期格式化
<html>
<head>
<meta charset="UTF-8">
<title>title>
head>
<body>
<div id="app">
{{date | dateFmt('yyyy-MM-dd hh:mm:ss')}}
div>
<script src="js/vue.min.js">script>
<script>
Date.prototype.format = function (format) {
var args = {
"M+": this.getMonth() + 1,
"d+": this.getDate(),
"h+": this.getHours(),
"m+": this.getMinutes(),
"s+": this.getSeconds(),
};
if (/(y+)/.test(format))
format = format.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
for (var i in args) {
var n = args[i];
if (new RegExp("(" + i + ")").test(format))
format = format.replace(RegExp.$1, RegExp.$1.length == 1 ? n : ("00" + n).substr(("" + n).length));
}
return format;
};
Vue.filter("dateFmt",function(value,fmt){
return value.format(fmt || "yyyy-MM-dd");
})
var vue = new Vue({
el:"#app",
data:{
date:new Date()
}
});
script>
body>
html>
er);
var app = new Vue({
el:"#app",
data:{
num:0
},
methods:{
//父组件中定义操作num的方法
numPlus(){
this.num++;
},
numReduce(){
this.num--;
}
}
});
```
效果:
[外链图片转存中…(img-eE3RXQM6-1595410166851)]
子组件不能直接修改父组件传递参数的引用或者基本类型参数值。
目标
学习和掌握vuejs的过滤器的使用,实现案例人民币符号添加、和日期格式化.
过滤器案例一:人民币符号的前缀添加
<html>
<head>
<meta charset="utf-8" />
<title>title>
head>
<body>
<div id="app">
{{title}}==={{totalPrice | money}}=={{addMoeny(totalPrice)}}
div>
<script src="js/vue.min.js">script>
<script type="text/javascript">
//自定义过滤器
Vue.filter("money",function(value,prefix){
return prefix||"¥" + value;
});
//实例化对象
var vue = new Vue({
el:"#app",
data:{title:"你好"},
// 计算属性
computed:{
totalPrice:function(){
return 100;
}
},
// 事件列表
methods:{
addMoeny:function(value,prefix){
return prefix||"¥" + value;
},
parentClick:function(opid){
console.log("parent click",opid);
}
},
//入口函数
created:function(){
}
});
script>
body>
html>
过滤器案例二:–日期格式化
<html>
<head>
<meta charset="UTF-8">
<title>title>
head>
<body>
<div id="app">
{{date | dateFmt('yyyy-MM-dd hh:mm:ss')}}
div>
<script src="js/vue.min.js">script>
<script>
Date.prototype.format = function (format) {
var args = {
"M+": this.getMonth() + 1,
"d+": this.getDate(),
"h+": this.getHours(),
"m+": this.getMinutes(),
"s+": this.getSeconds(),
};
if (/(y+)/.test(format))
format = format.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
for (var i in args) {
var n = args[i];
if (new RegExp("(" + i + ")").test(format))
format = format.replace(RegExp.$1, RegExp.$1.length == 1 ? n : ("00" + n).substr(("" + n).length));
}
return format;
};
Vue.filter("dateFmt",function(value,fmt){
return value.format(fmt || "yyyy-MM-dd");
})
var vue = new Vue({
el:"#app",
data:{
date:new Date()
}
});
script>
body>
html>