Java零基础——Vue基础篇

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.offsetYconsole.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)breakcase "-":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))//上面已拿到过滤的数据,直接赋值给userListthis.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和methodsfilters:{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.isCheckedlet 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和methodscreated(){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和methodsdestroyed(){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>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/628145.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring Boot - Application Events 的发布顺序_ApplicationStartingEvent

文章目录 概述Code源码分析 概述 Spring Boot 的广播机制是基于观察者模式实现的&#xff0c;它允许在 Spring 应用程序中发布和监听事件。这种机制的主要目的是为了实现解耦&#xff0c;使得应用程序中的不同组件可以独立地改变和复用逻辑&#xff0c;而无需直接进行通信。 …

VMware虚拟机忘记密码操作方法

下面已openEuler虚拟机为例&#xff1a; 1、点击重启时&#xff0c;一直按esc&#xff08;鼠标点击一下&#xff0c;确保鼠标在你的虚拟机里面&#xff09; 2、一直到进入到如下页面按e键&#xff08;可能会略有不同&#xff09; 3、按e键后跳转到如下页面 4、在该页面输入 in…

高级定时器

本节主要介绍以下内容&#xff1a; 定时器简介 高级定时器功能框图讲解 一、定时器简介 定时器功能 &#xff1a;定时、输出比较、输入捕获、断路输入 定时器分类 &#xff1a;基本定时器、通用定时器、高级定时器 定时器资源 &#xff1a;F103有2个高级定时器、4个通…

c语言-数据类型(下)

目录 4.实型变量 5.字符常量 直接常量&#xff1a; 转义字符&#xff1a; 6.字符变量 7.字符串常量 五、输出格式总结 整型&#xff1a; 浮点型&#xff1a; 字符及字符串&#xff1a; 指针&#xff08;地址&#xff09;&#xff1a; 六、typedef 七、sizeof一个问…

Matlab并行编程之GPU

Matlab并行编程之GPU Matlab提供GPU上计算支持: 基础数据类型(gpuArray和对应API),支持GPU计算的内置函数和多个工具包,支持PTX内核对象加载,支持MEX函数使用CUDA C/C开发等。对大规模数据处理&#xff0c;复杂计算&#xff0c;利用GPU计算能提供显著的性能加速效果. Matlab同…

Docker之网络配置的使用

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是君易--鑨&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的博客专栏《Docker之网络配置的使用》。&#x1f3af;&…

OpenHarmony——Linux之IR驱动

Linux之IR驱动 背景 在光谱中波长自760nm至400um的电磁波称为红外线&#xff0c;它是一种不可见光。红外遥控成本很低&#xff0c;以前广泛应用在电视&#xff0c;空调等电器的控制上面&#xff0c;现在随着蓝牙遥控器慢慢普及&#xff0c;红外遥控越来越少&#xff0c;但在某…

图像处理:孤立点的检测

图像处理-孤立点的检测 孤立点的检测在图像处理中通常涉及到检测图像中的突变或者边缘&#xff0c;而使用二阶导数是一种常见的方法。一阶导数可以帮助找到图像中的边缘&#xff0c;而二阶导数则有助于检测边缘上的峰值&#xff0c;这些峰值可能对应于孤立点或者特殊的图像结构…

AI大模型预先学习笔记二:prompt提问大模型、langchain使用大模型框架、fine tune微调大模型

文章目录 一、Prompt Engineering&#xff08;怎么去提问大模型&#xff09;1&#xff09;环境准备2&#xff09;交互代码的参数备注3&#xff09;交互代码 二、LangChain&#xff08;一个框架去使用大模型&#xff09;1&#xff09;LangChain核心介绍&#xff1a;I/O模块、数据…

TypeError: (0 , _ahooks.createUpdateEffect) is not a function

版本 "next": "14.0.4", "antd-mobile": "^5.34.0", next中使用antd-mobile可困难了.主要是因为antd-mobile不支持ssr 1.下载antd-mobile包,在next.config.js中加入 transpilePackages: [antd-mobile,], 2.在页面中引入antd-mobi…

蓝桥杯备赛day02 -- 算法训练题 拿金币Java

目录 题目&#xff1a; 问题描述 输入格式 输出格式 解题过程 第一步 定义dp数组 第二步 确定 dp 数组递推公式 第三步 dp数组的初始化 第四步 dp数组的遍历顺序 第五步 举例说明 报错&#xff1a;内存超限 用dp数组去存储位置上的金币 dp数组从二维降为一维 收获&a…

【MCAL】MCU模块详解

目录 前言 正文 1. MCU模块介绍 2. MCU依赖的模块 3. MCU模块提供服务 3.1 时钟的初始化 3.2 MCU模式的配置 3.3 MCU软件复位功能 3.4 RAM的初始化 4.MCU重要数据类型 4.1 Mcu_ResetType 4.2 Mcu_ModeType 5. MCU重要API 5.1 Mcu_Init 5.2 Mcu_InitClock 5.3 M…

信息系统安全——Linux 访问控制机制分析

实验 4 Linux 访问控制机制分析 4.1 实验名称 《Linux 访问控制机制分析》 4.2 实验目的 1 、熟悉 Linux基本访问控制机制使用和原理 2 、熟悉 Linux S 位的作用和使用 3 、熟悉强制访问控制 Selinux 原理及其使用 4.3 实验步骤及内容 1 、Linux 基本访问控制机制 &#xff08…

vue el-table 多选框回填

主要代码: //选中列&#xff0c;所有列&#xff0c;表名toggleSelection(selectRows, totalRows, tablename) {this.$refs.table.clearSelection();if (selectRows.length > 0) {this.$nextTick(() > {selectRows.forEach(item > {totalRows.forEach(item1 > {if (…

C语言天花板——指针(经典题目)

指针我们已经学习的差不多了&#xff0c;今天我来给大家分享几个经典的题目&#xff0c;来让我们相互学习&#x1f3ce;️&#x1f3ce;️&#x1f3ce;️ int main() {int a[4] { 1, 2, 3, 4 };int* ptr1 (int*)(&a 1);int* ptr2 (int*)((int)a 1);printf("%x,%…

连锁品牌如何引流获客?小魔推短视频矩阵助你流量爆棚

近几年因为大环境的影响&#xff0c;大多数实体行业的生意都不太好做&#xff0c;为了帮助更多实体行业提升品牌知名度&#xff0c;带来更多的流量与转化&#xff0c;餐赞小魔推也在不断的更新迭代&#xff0c;同时考虑到了单门店与连锁品牌使用的便捷性。 目前针对连锁品牌方&…

功能权限篇

文章目录 1. 如何设计一套权限系统1.1 目标1.2 权限模型1.2.1 模型一RBAC1.2.2 模型二ABAC 2.如何实现菜单的创建&#xff1f;2.1 表结构2.2 前端实现2.3 后端实现 3. 如何实现角色的创建&#xff1f;4.如何给用户分配权限 —— 将菜单赋予角色&#xff1f;5.如何给用户分配权限…

【目标跟踪】跨相机如何匹配像素

文章目录 前言一、计算思路二、代码三、结果 前言 本本篇博客介绍一种非常简单粗暴的方法&#xff0c;做到跨相机像素匹配。已知各相机内外参&#xff0c;计算共视区域像素投影&#xff08;不需要计算图像特征&#xff09;。废话不多说&#xff0c;直接来&#xff0c;见下图。…

QT -狗狗管理工具

QT -狗狗管理工具 一、演示效果二、UML三、关键代码四、程序链接 一、演示效果 二、UML 三、关键代码 #include <QFrame> #include <QHBoxLayout> #include <QVBoxLayout> #include <QLabel> #include <QSizePolicy> #include <QDialog> …

算法第十八天-打家劫舍Ⅱ

打家劫舍Ⅱ 题目要求 解题思路 [打家劫舍Ⅱ]是说两个相邻的房间不能同时偷&#xff0c;并且首尾两个房间是相邻的&#xff08;不能同时偷首尾房间&#xff09;明显是基于[打家劫舍Ⅰ]做的升级。[打家劫舍Ⅰ]也是说两个相邻的房间不能同时偷&#xff0c;但是首尾房间不是相邻的…