vue 基础练习
1、初识vue
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Vue 示例</title> </head> <body> <div id="app"> <ul> <li v-for="book in books">{{book.name}}</li> </ul> </div> <script src="./vue.js"></script> <script> new Vue({ el:'#app', data:{ books:[ {name:'<<vue.js>>'}, {name:'<<Javascript>>'}, {name:'<<html>>'} ] } }) </script> </body> </html>
显示结果:
2、数据绑定和第一个vue应用 v-model
<!-- test1.html里面的内容 --> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Vue 示例</title> </head> <body> <div id="app"> <input type="text" v-model="name" placeholder="你的姓名"> <h1>你好!{{name}}</h1> </div> <script src="./vue.js"></script> <script> new Vue({ el:'#app', data:{ name } }) </script> </body> </html>
3、vue 指向变量,实现双向数据绑定。
当修改其中任意一个时,另外一个也随之变化:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div id="app"> </div> <script src="./vue.js"></script> <script> var myData = { a:1 } var app = new Vue({ el:'#app', data:myData, }) console.log(app.a); //1 // 修改vue属性,原数据也随之改动 app.a=2; console.log(myData.a); //2 // 反之,修改原数据,vue的属性也随之改动 myData.a=3; console.log(app.a); //3 </script> </body> </html>
4、生命周期 created mounted beforeDestroy
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div id="app"> </div> <script src="./vue.js"></script> <script> /* • created 实例创建完成后调用,此阶段完成了数据的观测等,但尚未挂载, $el 还不可用。 需要初始化处理一些数据时会比较有用,后面章节将有介绍. • mounted el 挂载到实例上后调用,一般我们的第一个业务逻辑会在这里开始 • beforeDestroy 实例销毁之前调用。主要解绑一些使用 addEventListener 监听的事件等。 这些钩子与 el data 类似,也是作为选项写入 Vue 实例内,并且钩子的 this 指向的是调用它 的Vue 实例 */ var app = new Vue({ el:'#app', data:{ a:2 }, created:function(){ console.log(this.a); //2 }, mounted:function(){ console.log(this.$el); //<div id='app'></div> } }) </script> </body> </html>
5、插值与表达式 { { } }
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>插值与表达式</title> </head> <body> <div id="app"> {{book}} </div> <script src="./vue.js"></script> <script> /* 使用双大括号( Mustache 语法)“{{}}”是最基本的文本插值方法,它会自动将我们双向绑 定的数据实时显示出来,例如: */ new Vue({ el:'#app', data:{ book:'《Vue.js 实战》' //《Vue.js 实战》 } }) </script> </body> </html>
6、使用vue实现每秒更新现在的实时时间 mounted beforeDestroy timer 设置定时器setInterval 清除定时器clearInterval
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>使用vue实现每秒更新实时时间</title> </head> <body> <div id="app"> {{date}} </div> <script src="./vue.js"></script> <script> var app = new Vue({ el:'#app', data:{ date:new Date() }, mounted:function () { var _this = this; //声名一个变量指向vue实例this,保证作用域一致 this.timer = setInterval(function() { _this.date = new Date(); //修改数据 date }, 1000); }, beforeDestroy: function() { if(this.timer){ clearInterval(this.timer); //在vue实例销毁前,清除定时器 } } }) //Thu Feb 24 2021 16:28:12 GMT+0800 (中国标准时间) </script> </body> </html>
7、使用v-html输出HTML超链接
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>使用v-html输出HTML超链接</title> </head> <body> <div id="app"> <span v-html="link"></span> </div> <script src="./vue.js"></script> <script> //如果有的时候就是想输出 HTML ,而不是将数据解释后的纯文本,可以使用 v-html: new Vue({ el:'#app', data:{ link:'<a href="#">这是一个连接</a>' } }) /* link 的内容将会被渲染为 个具有点击功能的 标签,而不是纯文本。这里要注意,如果将用 户产生的内容使用 v-html 输出后,有可能导致 xss 攻击,所以要在服务端对用户提交的内容进行 处理, 般可将尖括号“< ”转义。 */ </script> </body> </html>
输出结果:
8、在{ { } }中运算,三元运算
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>在{{}}中运算,三元运算</title> </head> <body> <div id="app"> {{number / 10}} {{isOK ? '确定' : '取消'}} {{text.split(',').reverse().join(',')}} </div> <script src="./vue.js"></script> <script> var app = new Vue({ el:'#app', data:{ number:200, isOk:false, text:'hello,world' } }) </script> </body> </html>
9、过滤器 filters 实例,实时时间格式化输出。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>过滤器实例,实时时间格式化输出</title> </head> <body> <div id="app"> {{date | formatDate}} </div> <script src="./vue.js"></script> <script> //在月份、日期、小时等小于10时前加补0 var padDate = function(value){ return value < 10 ? '0' + value : value; } var app = new Vue({ el:'#app', data:{ date:new Date() }, filters: { formatDate: function(value) { //这里的value就是需要过滤的数据 var date = new Date(value); var year = date.getFullYear(); var month = padDate(date.getMonth() + 1); var day = padDate(date.getDate()); var hours = padDate(date.getHours()); var minutes = padDate(date.getMinutes()); var seconds = padDate(date.getSeconds()); //将整理好的数据返回出去 return year + '-' + month + '-' + day + '-' + hours + ':' + minutes + ':' + seconds; } }, mounted:function(){ var _this = this; //声明一个变量指向 Vue实例this,保证作用域一致 this.timer = setInterval(function(){ _this.date = new Date(); //修改数据date },1000) }, beforeDestroy:function(){ if(this.timer){ clearInterval(this.timer); //在vue实例销毁前,清除我们的定时器 } } }) //输出:2021-12-26-11:39:10 </script> </body> </html>
输出:2021-12-26-11:39:10
10、指令与事件 v-if="show"实现网页上的内容显示与否
指令( Directives )是 ue 模板中最常用的 项功能,它带有前缀 -, 在前文我们已经使用 过不少指令了,比如 -if v-html v-pre 等。指令的主要职责就是当其表达式的值改变时,相应地 将某些行为应用到 DOM 上,以 if 为例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>v-if="show"实现网页上的内容显示与否</title> </head> <body> <div id="app"> <p v-if="show">显示这段文字</p> </div> <script src="./vue.js"></script> <script> var app = new Vue({ el:'#app', data:{ show:true //当数据 show 的值为 true 时, 元素会被插入,为 false 时则会被移除 } }) </script> </body> </html>
结果:
11、v-bind更新HTML元素属性
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>11、v-bind更新HTML元素属性</title> </head> <body> <div id="app"> <a v-bind:href="url">链接</a> <img v-bind:src="imgUrl" alt="#"> </div> <script src="./vue.js"></script> <script> //v-bind 的基本用途是动态更新 HTML 元素上的属性 var app = new Vue({ el:'#app', data:{ url:'https://www.github.com', imgUrl:'https://img0.baidu.com/it/u=2936746125,1314779078&fm=253&fmt=auto&app=138&f=JPG?w=200&h=200' } }) </script> </body> </html>
显示结果:
12、v-on绑定事件监听
另一个非常重要的指令就是 v-on ,它用来绑定事件监听器,这样我们就可以做 些交互了, 先来看下面的示例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>12、v-on绑定事件监听</title> </head> <body> <div id="app"> <p v-if="show">这是一段文字</p> <button v-on:click="handleClose">点击隐藏</button> </div> <script src="./vue.js"></script> <script> var app = new Vue({ el:'#app', data:{ show:true }, methods: { handleClose() { this.show = false } }, }) </script> </body> </html>
结果:
在button 按钮上,使用 v-on:click 给该元素绑定了 个点击事件,在普通元素上, v-on 可以监 昕原生的 DOM 事件,除了 click 外,还有 dblclick keyup, mousemove 等。表达式可以是 个方 法名,这些方法都写在 Vue 实例的 methods 属性内,并且是函数的形式,函数内的 this 指向的是当 Vue 实例本身,因此可以直接使用 this.xxx 的形式来访问或修改数据,如示例中的 this.show = false ;把数据 show 修改为了 false ,所以点击按钮时,文本 素就被移除了。
表达式除了方法名, 也可以直接是 个内联语旬,上例也可以改写为:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>12、v-on绑定事件监听</title> </head> <body> <div id="app"> <p v-if="show">这是一段文字</p> <!-- //<button v-on:click="handleClose">点击隐藏</button> --> <button v-on:click="show = false">点击隐藏</button> </div> <script src="./vue.js"></script> <script> var app = new Vue({ el:'#app', data:{ show:true }, // methods: { // handleClose() { // this.show = false // } // }, }) </script> </body> </html>
13、语法糖 <a v-bind:href= "url" >链接 </a> 可以缩写成<a :href= "url" >链接 </a> v- on 可以直接用 @来缩写
语法糖是指在不影响功能的情况下 添加某种方法实现同样的效果 从而方便程序开发。 Vue.js里 v-bind和 v-on 指令都提供了语法糖 也可以说是缩写 比如 v-bind 可以省略 v-bind, 直接写一个冒号 :
例如:
<a v-bind:href="url"></a> <img v-bind:src="imgUrl" alt="">
可以缩写成
<a :href="url"></a> <img :src="imgUrl" alt="">
v- on 可以直接用 @来缩写:
<button v-on:click="handleClose">点击隐藏</button>
可缩写为:
<button @click="handleClose">点击隐藏</button>
第三章 计算属性
14、计算属性
通过上一章的介绍,我们己经可以搭建出一个简单的 Vue 应用,在模板中双向绑定 些数据 或表达式了。但是表达式如果过长,或逻辑更为复杂时,就会变得雕肿甚至难以阅读和维护,比如:
<div id="app"> {{text.split(',').reverse().join(',')}} </div>
这里的表达式包含 3个操作,并不是很清晰,所以在遇到复杂的逻辑时应该使用计算属性。 上例可以用计算属性进行改写:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>13、计算属性</title> </head> <body> <div id="app"> <!-- //{{text.split(',').reverse().join(',')}} --> {{reverseText}} </div> <script src="./vue.js"></script> <script> var app = new Vue({ el:'#app', data:{ text:'123,456' }, computed: { reverseText:function() { return this.text.split(',').reverse().join(',') } }, }) // 输出:456,123 </script> </body> </html>
所有的计算属性都以函数的形式写在vue的实例内的computed选项内,最终返回计算后的结果。
15、计算属性的用法-计算购物车内两个包裹的总价
在一个计算属性里可以完成各种复杂的逻辑,包括运算、函数调用等,只要最终返回 一个结 果就可以。除了上例简单的用法,计算属性还可以依赖多个 vue 实例的数据,只要其中任 一数据 变化,计算属性就会重新执行,视图也会更新。例如,下面的示例展示的是在购物车内两个包裹的 物品总价:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>15、计算属性的用法-计算购物车内两个包裹的总价</title> </head> <body> <div id="app"> 总价:{{prices}} </div> <script src="./vue.js"></script> <script> var app = new Vue({ el:'#app', data:{ package1:[ { name:'iphone13', price:3000, count:1 }, { name:'huawei', price:5000, count:5 } ], package2:[ { name:'xiaomi', price:4000, count:2 }, { name:'vivo', price:3500, count:3 } ] }, computed: { prices:function() { var prices = 0; for(var i = 0; i < this.package1.length; i ++){ prices += this.package1[i].price * this.package1[i].count; } for(var i = 0; i < this.package2.length; i ++){ prices += this.package2[i].price * this.package2[i].count; } return prices } }, }) // 输出:总价:46500 </script> </body> </html>
当package1或 package2 中的商品有任何变化,比如买数量变化或增删商品时,计算属性prices 就会自动更新 视图中的总价也会自动变化。
每一个计算属性都包含一个 getter 和一个 setter,我们上面的两个示例都是计算属性的默认用法,只是利用了getter 来读取。在你需要时,也可以提供一个setter函数,当手动修改计算属性的值就像修改一个普通数据那样时,就会触发setter函数,执行一些自定义的操作,例如:
16、getter读取和setter写入
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>16、getter读取和setter写入</title> </head> <body> <div id="app"> 姓名:{{fullName}} </div> <script src="./vue.js"></script> <script> var app = new Vue({ el:'#app', data:{ firstName:'Jack', lastName:'Green', }, computed: { fullName: { // getter用于读取 get:function(){ return (this.firstName + '' + this.lastName); }, // setter在写入时触发 set:function(newValue){ var names = newValue.split(''); this.firstName = names[0]; this.lastName = names[name.length]; } } }, }) // 输出:姓名:JackGreen </script> </body> </html>
当执行 app.fullName = 'John Green';时,setter就会被调用,数据firstName和 lastName 都会相对更新,视图同样也会更新。
绝大多数情况下,我们只会用默认的getter方法来读取一个计算属性,在业务中很少用到setter,所以在声明一个计算属性时,可以直接使用默认的写法,不必将getter和 setter都声明。
计算属性除了上述简单的文本插值外,还经常用于动态地设置元素的样式名称class和内联样式style,在下章会介绍这方面的内容。当使用组件时,计算属性也经常用来动态传递props,这也会在第7章组件里详细介绍。
计算属性还有两个很实用的小技巧容易被忽略:一是计算属性可以依赖其他计算属性;二是计算属性不仅可以依赖当前Vue实例的数据,还可以依赖其他实例的数据,例如:
-------------------------------------------
个性签名:独学而无友,则孤陋而寡闻。做一个灵魂有趣的人!
如果觉得这篇文章对你有小小的帮助的话,记得在右下角点个“推荐”哦,博主在此感谢!