1.【熟悉】Vue简介
1.1 简介
它是一个构建用户界面单页面的框架 Vue是一个前端框架
https://www.pmdaniu.com/#file UI网站
UI 一般开发者使用蓝湖 工具 看着UI图 写接口
https://lanhuapp.com/web/#/item
是一个轻量级的MVVM(Model-View-ViewModel),其实就是所谓的数据的双向绑定
Mvc
M—model mapper domain utils service servceimpl
V----view html thymeleaf
C----controller
数据驱动和组件化的前端开发
通过简单的API就能实现响应式的数据绑定和组合的视图组件
指令:
用来扩展html标签的功能
https://cn.vuejs.org/
1.2 其它
简单、易学、更轻量
指令v-xxx开头 v-if v-for 这些作用在html标签中
HTML + JSON数据
开发者 尤雨溪 华人 Vue React
这几个框架都不兼容低版本IE window Xp
2.【重点】MVVM的思想
2.1 Ajax请求数据 显示到页面
1,点击按钮触发事件
2,使用$.post $.get $.ajax 发请求
3,请求 完成之后拿到数据
4,使用document.getElementById(“id”)找到页面的dom对象
5,把第三部请求回来的数据使用innerText innerHtml去修改
2.2 MVVM 设计思想
MVC
|–M Model (domain,service,serviceimpl.utils.pojo.mapper)
|–V view thymeleaf jsp html
|–C controller 接收前端请求(控制器)
Model:对应数据层的域模型,它主要做域模型的同步。通过 Ajax/fetch 等 API 完成客户端和服务端业务 Model 的同步。在模型层间关系里,它主要用于抽象出 ViewModel 中视图的 Model。个人理解:后端提供API,后端服务架构是 控制器+数据模型 或者 纯控制器。
View:View是作为视图模板,用于定义结构、布局。它自己不处理数据,只是将ViewModel中的数据展现出来。此外为了和ViewModel产生关联,那么还需要做的就是数据绑定的声明,指令的声明,事件绑定的声明。ViewModel和View之间是双向绑定,意思就是说ViewModel的变化能够反映到View中,View的变化也能够改变ViewModel的数据值。
ViewModel:ViewModel起着连接View和Model的作用,同时用于处理View中的逻辑。在MVC框架中,视图模型通过调用模型中的方法与模型进行交互,然而在MVVM中View和Model并没有直接的关系,在MVVM中,ViewModel从Model获取数据,然后应用到View中。个人理解:Web前端的webserver对View进行双向绑定渲染。
整个MVVM实际上实现了前后端分离,通过api来实现前后端交互,前端通过纯js或者双向绑定框架来渲染页面。
前后端不分离(crm页面写在crm项目里面 html thymeleaf(模板引擎) )
前后端分离
大概如:
数据库(MySQL、PostgreSQL)<—双向交互—>api(php、java、Python、node)<—双向交互—>ajax/fetch/websocket(node服务、jQ、js)<—双向绑定—>html(标签、css)。
MVVM有利于项目分工和升级,所谓对前后端分离。但也有缺点,就是不利于 。
MVC:服务端来渲染数据,老旧模式。MC属于纯后端,V属于前端,js权重不高,有利于SEO。
万物基于api,一套api可以针对小程序、app、前端,为何不首先使用。需要SEO对部分,单独分离出项目,采用MVC渲染静态页面或者纯html即可。
2.3 MVVM图例解析
3.【掌握】IDEA开发环境的配置
3.1 安装插件
3.2 创建前端项目
4.【掌握】安装和部署
https://cn.vuejs.org/v2/guide/installation.html
4.1 直接下载并用 script 标签引入
Vue 会被注册为一个全局变量。
在开发环境下不要使用压缩版本,不然你就失去了所有常见错误相关的警告!
开发版本包含完整的警告和调试模式
https://cn.vuejs.org/v2/guide/installation.html
4.2 NPM【后面讲】
在用 Vue 构建大型应用时推荐使用 NPM 安装[1]。NPM 能很好地和诸如 webpack 或 Browserify 模块打包器配合使用。同时 Vue 也提供配套工具来开发单文件组件。
最新稳定版
npm install vue
4.3 导入js到项目里面
4.4 第一个Vue应用HelloWorld
1.idea下载插件 (因为下了插件有提示)Vue.js
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>helloVue</title>
</head>
<body>
<!--声明一个页面容器-->
<div id="app">
用户名:{{username}} <br>
性别:<span v-text="sex"></span><br>
性别:<span v-text="sex=='男'?'汉子':'妹子'"></span><br>
备注:{{remark}}<br>
备注:<span v-html="remark"></span>
<input type="button" value="点我" @click="clickMe(1)" >
</div>
</body>
<script src="../js/vue.js"></script>
<script>
//创建一个Vue实例
let vue=new Vue({
//指定个vue实例和页面的哪个容器关联
el: "#app",
data:{
username:'小明',
age:22,
sex:'男',
remark:'<font color=red>一个牛B的男人</font>'
},
methods:{
// clickMe(id){
// alert(id)
// }
clickMe:function (id) {
alert(id)
}
}
})
</script>
</html>
4.5 配置页面模板
5.【掌握】v-text,v-html,v-pre,v-once指令
5.1 概述
Vue.js 使用了基于 HTML 的模板语法,允许开发者声明式地将 DOM 绑定至底层 Vue 实例的数据。所有 Vue.js 的模板都是合法的 HTML ,所以能被遵循规范的浏览器和 HTML 解析器解析。
在底层的实现上,Vue 将模板编译成虚拟 DOM 渲染函数。结合响应系统,Vue 能够智能地计算出最少需要重新渲染多少组件,并把 DOM 操作次数减到最少。
5.2 v-text
v-text主要用来更新textContent,可以等同于JS的innerText属性。
<span v-text="msg"></span>
这两者等价:
<span>{{msg}}</span>
5.3 v-html
双大括号的方式会将数据解释为纯文本,而非HTML。为了输出真正的HTML,可以用v-html指令。它等同于JS的innerHtml属性。
或者jquery的$().html(aaa)
<div v-html="rawHtml"></div>
这个div的内容将会替换成属性值rawHtml,直接作为HTML进行渲染。
5.4 v-pre
v-pre主要用来跳过这个元素和它的子元素编译过程。可以用来显示原始的Mustache标签。跳过大量没有指令的节点加快编译。
<div id="app">
<span v-pre>{{message}}</span> //这条语句不进行编译
<span>{{message}}</span>
</div>
最终仅显示第二个span的内容
5.5 v-once
v-once关联的实例,只会渲染一次。之后的重新渲染,实例极其所有的子节点将被视为静态内容跳过,这可以用于优化更新性能。
<span v-once>This will never change:{{msg}}</span> //单个元素
<div v-once>//有子元素
<h1>comment</h1>
<p>{{msg}}</p>
</div>
上面的例子中,msg即使产生改变,也不会重新渲染。
5.6 案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>02基本指令.html</title>
</head>
<body>
<!--声明一个页面容器-->
<div id="app">
<h1> v-text ===js里面innerText</h1>
用户名:{{username}} <br>
用户名:<span v-text="username"></span> <br>
备注:{{remark}} <br>
备注:<span v-text="remark"></span> <br>
年龄:<span v-text="age>60?'老年':'青年'"></span> <br>
年龄:{{age>60?'老年':'青年'}} <br>
年龄:{{age}} <br>
<hr>
<h1> v-html ===js里面的innerHTML</h1>
用户名:<span v-html="username"></span> <br>
备注:<span v-html="remark"></span> <br>
<hr>
<h1>v-pre 主要用来跳过这个元素和它的子元素编译过程</h1>
<span v-pre>{{username}}</span>
<hr>
<h1>v-once 这里面的元素是在页面加载时渲染一次,后面如果相关属性发生变化里面的值是不会变的</h1>
<span v-once>{{age}}</span>
<button @click="addAge">添加年龄</button>
<button @click="reduceAge">减少年龄</button>
</div>
</body>
<script src="../js/vue.js"></script>
<script>
//创建一个Vue实例
let vue=new Vue({
//指定个vue实例和页面的哪个容器关联
el: "#app",
data:{
username:'小明',
remark:'<font color=red>一个牛B的男人</font>',
age:22
},
methods:{
addAge(){
this.age++;
},
reduceAge(){
this.age--;
}
}
})
</script>
</html>
6.【掌握】属性绑定、事件绑定、双向绑定
涉及指令
1,v-bind 字面意思为绑定。是vue中提供的用户绑定属性的指令。v-bind可简写成:
2,v-on 事件绑定指令 可以简写成@
3,v-model 只能用于表单元素的双向绑定指令
6.1 属性绑定
在以前的开发中。我们使用title属性去设置鼠标悬浮的显示值,在vue 中可以使用V-bind去动态设置属性,以title为例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>03属性绑定.html</title>
</head>
<body>
<!--声明一个页面容器-->
<div id="app">
<img src="../images/mz.jpg" title="这是一个大妹子" width="320" height="480">
<img v-bind:src="imgPath" v-bind:title="title" width="320" height="480">
<img :src="imgPath" :title="title" width="320" height="480">
<hr>
<a href="http://www.baidu.com">百度</a><br>
<a v-bind:href="sinaUrl">{{sinaTitle}}</a><br>
<a :href="sinaUrl">{{sinaTitle}}</a><br>
</div>
</body>
<script src="../js/vue.js"></script>
<script>
//创建一个Vue实例
let vue=new Vue({
//指定个vue实例和页面的哪个容器关联
el: "#app",
data:{
imgPath:'../images/mz.jpg',
title:"这是一个大妹子",
sinaUrl:'http://www.sina.com.cn',
sinaTitle:"去新浪"
},
methods:{
// clickMe(id){
// alert(id)
// }
clickMe:function (id) {
alert(id)
},
addHandler(){
this.score++
},
reduceHandler(){
this.score--
}
}
})
</script>
</html>
6.2 事件绑定(v-model 一般用于表单)
在以前的开发中。我们使用onclick等属性去设置点击事件,在vue 中可以使用v-on去设置方式,可简写成@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>04事件绑定.html</title>
</head>
<body>
<h2>单击 双击 改变 进入 移出 移动 按下 松开 得到焦点 失去焦点</h2>
<!--声明一个页面容器-->
<div id="app">
<input type="button" v-on:click="testClick" value="单击事件绑定">
<input type="button" @click="testClick" value="单击事件绑定简写">
|
<input type="button" v-on:dblclick="testdbClick" value="双击事件绑定">
<input type="button" @dblclick="testdbClick" value="双击事件绑定简写">
|
<select @change="changeValue">
<option value="武汉1">武汉1</option>
<option value="武汉2">武汉2</option>
<option value="武汉3">武汉3</option>
<option value="武汉4">武汉4</option>
</select>
|
<input type="text" @focus="getFocus" @blur="lostFocus" :value="val">
<hr>
<div style="width: 300px;height: 300px;border: 2px solid green;text-align: center"
@mouseenter="testMouseenter"
@mouseleave="testMouseleave"
@mousedown="testMousedown"
@mouseup="testMouseup"
@mousemove="testMousemove"
>
{{content}}
</div>
</div>
</body>
<script src="../js/vue.js"></script>
<script>
//创建一个Vue实例
let vue=new Vue({
//指定个vue实例和页面的哪个容器关联
el: "#app",
data:{
val:'',
content:''
},
methods:{
testClick(){
console.log("单击")
},
testdbClick(){
console.log("双击")
},
changeValue(val){
console.log("改变",val.srcElement.value)
},
getFocus(){
console.log("得到焦点")
this.val='得到焦点';
},
lostFocus(){
console.log("失去焦点")
this.val='失去焦点'
},
testMouseenter(event){
this.content="鼠标进入"
console.log("进入",event)
},
testMouseleave(event){
this.content="鼠标离开"
console.log("离开",event)
},
testMousedown(event){
this.content="鼠标按下"
console.log("按下",event)
},
testMouseup(event){
this.content="鼠标松开"
console.log("松开",event)
},
testMousemove(event){
console.log(event)
this.content="移动 x="+event.offsetX+" y="+event.offsetY
console.log("移动")
}
}
})
</script>
</html>
6.3 双向绑定v-model
v-model 只能用于表单元素的双向绑定指令
v-bind是单向绑定
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>05双向绑定.html</title>
</head>
<body>
<h2>双向绑定</h2>
<!--声明一个页面容器-->
<div id="app">
<div>{{score}}</div>
<hr>
<input type="text" name="score" placeholder="请输入分数" v-model="score">
<input type="button" @click="addScore" value="+">
<input type="button" @click="reduceScore" value="-">
</div>
</body>
<script src="../js/vue.js"></script>
<script>
//创建一个Vue实例
let vue=new Vue({
//指定个vue实例和页面的哪个容器关联
el: "#app",
data:{
score:100
},
methods:{
addScore(){
this.score++;
},
reduceScore(){
this.score--;
}
}
})
</script>
</html>
6.4 双向绑定v-model 小练习
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="../js/vue.js"></script>
</head>
<body>
<div id="app">
<div>
<input type="text" v-model="num1">
<select v-model="opt">
<option>+</option>
<option>-</option>
<option>*</option>
<option>÷</option>
</select>
<input type="text" v-model="num2">
<input type="button" value="=" @click="compute">
<input type="text" v-model="result">
</div>
</div>
</body>
<script>
let vue = new Vue({
el: "#app",
data: {
opt:"+",
num1: undefined,
num2: undefined,
result: undefined,
},
methods: {
compute() {
switch (this.opt) {
case "+":
// this.result=new Number(this.num1)+new Number(this.num2)
this.result=parseFloat(this.num1)+parseFloat(this.num2)
break
case "-":
this.result=parseFloat(this.num1)-parseFloat(this.num2)
break;
case "*":
this.result=parseFloat(this.num1)*parseFloat(this.num2)
break;
case "÷":
this.result=parseFloat(this.num1)/parseFloat(this.num2)
break;
}
}
}
})
</script>
</html>
7.【重要】条件渲染v-if v-show
7.1 相关指令
1,v-if
2,v-else
3,v-else -if
4,v-show
7.2 v-if
v-if可以实现条件渲染,Vue会根据表达式的值的真假条件来渲染元素。
<div id="app">
<a v-if="ok">yes</a>
</div>
<script>
var vue = new Vue({
el: '#app',
data: {
ok:false,
}
})
</script>
如果属性值ok为true,则显示。否则,不会渲染这个元素。
7.3 v-else
v-else是搭配v-if使用的,它必须紧跟在v-if或者v-else-if后面,否则不起作用。
<a v-if="ok">yes</a>
<a v-else>No</a>
7.4 v-else-if
v-else-if充当v-if的else-if块,可以链式的使用多次。可以更加方便的实现switch语句。
<div id="app">
<div v-if="type==='A'">
A
</div>
<div v-else-if="type==='B'">
B
</div>
<div v-else-if="type==='C'">
C
</div>
<div v-else>
Not A,B,C
</div>
</div>
<script>
var vue = new Vue({
el: '#app',
data: {
ok:false,
type:'A'
}
})
</script>
7.5 v-show
<h1 v-show="ok">hello world</h1>
也是用于根据条件展示元素。和v-if不同的是,如果v-if的值是false,则这个元素被销毁,不在dom中。但是v-show的元素会始终被渲染并保存在dom中,它只是简单的切换css的dispaly属性。
注意:v-if有更高的切换开销
v-show有更高的初始渲染开销。
因此,如果要非常频繁的切换,则使用v-show较好;如果在运行时条件不太可能改变,则v-if较好
7.6 案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="../js/vue.js"></script>
</head>
<body>
<div id="app">
<div>
<input type="text" v-model="score">
<div v-if="score>=90">
优秀
</div>
<div v-else-if="score>=80">
良好
</div>
<div v-else-if="score>=70">
一般
</div>
<div v-else-if="score>=60">
及格
</div>
<div v-else>
不及格
</div>
<input type="button" value="点击" @click="flag=!flag">{{flag}}
<div v-show="flag">
我是DIV里面的内容
</div>
</div>
</div>
</body>
<script>
let vue = new Vue({
el: "#app",
data: {
flag: false,
score:100
},
methods: {
}
})
</script>
</html>
8.【重点】列表渲染v-for
8.1 v-for
用v-for指令根据遍历数组来进行渲染 前端不叫集合
有下面两种遍历形式
<div v-for="(item,index) in items"></div> //使用in,index是一个可选参数,表示当前项的索引
<div v-for="item in items"></div> //使用in
下面是一个例子,并且在v-for中,拥有对父作用域属性的完全访问权限。
8.2 v-for案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="../js/vue.js"></script>
</head>
<body>
<div id="app">
<p>
<div v-for="item in arr1">
{{item}}
</div>
</p>
<p>
<div v-for="(item,index) in arr1">
{{item}}---{{index}}
</div>
</p>
<p>
<div v-for="(item,index) in userList">
{{item.id}}--{{item.name}}--{{item.address}}--{{item.sex==1?"男":"女"}}
</div>
</p>
<p>
<table border="1" cellspacing="0" width="100%" cellpadding="0">
<tr>
<th>编号</th>
<th>姓名</th>
<th>地址</th>
<th>性别</th>
</tr>
<tr align="center" v-for="user in userList" >
<td v-text="user.id"></td>
<td>{{user.name}}</td>
<td v-text="user.address"></td>
<td>
{{user.sex==1?"男":"女"}}
</td>
</tr>
</table>
</p>
<p>
<select v-model="jg">
<option v-for="item in options" :value="item.id">{{item.name}}</option>
</select>
<br>
{{jg}}
</p>
<input type="button" value="添加一个用户" @click="addUser">
</div>
</body>
<script>
let vue = new Vue({
el: "#app",
data: {
arr1: ["a","b","c","d","e"],
userList:[
{id:1,name:"小明",address:"武汉",sex:1},
{id:2,name:"小红",address:"东莞",sex:0},
{id:3,name:"小芳",address:"佛山",sex:0},
{id:4,name:"小丽",address:"深圳",sex:0}
],
options:[
{id:1,name:"北京"},
{id:2,name:"上海"},
{id:3,name:"武汉"},
{id:4,name:"深圳"}
],
jg:undefined
},
methods: {
addUser() {
this.userList.push({id:5,name:"小苏",address:"琅琊榜",sex:1})
}
}
})
</script>
</html>
8.3 v-for-CRUD案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>单面页面CRUD案例</title>
<script src="../js/vue.js"></script>
</head>
<body>
<div id="app">
<p>
<input type="number" placeholder="编号" style="width: 50px" v-model="user.id">
<input type="text" placeholder="姓名" style="width: 100px" v-model="user.name">
<input type="text" placeholder="地址" style="width: 150px" v-model="user.address">
<select v-model="user.sex">
<option value="1">男</option>
<option value="0">女</option>
</select>
<button @click="addUser">添加</button>
<input type="text" placeholder="姓名" v-model="searchName">
<button @click="doSearch">搜索</button>
</p>
<hr>
<p>
<table border="1" cellspacing="0" width="100%" cellpadding="0">
<tr>
<th>编号</th>
<th>姓名</th>
<th>地址</th>
<th>性别</th>
<th>操作</th>
</tr>
<tr align="center" v-for="(user,index) in userList" >
<td v-text="user.id"></td>
<td>{{user.name}}</td>
<td v-text="user.address"></td>
<td>
{{user.sex==1?"男":"女"}}
</td>
<td>
<button @click="toUpdate(user)">修改</button>
<button @click="doDelete(index)">删除</button>
</td>
</tr>
</table>
</p>
<p>
<input type="number" readonly placeholder="编号" style="width: 50px" v-model="update.id">
<input type="text" placeholder="姓名" style="width: 100px" v-model="update.name">
<input type="text" placeholder="地址" style="width: 150px" v-model="update.address">
<select v-model="update.sex">
<option value="1">男</option>
<option value="0">女</option>
</select>
<button @click="updateUser">修改</button>
</p>
</div>
</body>
<script>
let vue = new Vue({
el: "#app",
data: {
userList:[
{id:1,name:"小明",address:"武汉",sex:1},
{id:2,name:"小红",address:"东莞",sex:0},
{id:3,name:"小芳",address:"佛山",sex:0},
{id:4,name:"小丽",address:"深圳",sex:0}
],
//添加的属性绑定
user:{
id:undefined,
name:undefined,
address:undefined,
sex:0
},
update:{
id:undefined,
name:undefined,
address:undefined,
sex:0
},
searchName:undefined
},
methods: {
//添加用户
addUser() {
this.userList.push({
id: this.user.id,
name: this.user.name,
address: this.user.address,
sex: this.user.sex
});
},
//搜索
doSearch(){
if(this.searchName){
//注意这个方法(currentValue,index)
let arr=this.userList.filter(item=>{
return item.name.indexOf(this.searchName)>=0
})
// alert(JSON.stringify(arr))
//上面已拿到过滤的数据,直接赋值给userList
this.userList=arr;
}
},
//去更新
toUpdate(user){
this.update.id=user.id;
this.update.name=user.name;
this.update.address=user.address;
this.update.sex=user.sex;
},
//更新
updateUser(){
let arr=this.userList.map(item=>{
if(item.id==this.update.id){
item.name=this.update.name;
item.address=this.update.address;
item.sex=this.update.sex;
}
return item;
})
alert(JSON.stringify(arr))
},
//删除
doDelete(index){
//参数1 开始删除的索引位置 参数2 从索引位置开始后现删除几个
this.userList.splice(index,1);
}
}
})
</script>
</html>
9.【了解】过滤器的使用
作用就是格式化
9.1 概述
Vue.js 允许你自定义过滤器,可被用于一些常见的文本格式化。过滤器可以用在两个地方:双花括号插值和 v-bind 表达式 (后者从 2.1.0+ 开始支持)。过滤器应该被添加在 JavaScript 表达式的尾部,由“管道”符号指示:
过滤器分为两种
Ø 全局过滤器 所有Vue实例里面都可以使用Vue.filter
Ø 局部过滤器 当前的Vue实例里面可以使用
9.2 代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="../js/vue.js"></script>
</head>
<body>
<div id="app">
<div>{{money}}</div>
<div>{{money|moneyHandler}}</div>
<div>{{birth}}</div>
<div>{{birth|birthHandler}}</div>
<div>{{sex==1?"男":"女"}}</div>
<div>{{sex|sexHandler}}</div>
</div>
<hr>
<div id="app2">
<div>{{money}}</div>
<div>{{money|moneyHandler}}</div>
<div>{{birth}}</div>
<div>{{birth|birthHandler}}</div>
<div>{{sex==1?"男":"女"}}</div>
<div>{{sex|sexHandler}}</div>
</div>
</body>
<script>
//全局过滤器的声明
// Vue.filter("sexHandler",function (value) {
// return value==1?"汉子":"妹子"
// })
// Vue.filter("moneyHandler",function (value) {
// return value.toFixed(2)//保留两位小数
// })
// Vue.filter("birthHandler",function (value) {
// return value.getFullYear()+"-"+(value.getMonth()+1)+"-"+value.getDate()+" "+value.getHours()+":"+value.getMinutes()+":"+value.getSeconds()
// })
let vue = new Vue({
//在过滤器里面无法访问data和methods
filters:{
sexHandler(value){
return value==1?"汉子":"妹子"
},
moneyHandler(value){
return value.toFixed(2)//保留两位小数
},
birthHandler:function (value) {
return value.getFullYear()+"-"+(value.getMonth()+1)+"-"+value.getDate()+" "+value.getHours()+":"+value.getMinutes()+":"+value.getSeconds()
}
},
el: "#app",
data: {
money:9999.9193,
birth:new Date(),
sex:1
},
methods: {
}
})
let vue2 = new Vue({
el: "#app2",
filters:{
sexHandler(value){
return value==1?"汉":"妹"
},
moneyHandler(value){
return value.toFixed(3)//保留两位小数
},
birthHandler:function (value) {
return value.getFullYear()+"-"+(value.getMonth()+1)+"-"+value.getDate()
}
},
data: {
money:9999.9193,
birth:new Date(),
sex:1
},
methods: {
}
})
</script>
</html>
10.【了解】监听器的使用
10.1 作用
就是用来监听data里面的数据值是否发生变化。如果发生变化会触发监听器
10.2 案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>10监听器的使用.html</title>
<script src="../js/vue.js"></script>
</head>
<body>
<div id="app">
<div>
<input type="text" v-model="age">
<input type="text" v-model="user.age">
</div>
</div>
</body>
<script>
let vue = new Vue({
el: "#app",
//监听器
watch:{
age(newVal,oldVal){
console.log(newVal)
console.log(oldVal)
},
'user.age':function (newVal,oldVal) {
console.log(newVal)
console.log(oldVal)
}
},
data: {
age:18,
user:{
age:100,
}
},
methods: {
m1() {
}
}
})
</script>
</html>
11.【掌握】购物车
11.1 效果**
11.2 代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>11购物车.html</title>
<script src="../js/vue.js"></script>
</head>
<body>
<div id="app">
<table border="1" cellspacing="0" width="100%" cellpadding="0">
<tr>
<th>
<input type="checkbox" v-model="isCheckAll" @click="checkAll" />
</th>
<th>编号</th>
<th>商品名称</th>
<th>价格</th>
<th>数量</th>
<th>小计</th>
<th>备注</th>
<th>操作</th>
</tr>
<tr align="center" v-for="(item,index) in goodsList" >
<td>
<input type="checkbox" v-model="item.isChecked" @click="rowCheckBoxClick(item)" >
</td>
<td>{{item.id}}</td>
<td>{{item.goodsName}}</td>
<td>{{item.price|moneyHandler}}</td>
<td>
<button @click="reduceNum(item)">-</button>
{{item.num}}
<button @click="addNum(item)">+</button>
</td>
<td>{{item.amount|moneyHandler}}</td>
<td>{{item.remark}}</td>
<td>
<button @click="doDelete(index)">删除</button>
</td>
</tr>
<tr align="right" >
<td colspan="11">
应付:{{totalAmount|moneyHandler}}
<button>结算</button>
</td>
</tr>
</table>
</div>
</body>
<script>
Vue.filter("moneyHandler",function (value) {
return "¥"+value.toFixed(2)//保留两位小数
})
let vue = new Vue({
el: "#app",
data: {
goodsList:[
{isChecked:false,id:1,goodsName:'小霸王1',price:200,num:1,amount:200,remark:'牛逼'},
{isChecked:false,id:2,goodsName:'小霸王2',price:300,num:1,amount:300,remark:'牛逼'},
{isChecked:false,id:3,goodsName:'小霸王3',price:200,num:1,amount:200,remark:'牛逼'},
{isChecked:false,id:4,goodsName:'小霸王4',price:100,num:1,amount:100,remark:'牛逼'},
{isChecked:false,id:5,goodsName:'小霸王5',price:50,num:1,amount:50,remark:'牛逼'},
{isChecked:false,id:6,goodsName:'小霸王6',price:10,num:1,amount:10,remark:'牛逼'},
],
//是否全选
isCheckAll:false,
//选中的订单总金额
totalAmount:0,
},
methods: {
//全选全否
checkAll() {
this.isCheckAll=!this.isCheckAll;
this.goodsList.filter(item=>{
item.isChecked=this.isCheckAll;
})
this.computedTotalAmount();
},
//增加数量
addNum(goods){
goods.num++
//计算小计
goods.amount=goods.price*goods.num;
this.computedTotalAmount();
},
//减少数量
reduceNum(goods){
if(goods.num==1){
return;
}
goods.num--
//计算小计
goods.amount=goods.price*goods.num;
this.computedTotalAmount();
},
//行的checkbox点击事件
rowCheckBoxClick(goods){
goods.isChecked=!goods.isChecked
let flag=true;
this.goodsList.filter(item=>{
if(!item.isChecked){
flag=false;
}
})
//修改checkall的状态
this.isCheckAll=flag;
this.computedTotalAmount();
},
//删除
doDelete(index) {
this.goodsList.splice(index,1);
this.computedTotalAmount();
},
//统计总金额的方法、
computedTotalAmount(){
this.totalAmount=0;
this.goodsList.filter(item=>{
if(item.isChecked){
this.totalAmount+=item.amount;
}
})
}
}
})
</script>
</html>
12.【重点】生命周期(页面渲染顺序)【重点内容】
12.1 生命周期图【重点注意create方法】
12.2 代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>12生命周期.html</title>
<script src="../js/vue.js"></script>
</head>
<body>
<div id="app">
<div>{{count}}</div>
<div id="myDiv">我是DIV的内容</div>
<input type="button" value="添加" @click="m1">
</div>
</body>
<script>
let vue = new Vue({
el: "#app",//el==element
//这个是可用的生命周期的第一个方法
//这个方法里面 data和methods还没有初始化,所以不能使用this.xxx来调用data里面的属性 及methods里面的方法
beforeCreate(){
console.log("beforeCreate---"+this.count)
},
//vue对象创建成功。此时可以 data和methods已初始化完成,可以使用this.xxx来调用data里面的属性和methods里面的方法
//【重点方法】一般在这里面发送网络请求。因为这个方法里面可以最早的访问到data和methods
created(){
console.log("created---"+this.count)
this.m1();
},
//这个方法是内存里面编译好的模板还没有挂载到浏览器之前执行的方法这里面不能操作页面的dom对象
beforeMount(){
console.log("beforeMount---"+this.count)
var myDiv = document.getElementById("myDiv");
myDiv.innerText="hello"
console.log(myDiv)
},
//【重点】页面挂载完成的方法,编译好的模板已把页面替换了 这里是最早可以操作页面dom对象的方法
mounted(){
console.log("mounted---"+this.count)
var myDiv = document.getElementById("myDiv");
myDiv.innerText="hello"
},
//data里面的数据有变化,而模板里面又取了data里面的值,那么就当这个值变化时就会被触发
beforeUpdate(){
console.log("beforeUpdate--"+this.count)
},
//beforeUpdate执行之后页面的模板里面的数据替换完成之后,回调的方法
updated(){
console.log("updated--"+this.count)
},
//页面vue对象被销毁时触发的方法 里面还可以访问 data和methods(?)
beforeDestroy(){
console.log("beforeDestroy--"+this.count)
},
//页面vue对象已完成销毁 不能再访问data和methods
destroyed(){
console.log("destroyed--"+this.count)
},
data: {
count: 0,
userList:[]
},
methods: {
m1() {
console.log("m1")
var myDiv = document.getElementById("myDiv");
myDiv.innerText="m1m1m1m1m1m1m1m1m1"
this.count++;
}
}
})
</script>
</html>