Loading... ## 一.前后端分离 既然我们在开发中使用前后端分离模式,也就是前端拿到后端的数据时怎么处理,怎么输出都有前端自己来实现,这样就需要写大量的js代码,而为了简化js的代码,就衍生出了很多的框架,比如jquery,Angular,Vue,React等。 ## 二 Vue.js介绍 ### 1.什么是Vue.js Vue.js是一个构建数据驱动的 web 界面的渐进式框架。Vue.js 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。核心是一个响应的数据绑定系统。 ### 2.Vue的特点 #### 2.1 响应式编程 ``` 当数据发生改变时,自动更新视图。 ``` #### 2.2 组件化 ``` UI页面映射出一个组件树 组件可重用,可维护性好。 ``` ### 3.Vue的优势 ``` vue是轻量级框架、简单易学、双向数据绑定、组件化、视图、数据和结构的分离、虚拟DOM、运行速度快。 ``` ``` 而且vue是单页面应用,使页面局部刷新,不用每次跳转页面都要请求所有数据和dom,这样大大加快了访问速度和提升用户体验。而且他的第三方ui库很多节省开发时间。 ``` ### 4.Vue的响应式原理(MVVM) ``` Vue有一个重要特点是当数据发生变化时,可以自动更新视图,那这个是怎么实现的。这是因为Vue采用了MVVM架构模式。那什么是MVVM呢。 ``` #### 4.1MVC和MVVM结构对比 ``` MVC模式结构图 ``` ![](https://blog.fivk.cn/usr/uploads/2023/03/1647148951.png)V ``` MVVM模式结构图 ``` ![](https://blog.fivk.cn/usr/uploads/2023/03/423556987.png) 可以看到MVVM是一个MVC的增强版,正式连接了视图和模型,将表示逻辑从Controller移出放到一个新的对象里,即ViewModel。它实现了View和Model的自动同步,即当Model的属性改变时,我们不用再自己手动操作Dom元素来改变View的显示,而是改变属性后该属性对应的View层显示会自动改变。 #### 4.2 MVVM的组成部分 ##### 1.View View 是视图层,也就是用户界面。前端主要由 HTML 和 CSS 来构建,为了更方便地展现 ViewModel 或者 Model 层的数据,已经产生了各种各样的前后端模板语言,比如 FreeMarker、Thymeleaf 等等,各大 MVVM 框架如 Vue.js,AngularJS,EJS 等也都有自己用来构建用户界面的内置模板语言。 ##### 2.Model Model 是指数据模型,泛指后端进行的各种业务逻辑处理和数据操控,主要围绕数据库系统展开。这里的难点主要在于需要和前端约定统一的 接口规则 ##### 3.ViewModel ViewModel 是由前端开发人员组织生成和维护的视图数据层。在这一层,前端开发者对从后端获取的 Model 数据进行转换处理,做二次封装,以生成符合 View 层使用预期的视图数据模型。 **需要注意的是 ViewModel 所封装出来的数据模型包括视图的状态和行为两部分,而 Model 层的数据模型是只包含状态的.** 比如页面的这一块展示什么,那一块展示什么,这些都属于视图状态(展示); 页面加载进来时发生什么,点击这一块发生什么,这一块滚动时发生什么这些都属于视图行为(交互). 视图状态和行为都封装在了 ViewModel 里。这样的封装使得 ViewModel 可以完整地去描述 View 层。由于实现了双向绑定,ViewModel 的内容会实时展现在 View 层,这是激动人心的,因为前端开发者再也不必低效又麻烦地通过操纵 DOM 去更新视图。 MVVM 框架已经把最脏最累的一块做好了,我们开发者只需要处理和维护 ViewModel,更新数据视图就会自动得到相应更新,真正实现 事件驱动编程。 View 层展现的不是 Model 层的数据,而是 ViewModel 的数据,由 ViewModel 负责与 Model 层交互,这就完全解耦了 View 层和 Model 层,这个解耦是至关重要的,它是前后端分离方案实施的重要一环。 ## 三 Vue.js基础语法 ### 1 下载 方式1:Vue官网下载:https://v2.cn.vuejs.org/v2/guide/installation.html ![](https://blog.fivk.cn/usr/uploads/2023/03/4106563723.png) ``` 方式2: CDN ``` ### 2 第一个入门程序 ``` 开发Vue的工具很多,这里我们先使用之前讲解web前端时使用的工具Hbuilder ``` ``` Vue.js 的核心是实现了 MVVM 模式,它扮演的角色就是 ViewModel 层,那么我们的第一个应用程序就是展示她的 ``` **数据绑定** 功能,操作流程如下: #### 2.1 在Hbuilder中创建一个web项目 ![](https://blog.fivk.cn/usr/uploads/2023/03/1842882772.png) 再创建两个文件夹,一个是html放页面的,一个是js放vue.js的: ![](https://blog.fivk.cn/usr/uploads/2023/03/1835025038.png) #### 2.2 导入Vue.js ![](https://blog.fivk.cn/usr/uploads/2023/03/2969199074.png) #### 2.3 创建一个Vue实例 ,并将数据绑定到div中 ```html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <script src="../js/vue.js"></script> </head> <body> <div id="app"> {{msg}} </div> </body> <script> var v = new Vue({//创建一个Vue对象 el:"#app",//该Vue对象绑定在id为APP的一个容器上 data:{ msg:"hello Vue" } }); </script> </html> ``` 说明 ``` new Vue:创建vue对象,里面的el和data是属性。 el:'#app':绑定元素的 ID; data:{msg:"hello Vue"}:数据对象中有一个名为 `msg` 的属性,并设置了初始值 {{msg}}:在绑定的元素中使用 双花括号 将Vue创建的名为 msg 属性包裹起来,即可实现数据绑定功能。不需要自己写js赋值。 ``` #### 2.4 运行测试 ![](https://blog.fivk.cn/usr/uploads/2023/03/3245030545.png) #### 2.5 测试Vue的自动更新功能 Vue可以做到当数据发生改变时,自动更新视图 ![](https://blog.fivk.cn/usr/uploads/2023/03/3654920956.png) 说明: ```html 在之前的代码中,我们创建了一个名为 v 的 Vue 实例. var v = new Vue({//创建一个Vue对象 el:"#app",//该Vue对象绑定在id为APP的一个容器上 data:{ msg:"hello Vue" } }); 此时就可以在控制台直接输入 v.msg 来修改值,中间是可以省略 data 的,在这个操作中,我们并没有主动操作 DOM,就让页面的内容发生了变化,这就是借助了Vue的数据绑定功能实现的;MVVM 模式中要求 ViewModel 层就是使用 观察者模式 来实现数据的监听与绑定,以做到数据与视图的快速响应。 ``` ### 3.Vue实例的生命周期 #### 3.1 什么是Vue实例的生命周期 Vue 实例有一个完整的生命周期,也就是从开始创建、初始化数据、编译模板、挂载 DOM、渲染→更新→渲染、卸载等一系列过程,我们称这是 Vue 的生命周期。通俗说就是 Vue 实例从创建到销毁的过程,就是生命周期。 在 Vue 的整个生命周期中,它提供了一系列的事件,可以让我们在事件触发时注册 JS 方法,可以让我们用自己注册的 JS 方法控制整个大局,在这些事件响应方法中的 this 直接指向的是 Vue 的实例。 #### 3.2 Vue实例生命周期图 ![](https://blog.fivk.cn/usr/uploads/2023/03/618471238.png) #### 3.3 什么是生命周期钩子 生命周期钩子:就是生命周期事件的别名。生命周期钩子又叫生命周期函数 也叫生命周期事件。 #### 3.4 生命周期钩子函数有哪些 **创建期间的生命周期函数:** **beforeCreate**: 实例刚在内存中被创建出来,此时,还没有初始化好 data和methods属性。 触发时机:在实例初始化之后,数据观测(data observer) 和 event/watcher 事件配置之前被调用。 **created**: 实例已经在内存中创建完成。此时data和methods已经在内存中创建完成,但是还没有开始编译模板。 触发时机:实例已经创建完成之后被调用。 **beforeMount**: 此时已经完成了模板的编译,但是还没有挂载到页面中显示。 触发时机:挂载开始之前被调用 **mounted**: 此时,已经将编译好的模板,挂载到了页面指定的容器中显示。 触发时机:挂载到实例之后调用 **运行期间的生命周期函数:** **beforeUpdate**: 此时 data 中的状态值是最新的,但是界面上显示的 数据还是旧的,因为此时还没有开始重新渲染DOM节点。 触发时机:状态更新之前调用 **updated**: 此时 data 中的状态值和界面上显示的数据,都已经完成了更新,界面已经被重新渲染好了! 触发时机:实例更新完毕之后将会调用此函数 **销毁期间的生命周期函数:** **beforeDestroy**: 在这一步,实例仍然完全可用。 触发时机:实例销毁之前调用 **destroyed**: 调用之后Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。 触发时机:Vue 实例销毁后调用,组件销毁有很多种情况,比如页面关闭,页面跳转。 #### 3.5 测试生命周期 创建一个测试页面,写入需要测试的钩子函数 ```html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <script type="text/javascript" src="../js/vue.js" ></script> </head> <body> <div id="app"> <h1>{{message}}</h1> </div> <script> var v = new Vue({ el: '#app', data: { message: 'Vue的生命周期' }, beforeCreate: function() { console.group('------beforeCreate创建前状态------'); console.log("%c%s", "color:red" , "el : " + this.$el); console.log("%c%s", "color:red","data : " + this.$data); console.log("%c%s", "color:red","message: " + this.message) }, created: function() { console.group('------created创建完毕状态------'); console.log("%c%s", "color:red","el : " + this.$el); console.log("%c%s", "color:red","data : " + this.$data); console.log("%c%s", "color:red","message: " + this.message); }, beforeMount: function() { console.group('------beforeMount挂载前状态------'); console.log("%c%s", "color:red","el : " + (this.$el)); console.log("%c%s", "color:red","data : " + this.$data); console.log("%c%s", "color:red","message: " + this.message); }, mounted: function() { console.group('------mounted 挂载结束状态------'); console.log("%c%s", "color:red","el : " + this.$el); console.log("%c%s", "color:red","data : " + this.$data); console.log("%c%s", "color:red","message: " + this.message); }, beforeUpdate: function () { console.group('beforeUpdate 更新前状态===============》'); console.log("%c%s", "color:red","el : " + this.$el); console.log("%c%s", "color:red","data : " + this.$data); console.log("%c%s", "color:red","message: " + this.message); }, updated: function () { console.group('updated 更新完成状态===============》'); console.log("%c%s", "color:red","el : " + this.$el); console.log("%c%s", "color:red","data : " + this.$data); console.log("%c%s", "color:red","message: " + this.message); }, beforeDestroy: function () { console.group('beforeDestroy 销毁前状态===============》'); console.log("%c%s", "color:red","el : " + this.$el); console.log("%c%s", "color:red","data : " + this.$data); console.log("%c%s", "color:red","message: " + this.message); }, destroyed: function () { console.group('destroyed 销毁完成状态===============》'); console.log("%c%s", "color:red","el : " + this.$el); console.log("%c%s", "color:red","data : " + this.$data); console.log("%c%s", "color:red","message: " + this.message) } }) </script> </body> </html> ``` 页面运行以后,按F12,查看Console里的信息: ![](https://blog.fivk.cn/usr/uploads/2023/03/3845626479.png) 在Console中修改message的值: ![](https://blog.fivk.cn/usr/uploads/2023/03/2470159948.png) 关闭页面,会调用对应的销毁函数。 ### 4.Vue内部指令 #### 4.1 v-bind ``` v-bind 属性绑定 ``` 测试案例: ```html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <script src="../js/vue.js"></script> </head> <body> <div id="app"> <a v-bind:href="url">百度</a> <input type="text" v-bind:value="msg"/> </div> </body> <script> var v = new Vue({ el:"#app", data:{ url:"http://www.baidu.com", msg:"文本框的值" } }); </script> </html> ``` 说明: ``` v-bind后面是 :属性名=,"url"是找到data里面的属性url 当我们在控制台改变url和value时,对应值也会变化。类似的,我们还可以绑定其它属性,如src属性、class属性等 ``` v-bind也可以简化为: ``` <a :href="url">百度</a> <input type="text" :value="msg" /> ``` #### 4.2 v-text和 v-html ``` v-text用来输出双标签里的内容,内容中有标签,标签按原样显示 v-html也是用来输出双标签里的内容,内容中有标签,会解析标签 ``` 测试案例: ```html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <script type="text/javascript" src="../js/vue.js" ></script> </head> <body> <div id="app"> <!-- v-text的作用就是把数据直接当文本处理 --> <div v-text="msg" v-show="show"></div> <!-- v-html就是把数据当html处理,也就是会解析标签 --> <div v-html="msg" v-show="show"></div> </div> </body> <script> var v = new Vue({ el:"#app", data:{ msg:"<h1>盘龙居士</h1>", show:true //控制是否显示 } }); </script> </html> ``` 测试结果: ![](https://blog.fivk.cn/usr/uploads/2023/03/4031288412.png) #### 4.3 v-if,v-else-if,v-else > 双分支结构 测试案例: ```html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <script src="../js/vue.js"></script> </head> <body> <div id="app"> <!-- 这里的v-model是和下面的age双向绑定的,上面修改下面也修改 --> <input type="text" v-model="age"/> <div v-if="age<18">小孩子</div> <div v-else-if="age<50">青年</div> <div v-else-if="age<60">中年</div> <div v-else>老年</div> </div> </body> <script> var v = new Vue({ el:"#app", data:{ age:50 } }); </script> </html> ``` 说明: > 其实和咱们java里面一样的,无论是v-if还是v-else-if后面的值都必须是布尔值,为true的就显示 #### 4.4 v-for > 1.for循环普通数组 案例代码: ```html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <script src="../js/vue.js"></script> </head> <body> <div id="app"> <!-- 写上两个参数的时候前者是值,后者是角标 --> <div v-for="(v,k) in forDatas">{{v}}------{{k}}</div> <div>=============================</div> <!-- 只写一个参数的时候就表示值 --> <div v-for="item in forDatas">{{item}}</div> </div> </body> <script> var v = new Vue({ el:"#app", data:{ forDatas:[23,43,31,56,53,27] } }); </script> </html> ``` ![](https://blog.fivk.cn/usr/uploads/2023/03/810587308.png) 说明: > 写上两个参数的时候前者是值,后者是角标,只写一个参数的时候就表示值 > 2.for循环对象数组 案例代码: ```html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <script src="../js/vue.js"></script> </head> <body> <div id="app"> <table> <!-- item是拿到了json数组里面的每一个json --> <tr v-for="item in userList"> <!-- 从json里面拿到每一个值 --> <td>{{item.username}}</td> <td>{{item.age}}</td> <td>{{item.sex}}</td> </tr> </table> </div> </body> <script> var v = new Vue({ el:"#app", data:{ userList:[ {username:"panlong",age:18,sex:"男"}, {username:"刘德华",age:28,sex:"男"}, {username:"梅艳芳",age:18,sex:"女"}] } }); </script> </html> ``` ![](https://blog.fivk.cn/usr/uploads/2023/03/345174679.png) > 3.for循环对象 案例代码: ```html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <script src="../js/vue.js"></script> </head> <body> <div id="app"> <!-- 可以放在div内部,让内部div重复生成 --> <!-- 只写一个item的时候表示的就是值 --> <div v-for="item in userInfo"> <div>{{item}}</div> </div> <div>-----------------------</div> <!-- 写两个参数,前者表示值,后者表示键 没有写内部div直接重复生成当前div--> <div v-for="(v,k) in userInfo">{{k}}--{{v}}</div> </div> </body> <script> var v = new Vue({ el:"#app", data:{ userInfo:{username:"panlong",age:18,sex:"男"} } }); </script> </html> ``` ![](https://blog.fivk.cn/usr/uploads/2023/03/896186270.png) > 4.for循环数字 案例代码: ```html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <script src="../js/vue.js"></script> </head> <body> <div id="app"> <div v-for="i in 10">{{i}}</div> </div> </body> <script> // 这里你要注意,虽然上面循环的数据并不在我们下面的定义 // 但是这里的new Vue并且绑定到id为app的容器是不能少的 // 因为上面的v-for也是Vue里面的,得依托于这个对象 var v = new Vue({ el:"#app", }) </script> </html> ``` ![](https://blog.fivk.cn/usr/uploads/2023/03/841463217.png) ### 5.Vue数据双向绑定 #### 5.1.什么是双向数据绑定 Vue.js 是一个 MVVM 框架,即数据双向绑定,即当数据发生变化的时候,视图也就发生变化,当视图发生变化的时候,数据也会跟着同步变化。这也算是 Vue.js 的精髓之处了。 值得注意的是,我们所说的数据双向绑定,一定是对于 UI 控件来说的,非 UI 控件不会涉及到数据双向绑定。单向数据绑定是使用状态管理工具的前提。如果我们使用 vuex,那么数据流也是单项的,这时就会和双向数据绑定有冲突。 #### 5.2 怎么实现双向数据绑定 ##### v-model v-model 指令可以在表单及元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理。 <div class="tip inlineBlock error"> 注意:v-model 会忽略所有表单元素的 value、checked、selected 特性的初始值而总是将 Vue 实例的数据作为数据来源。你应该通过 JavaScript 在组件的 data 选项中声明初始值! </div> 测试案例: 用非v-model方式的时候,是不能双向绑定的 ```html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <script src="../js/vue.js"></script> </head> <body> <div id="app"> <!-- 以下为单向绑定的,也就是只能去取data里面的值 --> <input :value="msg"/> <div>{{msg}}</div> </div> </body> <script> new Vue({ el:"#app", data:{ msg:"hello" } }) </script> </html> ``` 修改文本框里面的值并不能修改下面的 ![](https://blog.fivk.cn/usr/uploads/2023/03/3622196654.png) 改为v-model方式绑定: ```html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <script src="../js/vue.js"></script> </head> <body> <div id="app"> <!-- 双向绑定 --> <input v-model="msg"/> <div>{{msg}}</div> </div> </body> <script> new Vue({ el:"#app", data:{ msg:"hello" } }) </script> </html> ``` 文本框追加了world 下面也跟着增加 ![](https://blog.fivk.cn/usr/uploads/2023/03/1040210054.png) 案例2: ```html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <script src="../js/vue.js"></script> </head> <body> <div id="app"> <select v-model="selected"> <option value="">请选择</option> <option value="苹果">苹果</option> <option value="西红柿">西红柿</option> <option value="草莓">草莓</option> </select> <div>{{selected}}</div> </div> </body> <script> new Vue({ el:"#app", data:{ selected:"" } }); </script> </html> ``` ![](https://blog.fivk.cn/usr/uploads/2023/03/1854219541.png) 案例3: ```html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <script src="../js/vue.js"></script> </head> <body> <div id="app"> <span>选项:</span> <label>西瓜</label> <input type="checkbox" value="西瓜" v-model="checkeds"/> <label>草莓</label> <input type="checkbox" value="草莓" v-model="checkeds"/> <label>苹果</label> <input type="checkbox" value="苹果" v-model="checkeds"/> <div style="margin-top:30px"> <span>选中的值:</span> <div v-for="item in checkeds">{{item}}</div> </div> </div> </body> <script> var v = new Vue({ el:"#app", data:{ checkeds:[] } }); </script> </html> ``` ![](https://blog.fivk.cn/usr/uploads/2023/03/533473327.png) ### 6.Vue事件绑定 ##### **v-on** ``` v-on:事件名 = “方法名” 简写方式: @事件名 = “方法名” 事件名有哪些: click|keydown|keyup|mouseover|mouseout|自定义事件名 ``` 测试案例1: ```html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <script src="../js/vue.js"></script> </head> <body> <div id="app"> <input type="text" v-model="firstData"/>+ <input type="text" v-model="secondData"/> <button v-on:click="add">=</button> <input type="text" v-model="rs"/> </div> </body> <script> var v = new Vue({ el:"#app", data:{ firstData:0, secondData:0, rs:0 }, methods: { add:function(){ this.rs = parseInt(this.firstData) + parseInt(this.secondData); } }, }); </script> </html> ``` ![](https://blog.fivk.cn/usr/uploads/2023/03/4176698634.png) **v-on: 可以简化为@** ```html <div id="app"> <input type="text" v-model="firstData"/>+ <input type="text" v-model="secondData"/> <button @click="add">=</button> <input type="text" v-model="rs"/> </div> ``` 测试案例2: ```html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <script src="../js/vue.js"></script> </head> <body> <div id="app"> <div>输入年龄,按回车将会显示对应年龄的类别</div> <input type="text" v-on:keyup.enter="show" v-model="age"/> <div>{{person}}</div> </div> </body> <script> var v = new Vue({ el:"#app", data:{ age:0, person:"" }, methods: { show:function(){ if(this.age >=0 && this.age <=12){ this.person = "小孩子"; }else if(this.age <=18){ this.person = "中孩子"; }else{ this.person = "成年人"; } } } }); </script> </html> ``` 测试结果: ![](https://blog.fivk.cn/usr/uploads/2023/03/1446839856.png) ### 7.综合案例 > 根据前面学习的vue的基础语法和事件绑定,实现一下商品的查询,添加,删除功能。 测试案例: ```html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <script src="../js/vue.js"></script> <style> td{ width:200px; text-align: center; } .header{ width:800px; height: 140px; margin: 0 auto; } .title{ background-color: gainsboro; margin-top: 5px; margin-bottom: 10px; } </style> </head> <body> <div id="app"> <div class="header"> <div class="title">添加</div> <div> <span>用户名:</span><input type="text" v-model="username"/> <span>性别:</span><input type="text" v-model="sex"/> <span>年龄:</span><input type="text" v-model="age"/> <button v-on:click="addUser">添加</button> </div> <div class="title">查询</div> <span>用户名:</span><input type="text" v-model="s_username"/> <button @click="searchUser">查询</button> </div> <div> <table border="1" style="margin: 0 auto;"> <thead> <tr> <td>用户名</td> <td>性别</td> <td>年龄</td> <td>操作</td> </tr> </thead> <tbody> <tr v-for="item in searchUser(s_username)"> <td>{{item.username}}</td> <td>{{item.sex}}</td> <td>{{item.age}}</td> <td><a href="#" @click="deleteUser(item.username)">删除</a></td> </tr> </tbody> </table> </div> </div> </body> <script> var v = new Vue({ el:"#app", data:{ username:"", sex:"", age:"", s_username:"", userList:[ {username:"刘德华",sex:"男",age:58}, {username:"张学友",sex:"男",age:56}, {username:"黎明",sex:"男",age:55}, {username:"郭富城",sex:"男",age:54} ], }, methods: { addUser:function(){ var users = { username:this.username, sex:this.sex, age:this.age } if(this.username != null && this.sex != null && this.age != null && this.username != "" && this.sex != "" && this.age != ""){ this.userList.push(users); }else{ alert("请填完用户信息") } }, deleteUser:function(username){ // 这里的箭头函数,前面的item是参数,如果是多个就需要加上括号,这里表示的是每一个json var index = this.userList.findIndex(item=>{ if(username == item.username){ return true; } }) // splice的用法是从index角标开始删除i个数据,这里的i是1,因为我们每次只删除一个学生。 this.userList.splice(index,1); }, searchUser:function(s_username){ //返回筛选过后的结果集展示 return this.userList.filter(item =>{ if(item.username.includes(s_username)){ return item; } }) } } }); </script> </html> ``` 测试结果: <div class='album_block'> [album type="photos"] ![](https://blog.fivk.cn/usr/uploads/2023/03/3544926644.png) ![](https://blog.fivk.cn/usr/uploads/2023/03/558111277.png) ![](https://blog.fivk.cn/usr/uploads/2023/03/1467347039.png) ![](https://blog.fivk.cn/usr/uploads/2023/03/2687584979.png) [/album] </div> ### 8.Watch 选项 vue的选项很多,除了前面用到的el,data,methods等,还有其它的。比如Watch > 数据变化的监控经常使用,例如天气预报的穿衣指数,它主要是根据温度来进行提示的。温度大于25度时,我们建议穿T恤短袖,温度小于25度大于0度时,我们建议穿毛衣外套,温度小于0度时我们建议穿棉衣羽绒服。 ```html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <script type="text/javascript" src="js/vue.js" ></script> </head> <body> 输入温度,显示穿衣指数 <div id="app"> <p>温度:{{temperature}}</p> <p>穿衣建议:{{advise}}</p> 输入温度:<input type="text" v-model="temperature" /> </div> <script> var v=new Vue({ el:"#app", data:{ temperature:"", advise:"" }, //监控温度的变化 watch:{ temperature:function(newVal,oldVal){ if (newVal > 25) { this.advise ="建议穿T恤短袖"; } else if (newVal >= 0 && newVal <= 25) { this.advise ="建议穿毛衣外套"; } else { this.advise ="建议穿棉服羽绒服"; } } } }) </script> </body> </html> ``` 测试结果: ![](https://blog.fivk.cn/usr/uploads/2023/03/434970318.png) ## 四.Axios异步通信 ### 1 什么是Axios? ``` Axios是一个类库,基于Promise管理的HTTP 库,是前端通信框架,可以用在浏览器和 node.js 中。axios实现了对ajax的封装,常用于Ajax请求。 注解:promise是Java Script的一个对象,代表了未来将要发生的事件,用来传递异步操作的消息。 ``` ### 2 Axios和Ajax的关系 ``` Axios是AJAX技术的一种实现,就像Jquery中的$.ajax也是AJAX技术的一种实现。 Axios是通过Promise实现XHR封装,其中Promise是控制手段,XHR是实际发送Http请求的客户端。 Jquery中的$.ajax是通过callback+XHR实现(XHR就是XmlHttpRequest对象) 再通俗一点讲:AJAX是汽车,Axios是奥迪,$.ajax是奔驰 ``` ### 3 为什么要用Axios? ``` 因为vue的边界很明确,就是为了处理DOM,所以并不具备通信功能,为了解决通信问题,作者单独开发了一个名为 vue-resource 的插件,不过在进入 2.0 版本以后停止了对该插件的维护并推荐了 Axios 框架,此时就需要额外使用一个通信框架与服务器交互。 功能就像jQuery提供的AJAX通信功能。 ``` ### 4 Axios的API ```JavaScript axios({ method: 'get', url: '/user/12345', data: { id:1, name:'aa' } }); ``` ### 5 Axios的使用 ``` axios提供了多种请求方式,比如直接发起get或post请求: ``` #### **5.1.get请求** **案例1** 通过axios 跟服务器端 交互 index.html : ```html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <script src="../js/vue.js"></script> <!-- 引入axios依赖包 --> <script src="https://unpkg.com/axios/dist/axios.min.js"></script> </head> <body> <div id="app"> <table border="1"> <thead> <tr> <td>id</td> <td>stuName</td> <td>sex</td> <td>tId</td> </tr> </thead> <tbody> <tr v-for="item in users"> <td>{{item.id}}</td> <td>{{item.stuName}}</td> <td>{{item.sex}}</td> <td>{{item.tId}}</td> </tr> </tbody> </table> </div> </body> <script> var v = new Vue({ el:"#app", data:function(){ // 注意这里的data是一个函数了,不再是之前的data属性,是需要返回值的. return{ users:{ id:null, stuName:null, sex:null, tId:null } } }, mounted:function(){ axios({ method:"get", url:"http://127.0.0.1:9898/query_student", }).then((response)=>{ this.users = response.data; }) } }); </script> </html> ``` 测试: ![](https://blog.fivk.cn/usr/uploads/2023/03/3076291248.png) 说明: ``` 这里使用 axios 框架的 get 方法请求 AJAX 并自动将数据封装进了 Vue 实例的数据对象中 我们在data中的数据结构必须要和Ajax响应回来的数据格式匹配! ``` 带参数的get请求 java代码 ```java @RequestMapping(value = "query_student_by_name",method = RequestMethod.GET) @ResponseBody @CrossOrigin public Student queryStudentByName(@RequestParam("stuName") String stuName){ return studentService.queryStudentByName(stuName); } ``` 前端 ```html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <script src="../js/vue.js"></script> <!-- 引入axios依赖包 --> <script src="https://unpkg.com/axios/dist/axios.min.js"></script> </head> <body> <div id="app"> <input v-model="queryStuName"/> <button v-on:click="getData">查询用户数据</button> <table border="1"> <thead> <tr> <td>id</td> <td>stuName</td> <td>sex</td> <td>tId</td> </tr> </thead> <tbody> <tr> <td>{{users.id}}</td> <td>{{users.stuName}}</td> <td>{{users.sex}}</td> <td>{{users.tId}}</td> </tr> </tbody> </table> </div> </body> <script> var v = new Vue({ el:"#app", data:function(){ return { queryStuName:"", users:{ id:null, stuName:null, sex:null, tId:null } } }, methods:{ getData:function(){ axios({ url:"http://127.0.0.1:9898/query_student_by_name", method:"get", params:{ stuName:this.queryStuName }, headers: { "Content-type": "application/json;charset=utf-8" } }).then((response)=>{this.users = response.data}) } }, }) </script> </html> ``` #### 5.2.post请求 ``` post提交,再处理返回结果 ``` java ```java @RequestMapping(value = "query_student_by_name_use_post",method = RequestMethod.POST) @ResponseBody public Student queryStudentByNameUsePost(@RequestParam("stuName") String stuName){ return studentService.queryStudentByName(stuName); } ``` html ```html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <script src="../js/vue.js"></script> <!-- 引入axios依赖包 --> <script src="https://unpkg.com/axios/dist/axios.min.js"></script> </head> <body> <div id="app"> <input v-model="queryStuName"/> <button v-on:click="getData">查询用户数据</button> <table border="1"> <thead> <tr> <td>id</td> <td>stuName</td> <td>sex</td> <td>tId</td> </tr> </thead> <tbody> <tr> <td>{{users.id}}</td> <td>{{users.stuName}}</td> <td>{{users.sex}}</td> <td>{{users.tId}}</td> </tr> </tbody> </table> </div> </body> <script> var v = new Vue({ el:"#app", data:function(){ return { queryStuName:"", users:{ id:null, stuName:null, sex:null, tId:null } } }, methods:{ getData:function(){ axios({ url:"http://127.0.0.1:9898/query_student_by_name_use_post", method:"post", //如果是post请求就要用data传参 data:{ stuName:this.queryStuName }, headers: { "Content-type": "application/x-www-form-urlencoded;charset=utf-8" } }).then((response)=>{this.users = response.data}) } }, }) </script> </html> ``` ## 五 安装VS Code ``` Visual Studio Code,简称VS Code,是一种简化且高效的代码编辑器,同时支持诸如调试,任务执行和版本管理之类的开发操作。它的目标是提供一种快速的编码编译调试工具。 优势: 支持多种语言的编写,前后端都可以用 插件多 跨平台 启动速度快 免费 .... ``` ### 1.下载路径 https://code.visualstudio.com/ ![](https://blog.fivk.cn/usr/uploads/2023/03/188451376.png) ### 2.安装步骤 ![](https://blog.fivk.cn/usr/uploads/2023/03/1860203723.png) ![](https://blog.fivk.cn/usr/uploads/2023/03/1193955393.png) ![](https://blog.fivk.cn/usr/uploads/2023/03/4011564367.png) **安装后界面如下:** ![](https://blog.fivk.cn/usr/uploads/2023/03/3275851337.png) ### 3.配置 #### 3.1 安装中文简体VSCode插件 ![](https://blog.fivk.cn/usr/uploads/2023/03/254288445.png) ![](https://blog.fivk.cn/usr/uploads/2023/03/398643213.png) ![](https://blog.fivk.cn/usr/uploads/2023/03/3910179565.png) #### 3.2安装Vetur插件 > Vetur支持.vue文件的语法高亮显示,除了支持template模板以外,还支持大多数主流的前端开发脚本和插件,比如Sass和TypeScript ![](https://blog.fivk.cn/usr/uploads/2023/03/720018554.png) 安装前: ![](https://blog.fivk.cn/usr/uploads/2023/03/2091017212.png) 安装后: ![](https://blog.fivk.cn/usr/uploads/2023/03/3555646065.png) #### 3.3 安装vue vscode snippets ``` vue语法提示,加强vue的便捷写法 ``` ![](https://blog.fivk.cn/usr/uploads/2023/03/3762829540.png) #### 3.4 安装Auto Close Tag ``` 自动闭合标签 ``` ![](https://blog.fivk.cn/usr/uploads/2023/03/2674036672.png) #### 3.5 安装 Bracket Pair Colorizer ``` 对括号进行着色,方便区分 ``` ![](https://blog.fivk.cn/usr/uploads/2023/03/763871641.png) #### 3.6 安装 Copy Relative Path ``` 用于复制文件的完整路径和相对路径 ``` ![](https://blog.fivk.cn/usr/uploads/2023/03/3419272238.png) 安装后: ![](https://blog.fivk.cn/usr/uploads/2023/03/2954047857.png) #### 3.7 安装Path Intellisense ``` 路径自动感知,在配置文件中配置`@`后我们就可以很方便快捷的引用各种文件了 ``` ![](https://blog.fivk.cn/usr/uploads/2023/03/80331733.png) 安装后: ![](https://blog.fivk.cn/usr/uploads/2023/03/92954900.png) #### 3.8 安装Vue Peek ``` 用于Vue快速查看组件定义以及组件跳转 ``` ![](https://blog.fivk.cn/usr/uploads/2023/03/1843703003.png) 安装后: ![](https://blog.fivk.cn/usr/uploads/2023/03/2886485638.png) #### 3.9 安装vscode-element-helper ``` 针对 Element 标签的属性以及方法进行区分,并且提供自动补全提示。 ``` ![](https://blog.fivk.cn/usr/uploads/2023/03/1140026659.png) ## 六 前端工程化vue-cli ``` Vue是渐近式框架,你可以用它一个功能,也可以用全家桶。前面的章节中,我们是在html中引入vue.js,只用它核心的数据绑定功能。但基于vue的扩展还有很多,比如vueRouter,axios,elementUI等。 vue-cli,它是一个专门为单页面应用快速搭建繁杂的Vue脚手架,通俗点说就是代码生成器,可以快速生成一套基于Vue完整的前端框架,单独编译,单独部署。可以再集成各种第三方插件,扩展出更多的功能。 也就是:Vue cli = Vue + 一堆的js插件 Vue CLI 4.5以下,对应的是Vue2 Vue CLI 4.5及以上,对应的是Vue3,创建项目的时候可以选择Vue2 利用vue-cli脚手架来构建Vue项目需要先安装Node.js和NPM环境。(安装了node.js才有npm ,才能安装vue-cli) ``` ### 1.环境安装 #### 1.1安装Node.js 可以在官网下载(https://nodejs.org/en/download/) ![](https://blog.fivk.cn/usr/uploads/2023/03/3069928042.png) **注意**:最新版本不支持win7系统,win7系统需要下载之前的版本,比如14之前的,下载地址:https://nodejs.org/dist/ 安装步骤很简单,一直点击下一步就可以,中间有一个安装目录,需要修改的可以改一下。 ![](https://blog.fivk.cn/usr/uploads/2023/03/301133099.png) 配置一下Node.js环境变量: ![](https://blog.fivk.cn/usr/uploads/2023/03/1955062981.png) 测试: cmd中输入命令 node -v 出现版本号代表配置成功. ![](https://blog.fivk.cn/usr/uploads/2023/03/1452675475.png) #### 1.2 安装npm 由于Node.js已经集成了npm,所以安装完Node.js,npm也一并安装好了。 在cmd终端输入命令npm -v ,出现版本号代表成功 ![](https://blog.fivk.cn/usr/uploads/2023/03/3785005035.png) #### 1.3 安装cnpm 由于有些npm有些资源被屏蔽或者是国外资源的原因,经常会导致用npm安装依赖包的时候失败,所有我还需要npm的国内镜像—cnpm。 在命令行中输入 npm install -g cnpm --registry=http://registry.npm.taobao.org 然后等待 ![](https://blog.fivk.cn/usr/uploads/2023/03/639095608.png) 查看是否安装成功,出现版本信息代表成功 ![](https://blog.fivk.cn/usr/uploads/2023/03/2885815858.png) 安装成功以后,之后 npm install 命令都可以更改为 cnpm install #### 1.4 安装脚手架Vue Cli 关于版本: ``` Vue CLI 3.0后的包名称由 vue-cli 改成了 @vue/cli。 所以3.0前后的版本安装方式不同。 ``` 3.0之前的版本安装方式: ``` 输入命令 npm install -g vue-cli 或者 cnpm install -g vue-cli -g :代表全局安装 ``` 3.0之后的版本安装方式: ``` 输入命令 npm install -g @vue/cli 或者 cnpm install -g @vue/cli ``` 另外要注意: ``` 默认npm全局安装的文件将会保存到 C:\Users\计算机名\AppData\Roaming\npm下,所以,安装好node后,可以重新设置一下node_global和node_cache的目录,win10中可以不设置,系统自己会配置环境变量,但win7中不会自动配置环境变量,为了方便找到你安装的文件,最好设置一下。 ``` 设置方式: 在node安装目录下创建node_global和node_cache文件夹: ![](https://blog.fivk.cn/usr/uploads/2023/03/725080770.png) 然后cmd中输入命令: ``` npm config set prefix "D:\Program Files\nodejs\node_global" npm config set cache "D:\Program Files\nodejs\node_cache" ``` 并配置一下环境变量 安装3.0之前的版本: ![](https://blog.fivk.cn/usr/uploads/2023/03/1841121006.png) 安装3.0之后的额版本: 将之前安装过的旧版本卸载掉 ![](https://blog.fivk.cn/usr/uploads/2023/03/956217279.png) 安装最新的版本 ![](https://blog.fivk.cn/usr/uploads/2023/03/3108676308.png) ### 2.创建第一个脚手架项目。 #### 2.1创建项目 vue-cli 3.0 以后项目创建命令: ``` vue create vue项目名 ``` ![](https://blog.fivk.cn/usr/uploads/2023/03/4156051559.png) 下一步,选择配置方式 ![](https://blog.fivk.cn/usr/uploads/2023/03/4240971962.png) 下一步,选择插件安装 通过↑ ↓ 箭头选择你要配置的项,按 空格 是选中,按 a 是全选,按 i 是反选。根据需要选择 ![](https://blog.fivk.cn/usr/uploads/2023/03/839042095.png) 下一步,选择vue.js版本 ![](https://blog.fivk.cn/usr/uploads/2023/03/2666720086.png) 下一步,选择Vue-Router实现方式 ![](https://blog.fivk.cn/usr/uploads/2023/03/3260513443.png) 下一步,选择css的预处理器 ![](https://blog.fivk.cn/usr/uploads/2023/03/3963075623.png) 下一步,一个插件化的javascript代码检测工具 ![](https://blog.fivk.cn/usr/uploads/2023/03/1883309266.png) 下一步,选择代码检测规则 ![](https://blog.fivk.cn/usr/uploads/2023/03/2214151068.png) 下一步,选择如何存放配置 ![](https://blog.fivk.cn/usr/uploads/2023/03/706839211.png) 下一步,是否保存当前配置 ![](https://blog.fivk.cn/usr/uploads/2023/03/828277007.png) 下一步,按回车后开始构建项目,可以看到成功信息 ![](https://blog.fivk.cn/usr/uploads/2023/03/1422701400.png) #### 2.2**启动服务** 启动服务有两种方式。 方式1: 命令的方式 ``` 进入项目所在文件夹,输入命令 npm run serve ``` ![](https://blog.fivk.cn/usr/uploads/2023/03/437767316.png) **测试:** 浏览器输入: http://localhost:8080/ ![](https://blog.fivk.cn/usr/uploads/2023/03/3419686021.png) 方式2: ![](https://blog.fivk.cn/usr/uploads/2023/03/3353592086.png) ![](https://blog.fivk.cn/usr/uploads/2023/03/888956049.png) ![](https://blog.fivk.cn/usr/uploads/2023/03/2364119963.png) 任务中, 点击运行,启动项目 ![](https://blog.fivk.cn/usr/uploads/2023/03/829765787.png) 访问页面: ![](https://blog.fivk.cn/usr/uploads/2023/03/1465392686.png) #### 2.3 项目结构目录 在自己的开发软件里打开创建出来的项目,我这里用vscode打开,打开方式是, 文件-->打开文件夹-->选择之前创建的vue项目文件夹。 打开的项目结构如下: ![](https://blog.fivk.cn/usr/uploads/2023/03/1242407532.png) #### 2.4 main.js、App.vue、index.html关系 **index.html---主页,项目入口** **App.vue---根组件** **main.js---入口文件** App.vue是个组件,通过export default 导出组件的名称为App 然后在main.js中,通过import App from './App'导入该组件 ![](https://blog.fivk.cn/usr/uploads/2023/03/3715418950.png) ![](https://blog.fivk.cn/usr/uploads/2023/03/3810231241.png) 运行入口文件main.js以后会新建一个Vue实例,在Vue实例中,通过mount(“#app”)告诉该实例要挂载的地方,即实例装载到index.html中的位置。而Vue实例中的内容就在App.vue中,也就是App.vue中的template里的内容会装载到index.html里的id="app"的div里面。 #### **2.5关闭服务** 在运行窗口下,按“Ctrl+C”,输入“y”,即可终止服务。 ## 七.Vue-router ### 1、什么是vue-router vue-router是vue.js官方路由管理器。vue的单页应用是基于路由和组件的,路由用于设定访问路径,并将路径和组件映射起来。 传统页面切换是用超链接a标签进行切换。但vue里是用路由,因为我们用Vue做的都是单页应用,就相当于只有一个主的index.html页面,所以你写的`<a></a>`标签是不起作用的,你必须使用`vue-router`来进行管理。 ### 2、 安装vue-router ``` vue-router是一个插件包,所以我们还是需要用npm来进行安装的。打开命令行工具,进入你的项目目录,输入下面命令。 npm install vue-router --save-dev 如果你安装很慢,也可以用cnpm进行安装,如果你在使用vue-cli中已经选择安装了vue-router,那这里不需要重复安装了。 ``` ### 3、在 main.js中引入 ![](https://blog.fivk.cn/usr/uploads/2023/03/267210623.png) ### 4、vue-router的使用 #### 4.1 给组件或页面定义路由 ![](https://blog.fivk.cn/usr/uploads/2023/03/1859248776.png) #### 4.2 **路由跳转的方式** 方式1: ``` <router-link to="{path:'/editUser',query:{id:user.id}}"></router-link> ``` ![](https://blog.fivk.cn/usr/uploads/2023/03/3163376961.png) 接收参数: ``` 接收的页面中的vue对象中: this.$route.query.id ``` 方式2: ``` this.$router.push({path:'/users'}) ``` ![](https://blog.fivk.cn/usr/uploads/2023/03/52459721.png) 完整案例: 创建News.vue组件 ```html <template> <div> 这是新闻列表页 <li v-for="news in newsList" :key="news.id"> <router-link :to="{path:'/newsInfo',query:{id:news.id}}"> {{news.title}}</router-link> </li> </div> </template> <script> export default { name: "News", data:function(){ return { newsList:[ { id:"1", title:"新闻1", content:"新闻1的内容" }, { id:"2", title:"新闻2", content:"新闻2的内容" } ] } } } </script> ``` 创建NewsInfo.vue组件 ```html <template> <div> {{news.content}} </div> </template> <script> export default{ name:"NewsInfo", data(){ return { news:{ id:"", title:"", content:"" } } }, mounted(){ //获取传过来的参数id this.news.id= this.$route.query.id var newsList=[ { id:"1", title:"新闻1", content:"新闻1的内容" }, { id:"2", title:"新闻2", content:"新闻2的内容" } ] var index = newsList.findIndex( item => { if(this.news.id == item.id){ return true; } }); this.news=newsList[index] } } </script> ``` 设置路由: ```JavaScript import { createRouter, createWebHashHistory } from "vue-router"; //import Home from "../views/Home.vue"; const routes = [ { path:"/", name:"News", component:()=>import("../views/News.vue") }, { path:"/newsInfo", name:"NewsInfo", component:()=>import("../views/NewsInfo.vue") } ]; const router = createRouter({ history: createWebHashHistory(), routes, }); export default router; ``` 设置App.vue主组件 ```JavaScript <template> <div> <!-- <router-link to="/">Home</router-link> | <router-link to="/about">About</router-link> --> <!-- 展示当前路径对应的组件内容 --> <router-view /> </div> </template> <style lang="scss"> #app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; } #nav { padding: 30px; a { font-weight: bold; color: #2c3e50; &.router-link-exact-active { color: #42b983; } } } </style> ``` #### 4.3 a和router-link的区别 a标签 ``` 点击a标签从当前页面跳转到另一个页面 通过a标签跳转,页面就会重新加载,相当于重新打开了一个网页 ``` router-link ``` 通过router-link进行跳转不会跳转到新的页面,不会重新渲染,它会选择路由所指的组件进行渲染 ``` 总结 ``` 通过a标签和router-link对比,router-link避免了重复渲染,不像a标签一样需要重新渲染减少了DOM性能的损耗 ``` 最后修改:2023 年 03 月 10 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 如果觉得我的文章对你有用,请随意赞赏