vue之简单操作
一、style和class使用
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="./js/vue.js"></script> <style> .red { background-color: red; } .size { font-size: 40px; } </style> </head> <body> <div id="app"> <div class="red"></div> // 这样写的话就把该标签的属性给写死了 该标签就是一个red 添加不好添加 <h1>class的使用</h1> <div :class="classObj"> // 这样通过动态绑定就可以实时修改也可以不修改 我是class,的div </div> <h1>style的使用</h1> <!-- <div style="background-color: aquamarine;font-size: 50px">--> <div :style="styleObj"> 我是style,的div </div> </div> </body> <script> var vm = new Vue({ el: '#app', data: { // class的字符串用法 classStr: 'red', // class的数组写法,因为类本身可以放多个,用数组最合适 classList: ['red'], // class的对象 classObj: {red: true, size: false}, // style 的字符串写法,以后改不好改 styleStr: 'background-color: aquamarine;font-size: 50px', // style的数组写法 // styleList: [{'background-color': 'green'}, {'font-size': '80px'}] // 样式如果是多个单词用- 链接的形式可以写成驼峰 styleList: [{backgroundColor: 'green'}, {fontSize: '80px'}], // style的对象写法 使用对象最合适 styleObj: {backgroundColor: 'blue', fontSize: '40px'} } }) </script> </html>
二、条件渲染
# 写在标签上,控制标签的显示与不显示 v-if='布尔值/运算完是布尔值' v-else-if='布尔值/运算完是布尔值' v-else
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="./js/vue.js"></script> </head> <body> <div id="app"> <h1>条件渲染</h1> <div v-if="score>=90">优秀</div> // 如果分数大于等于90就会为true 那么这个标签就会显示 <div v-else-if="score>=80 && score<90">良好</div> <div v-else-if="score>=60 && score<80">及格</div> <div v-else>不及格</div> // 上面三个条件都不成立 才会执行这个标签 这个标签才会显示 </div> </body> <script> var vm = new Vue({ el: '#app', data: { score: 98 } }) </script> </html>
三、列表渲染
# v-for:放在标签上,可以循环显示多个此标签
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="./js/vue.js"></script> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css"> <style> .top { margin-top: 50px; } </style> </head> <body> <div id="app"> <div class="container-fluid"> <div class="row top"> <div class="col-md-6 col-md-offset-3"> <div class="text-center" style="margin-bottom: 30px"> <button @click="handleClick" class="btn btn-danger">加载购物车</button> // 该点击事件 就是模拟从后端加载数据 然后把data中的变量goodList追加商品 </div> <div v-if="goodList.length>0"> <!--这个就是判断商品列表中是否有值 一开始是没有值的所以就不显示 点击事件之后 就有了值 那么就会显示--> <table class="table table-bordered"> <thead> <tr> <th>商品id号</th> <th>商品名</th> <th>商品价格</th> <th>商品数量</th> </tr> </thead> <tbody> <tr v-for="good in goodList"> <!--把商品列表 一个一个循环出来--> <th>{{good.id}}</th> <td>{{good.name}}</td> <td>{{good.price}}</td> <td>{{good.count}}</td> </tr> </tbody> </table> </div> <div v-else> <!--商品列表中如果没有值 就会执行else --> 购物车空空如何 </div> </div> </div> </div> </div> </body> <script> var vm = new Vue({ el: '#app', data: { goodList: [] }, methods: { handleClick() { // 假设去后端加载的数据 this.goodList = [{id: 1, name: '小汽车', price: '29999元', count: 1}, {id: 2, name: '钢笔', price: '9元', count: 2}, {id: 3, name: '铅笔', price: '4元', count: 10}, {id: 4, name: '苹果', price: '2元', count: 3},] } } }) </script> </html>
3.1 v-for循环数组、字符串、数字、对象
# v-for 可以循环数组,数字,字符串,对象 v-for="key in obj" -如果是数组:key就是数组的一个个元素 -如果是数字:key就是从1开始的一个个数字 -如果是字符串:key就是一个个字符 -如果是对象:key就是一个个value的值 v-for="(key,value) in obj" -如果是数组:key就是数组的一个个元素,value就是索引 -如果是数字:key就是从1开始的一个个数字,value就是索引 -如果是字符串:key就是一个个字符,value就是索引 -如果是对象:key就是一个个value的值,value就是一个个key # 每次循环的标签上,一般都会带一个属性: :key='值必须唯一' -key值得解释:为了加速虚拟dom的替换 为了修改值后 快速加载出画面来
<table class="table table-bordered"> <thead> <tr> <th>商品id号</th> <th>商品名</th> <th>商品价格</th> <th>商品数量</th> </tr> </thead> <tbody> <tr v-for="good in goodList" :key="good.id"> <!--可以把循环的每一行加一个 :key值 这样修改之后 再次加载会快一点 也可以不加 但是如果加了必须是唯一值 所以我把商品列表的id值做key 因为id是唯一的
vue中使用的是虚拟DOM,会和原生的DOM进行比较,然后进行数据的更新,提高数据的刷新速度(虚拟DOM用了diff算法)--> <th>{{good.id}}</th> <td>{{good.name}}</td> <td>{{good.price}}</td> <td>{{good.count}}</td> </tr> </tbody> </table>
3.2 数组和对象的检测和更新
# 有时候,我们用一些数组,对象的方法更新数组或对象的时候,发现页面没有变化 # 因为有些原生js数组和对象的一些内置方法 作者没有重写方法
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="./js/vue.js"></script> </head> <body> <div id="app"> <h1>数组的检测与更新</h1> <button @click="handleClick">点我追加女生</button> | <button @click="handleClick1">点我追加一批女生</button>| <button @click="handleClick4">点我修改数组页面变化</button>| <p v-for="girl in girls">{{girl}}</p> <h1>对象的检测与更新</h1> <button @click="handleClick2">点我追加身高</button> | <button @click="handleClick3">点我追加身高--解决</button> | <p v-for="(value,key) in obj">{{key}}---{{value}}</p> </div> </body> <script> var vm = new Vue({ el: '#app', data: { girls: ['刘亦菲', '迪丽热巴', '杨超越', '刘诗诗'], obj: {'name': 'lqz', age: 19} }, methods: { handleClick() { this.girls.push('美女1号') // 页面是发生变化了 }, handleClick1() { var a = this.girls.concat(['美女99号', '美女88号', '美女77号']) // 页面没有发生变化 console.log(a) }, handleClick2() { this.obj.height = '180' // 监控不到变化 页面没有发生 console.log(this.obj) }, handleClick3() { Vue.set(this.obj,'height',180) // 监控到变化了 页面才会显示 添加到了对象里 }, handleClick4(){ Vue.set(this.girls,0,'sdasdfas') // 这样写才可以监控到变化 页面才会显示添加到了数组里 } } }) // 所以不管是对象还是数组 如果使用了内置方法 页面没有发生变化 可以使用下面的方法 handClick5() { Vue.set(vm.obj, 'gender', '男') // Vue.set(添加的对象,key,value) Vue.set(this.girls,0,'sdasdfas') // Vue.set(添加的数组,索引,value) }, </script> </html>
四、双向数据绑定
# input标签,v-model:数据双向绑定 -使用 属性指令绑定 :value='变量' 是数据的单向绑定 # 数据发生变化 页面没有发生变化 - v-model="name" :数据双向绑定 # 这个时候不管页面发生变化 数据也会发生变化
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="./js/vue.js"></script> </head> <body> <div id="app"> <h1>数据双向绑定</h1> <p>用户名: <input type="text" v-model="name"></p> <p>密码: <input type="password" v-model="password"></p> // 用户输入什么 变量name和password会实时变化 <button @click="handleSubmit">提交</button>{{err}} </div> </body> <script> var vm = new Vue({ el: '#app', data: { name: '', password: '', err:'' }, methods: { handleSubmit() { console.log(this.name, this.password) this.err='用户名密码错误' } } }) </script> </html>
五、事件处理
# 事件绑定 v-on:事件名='函数'---》@事件名='函数' # input 也有很多事件 -blur:失去焦点触发 就是光标还在输入框闪烁就是焦点还在这个输入框 -change:发生变化触发 不发生变化不触发 -input:输入触发
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="./js/vue.js"></script> </head> <body> <div id="app"> <h1>input的事件处理</h1> <h2>blur</h2> <p><input type="text" v-model="name1" @blur="handleBlur"> ---->{{name1}}</p> <!--是要失去焦点就会触发 不管输入框中有没有发生变化--> <h2>change</h2> <p><input type="text" v-model="name2" @change="handleChange"> ---->{{name2}}</p> <!--就是输入框不管怎么改变 最后都是鼠标点击其他地方时 才会跟原来输入框中的字符比较 看有没有发送变化--> <h2>input</h2> <p><input type="text" v-model="name3" @input="handleInput"> ---->{{name3}}</p> <!--用户只要输入 都会触发--> </div> </body> <script> var vm = new Vue({ el: '#app', data: { name1: '', name2: '', name3: '' }, methods: { handleBlur() { console.log('失去焦点了,触发了', this.name1) }, handleChange() { console.log('发生变化,触发了', this.name2) }, handleInput() { console.log('输入了内容,触发了', this.name3) } } }) </script> </html>
5.1 过滤案例
# 现在我们可以写一个搜索输入框的案例 就是用户输入什么下方列表会根据用户的输入 # 然后比较列表中的值 把接近的值留下 不接近的值给删除
写这个案例之前需要补充一些知识点
<script> // 补充1:数组的过滤方法 var l = ['a', 'at', 'atom', 'be', 'beyond', 'cs', 'csrf'] var ll = l.filter(function (item) { return false // 返回false就删除 返回true就保留 }) console.log(ll) // 补充2: 判断子字符串是否在字符串中 大于等于0,表示子字符串在字符串中 var name = 'qq' var s = 'jason NB' var res = s.indexOf(name) console.log(res) // 补充3: es6的箭头函数 有什么用? 1 简洁 2 箭头函数没有自己的this,会用上一层的this var l = ['a', 'at', 'atom', 'be', 'beyond', 'cs', 'csrf'] var ll = l.filter( item => { return false }) console.log(ll) // var obj = { // 'f': function (item) { // console.log(item) // } // } var obj = { 'f': item => { console.log(item) } } obj['f']('999') var obj = { f: function () { console.log('匿名函数的this', this) }, f1: () => { console.log('箭头函数的this', this) } } obj.f() obj.f1() </script>
代码演示
<body> <div id="app"> <div class="row"> <div class="col-md-6 col-md-offset-3"> <h1>过滤案例</h1> <div><input type="text" v-model="data" @input="handleInput"></div> <ul> <li v-for="item in newList">{{item}}</li> </ul> </div> </div> </div> </body> <script> var vm = new Vue({ el: '#app', data: { data: '', dataList: ['a', 'at', 'atom', 'atoms', 'b', 'bs', 'bson', 'c', 'cs', 'csrf'], newList: ['a', 'at', 'atom', 'atoms', 'b', 'bs', 'bson', 'c', 'cs', 'csrf'], }, methods: { handleInput() { // this.newList = this.dataList.filter(item => { // 因为是this.所以是用户输入的值 是从dataList中比较 存在就保留 不存在才会删除 删除的是newList数组中的值 // 所以就算用户输入到一半再删除掉 最后dataList中的值是不变的 还是会把newList数组填满 还是会显示全部 // // if (item.indexOf(this.data) >= 0) { // // return true // // } else { // // return false // // } // }) // 简单写法 this.newList = this.dataList.filter(item => { item.indexOf(this.data) >= 0 // 用户输入的存在就会返回true 不存在就会返回false }) // 就是把匿名函数写成了箭头函数 然后因为filter返回的是布尔值 如果只返回一行 就可以不用写return } }, }) </script>
5.2 事件修饰符
.stop 只处理自己的事件,不向父控件冒泡
.self 只处理自己的事件,子控件冒泡的事件不处理
.prevent 阻止a链接的跳转
.once 事件只会触发一次(适用于抽奖页面)
<script src="./js/vue.js"></script> <div id="app"> <div class="row"> <div class="col-md-6 col-md-offset-3"> <h1>事件修饰符</h1> <ul @click.self="handleUl"> // 该修饰就是让该标签只执行自己的事件 冒泡上来的事件不执行 <li @click.stop="handleClick2">第一行</li> // 该修饰就是让该标签只处理自己的事件 不会往为父标签上传递 然后阻止事件冒泡 <li>第二行</li> </ul> <hr> <a @click.prevent="handlePrevent" href="http://www.baidu.com">点我去百度</a> // 该修饰就是让a标签不能跳转 然后我们在js代码中 然这个a标签跳转到了其他页面 <hr> <button @click.once="handleOnce">秒杀</button> // 该修饰就是让该事件只能触发一次 如果还想触发必须刷新页面 </div> </div> </div> <script> var vm = new Vue({ el: '#app', data: {}, methods: { handleUl() { alert('ul被点了') }, handleClick2() { alert('第一行被点了') }, handlePrevent() { alert('a被点了 但是不跳转') location.href = 'http://www.cnblogs.com' }, handleOnce(){ console.log('秒了') } } }) </script>
5.3 按键修饰符
// 键盘有很多按键, 回车,字母,esc... 按下或则抬起能够触发某个事件(函数的执行) <script src="./js/vue.js"></script> <div id="app"> 普通使用:<input type="text" v-model="myText" @keydown="handleDown($event)"> // 如果什么都不写 那么 键盘上的任意一个 按键被按下都会触发 @keydown="handleDown($event)" <hr> 监控enter键:<input type="text" v-model="myText" @keydown.enter="handleDown1()"> // 可以在后面写上按键的英文 或则按键对应的数字 @keydown.enter="handleDown1()" </div> <script> new Vue({ el: '#app', data: { myText: '' }, methods: { handleDown(event) { console.log(event.key) }, handleDown1() { console.log('esc被按了') } }, }) </script>