(五)、Vue双向绑定v-model
1.什么是双向绑定
Vue.js是一个MVVM框架,即数据双向绑定,即当数据发生变化的时候,视图也就发生变化,且视图发生变化的时候,数据也会跟着变化,这也就算Vue.js的精通之处。
注意:我们所说的数据双向绑定,一定是对于UI控件来说的,并非UI控件不会涉及到数据的双向绑定。单项数据绑定是使用状态管理工具的前提。如果我们使用vuex,那么数据流也是单项的,这就会和双向绑定有冲突。
2.为什么要使用双向绑定
在vue.js中,如果使用vuex,实际上数据是单向的,之所以说是数据双向绑定,这是用的UI空间来说,对于我么处理表单,Vue.js的双向绑定用起来就特别舒服了。即两者并不互斥,在全局性数据流使用单向,方便跟踪;局部性数据流使用双向,简单易操作。
3.在表单中使用双向绑定
我们可以在v-model
指令在表单input,textarea及select
元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法更新元素。尽管有些神奇,但v-model本质上不过是 语法糖。她负责监听用户的输入事件以更新数据,并对一些极端场景,进行一些特殊处理。
注意: v-model会忽略所有表单元素的 value,checked,selected特性的初始值而总是将Vue实列的数据作为数据来源,你应该通过JavaScript在组件的data选项中声明初始值。
4.表单双向绑定(实时更新)
v-model=" 数据",是双向绑定的操作 {{数据}},多选框是数组,所以我们在定义的时候要用数组
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <!-- 第一步导入vue--> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script> </head> <body> <div id="app"> 请输入文本: <input type="text" v-model="message"/>{{message}} <hr> 请输入文本域 <textarea v-model="message"></textarea>{{message}} <hr> 性别: <input type="radio" name="sex" value="男" v-model="sexx"> 男 <input type="radio" name="sex" value="女" v-model="sexx"> 女 {{sexx}} <hr> 下拉框: <select name="mix" id="" v-model="option"> <option disabled value="1">---请选择---</option> <option>A</option> <option>B</option> <option>C</option> </select> {{option}} <hr> 多复选: <p> 睡觉:<input type="checkbox" value="sleep" name="hobby" v-model="bo"> 游戏:<input type="checkbox" value="playGrame" name="hobby" v-model="bo"> 学习:<input type="checkbox" value="learn" name="hobby" v-model="bo"> 吃饭:<input type="checkbox" value="eat" name="hobby" v-model="bo"> {{bo}} </p> </div> <script> var vm = new Vue({ el:"#app", data:{ message:"123", sexx:"男", option:"1", bo:[] } }); </script> </body> </html>
(六)、组件component
1.什么是组件
组件是可复用的Vue实列,说白了就是一组可重复使用的模板,跟JSTL的自定义标签、Thymeleaf的th :fragment
等框架有着异曲同工之妙,通常一个应用会以一颗嵌套的组件树的形式来组织:类似于头身体尾部
说明
:
- Vue.component():注册组件
- pan:自定义组件的名字
- template:组件的模板
2.使用props数组
传递参数
像上面那样用组件没有任何意义,所以我们是需要传递参数到组件里,此时就需要使用props属性了!这个属性当中介,进行上传下达。
直接在模板中进行添加数据,<Jsxs></Jsxs>显示数据
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <!-- 第一步导入vue--> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script> </head> <body> <div id="app"> <Jsxs></Jsxs> </div> <script> // 创建组件 Vue.component('Jsxs',{ template: '<li>hello</li>' }) let vm = new Vue({ el:"#app", data:{ arrays:['c++','java','python'] } }); </script> </body> </html>
注意:默认规则下props属性里的值不能为大写,组件放在定义Vue对象的前面
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <!-- 第一步导入vue--> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script> </head> <body> <div id="app"> <!-- 组件: 传递给组件的值: props--> <Jsxs v-for="item in items" v-bind:lcp="item"></Jsxs> </div> <script> // 自定义组件要放在对象的前面,因为我们形成的工作空间是先绑定,然后在工作的、;如果放在后面,会显示不出来数据 Vue.component("Jsxs",{ props:['lcp'], template: '<li>{{lcp}}</li>' }); let vue = new Vue({ el:"#app", data:{ items:["java","Linux","前端"] } }); </script> </body> </html>
v-for="item in items"
:遍历Vue实例中定义的名为items的数组,并创建同等数量的组件v-bind:lcp="item"
:将遍历的item项绑定到组件中props定义名为item属性上;= 号左边的lcp为props定义的属性名,右边的为item in items 中遍历的item项的值
3.为什么使用组件如此麻烦?
- 定义的组件不能直接获取Vue 的data值
- 组件不仅仅是要把模板的内容进行复用,更重要的是组件间的通信。通常父组件的模板中包含子组件,父组件要正向的向子组件传递数据或者参数,子组件接收到后根据参数的不同来进行对应的渲染。
这个正向的数据传递在vue组件中就是通过props来实现的
。
(七)、Axious(网络通信-钩子mounted
)
1.什么是Axious
Axios是一个开源的可以用在浏览器端和Node JS的异步通信框架, 她的主要作用就是实现AJAX异步通信,其功能特点如下:
- 从浏览器中创建XMLHttpRequests
- 从node.js创建http请求
- 支持Promise API【JS中链式编程】
- 拦截请求和响应
- 转换请求数据和响应数据
- 取消请求
- 自动转换JSON数据
- 客户端支持防御XSRF(跨站请求伪造)
GitHub:https://github.com/axios/axios
2.为什么使用Axious
由于Vue.js是一个视图层框架并且作者(尤雨溪) 严格准守SoC(关注度分离原则)所以Vue.js并不包含AJAX的通信功能
, 为了解决通信问题, 作者单独开发了一个名为vue-resource的插件, 不过在进入2.0版本以后停止了对该插件的维护并推荐了Axios框架。少用jQuery, 因为它操作Dom太频繁!
3.Axious的引入
<script src="https://unpkg.com/axios@0.21.1/dist/axios.min.js"></script>
4.我的第一个Axious程序
咱们开发的接口大部分都是采用JSON格式, 可以先在项目里模拟一段JSON数据, 数据内容如下:创建一个名为data.json的文件并填入上面的内容, 放在项目的根目录下
data.json
{ "name": "Java", "url": "https://blog.kuangstudy.com", "page": 1, "isNonProfit": true, "address": { "street": "含光门", "city": "陕西西安", "country": "中国" }, "links": [ { "name": "bilibili", "url": "https://space.bilibili.com/95256449" }, { "name": "Java", "url": "https://blog.kuangstudy.com" }, { "name": "百度", "url": "https://www.baidu.com/" } ] }
html数据。 先获取路径,然后进行响应,响应在控制台上
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://unpkg.com/axios@0.21.1/dist/axios.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script> </head> <body> <div id="vue"></div> <script> let vm = new Vue({ el:"#vue", // data 的属性 data :{ }, mounted(){ //钩子函数 // 先获取路径,然后进行响应,相应在控制台上 axios.get('../data.json').then(respones=>(console.log(respones.data))); } }); </script> </body> </html>
首先我们使用钩子函数,进行绑定数据,然后说明以什么样的方式进行数据的响应,然后在前端利用Mustache(骂死她去)进行数据的获取
。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> // 闪烁 <style> [v-cloak]{ display: none; } </style> <script src="https://unpkg.com/axios@0.21.1/dist/axios.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script> </head> <body> <div id="vue"> <div> {{info.name}} {{info.address.street}} <a v-bind:href="info.url">个人博客</a> <!-- 取对象下面的数组的某一项--> {{info.links[2].url}} <a v-bind:href="info.links[2].url">bili</a> </div> </div> <script> let vm = new Vue({ el:"#vue", // data 的属性 data :{ }, data(){ return{ // 请求返回参数合适,必须和json字符串一样 info:null } }, mounted(){ //钩子函数,链式编程,ES6新特性 axios.get('../data.json').then(respones=>(this.info=respones.data)); } }); </script> </body> </html>
(八)、Vue生命周期
1.生命周期示意图
(九)、计算属性computed
1.什么是计算属性
计算属性的重点突出在属性
两个字上(属性是名词)。首先他是一个属性
,其次这个属性有计算
的能力,这里的计算
就是一个函数;简单的说:它就是一个能够将计算结果缓存起来的属性,(将行为转化为了静态的属性),仅此而已,可以想象成为缓存、(计算出来的结果,保存在属性中,内存中运行: 虚拟dom)
假如中间遇到数据的刷新,那么缓存就会自己消失
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script> </head> <body> <div id="app"> {{message}} <!-- methods 里面的方法我们 用方法 调用 不用属性 进行调用 --> <p>{{current()}}</p> <!-- computed 里面的方法我们 用属性 调用 不用方法 进行调用 --> <p>{{current2}}</p> </div> <script> let vue = new Vue({ el:"#app", data:{ message:'hello jsxs' }, methods:{ current:function (){ return Date.now(); //返回一个时间戳 } }, computed:{ //计算属性,,methods 和 computed 里面的方法名不能重名,重名之后methods的优先级高一点 current2:function (){ this.message; return Date.now(); //返回一个时间戳 } } }); </script> </body> </html>
2.计算属性注意点
注意:计算属性,,methods 和 computed 里面的方法名不能重名,重名之后methods的优先级高一点
说明:
methods
:定义方法, 调用方法使用currentTime1(), 需要带括号
computed
:定义计算属性, 调用属性使用currentTime2, 不需要带括号:this.message是为了能够让currentTime2观察到数据变化而变化
v-on
: 事件触发项,如果调用方法的话,就不用写小括号,因为是约束
如何在方法中的值发生了变化,则缓存就会刷新!可以在控制台使用vm.message=" xiao ", 改变下数据的值,再次测试观察效果!
结论:
调用方法时,每次都需要讲行计算,既然有计算过程则必定产生系统开销,那如果这个结果是不经常变化的呢?此时就可以考虑将这个结果缓存起来,采用计算属性可以很方便的做到这点,计算属性的主要特性就是为了将不经常变化的计算结果进行缓存,以节约我们的系统开销
;