一、v-for练习
- v-for 是列表渲染的指令;
请用如下数据生成一个列表
{fruits: [{name: '苹果',color: ['green', 'yellow']},{name: '香蕉',color: ['red', 'green', 'yellow']},{name: '芒果',color: ['green', 'yellow']}]}
- vue 代码
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Title</title></head><body><div id="app"><ul><!--要循环谁,就把 v-for 写在谁身上--><li v-for="(item, index) in fruits" :key="index">{{index + 1}}{{item.name}}<ul><li v-for="(color, cIndex) in item.color" :key="cIndex">{{cIndex + 1}} {{color}}</li></ul></li></ul></div><script src="vue.js"></script><script>let vm = new Vue({el: '#app',data: {fruits: [{name: '苹果',color: ['green', 'yellow']},{name: '香蕉',color: ['red', 'green', 'yellow']},{name: '芒果',color: ['green', 'yellow']}]}});// vue 是数据映射视图,数据的结构就决定了 html 的结构;</script></body></html>
二、vue中的事件绑定
使用 v-on 指令
- Vue 使用 v-on 绑定事件,无需获取 DOM,直接在模板中绑定
<button v-on:click="fn($event, 1, 2)">点我试试</button>
事件函数
- Vue 的事件函数写在 methods 属性中
let obj = {el: '#app',data: {msg: '你很帅'},methods: {fn (a, b, c) {// 1. 如果在绑定时,fn 不带小括号,那么函数会默认接收一个事件对象作为参数// 2. 如果绑定时带有小括号,那么默认不接收事件对象// 3. 如果既要事件对象,又要传递参数,需要在小括号中写一个 $event 用来标识事件对象,后面才是真正的参数;console.log(a);console.log(b);console.log(c);}}}
示例代码:
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Title</title></head><body><div id="app"><button v-on:click="fn($event, 1, 2)">点我试试</button></div><script src="vue.js"></script><script>let vm = new Vue({el: '#app',data: {msg: '你很帅'},methods: {fn (a, b, c) {// 1. 如果在绑定时,fn 不带小括号,那么函数会默认接收一个事件对象作为参数// 2. 如果绑定时带有小括号,那么默认不接收事件对象// 3. 如果既要事件对象,又要传递参数,需要在小括号中写一个 $event 用来标识事件对象,后面才是真正的参数;console.log(a);console.log(b);console.log(c);}}});// v-on:事件名 绑定事件// v-on 可以加简写成@</script></body></html>
三、事件修饰符
事件修饰符是什么?
- 为了方便 Vue 的事件处理,Vue 中增加了事件修饰符;
- 用法:v-on:事件名.修饰符
示例:
<a href="/" v-on:click.prevent="fn">请点击</a>
常见的事件修饰符
- 事件修饰符
- .prevent 阻止元素的默认行为
- .stop 阻止事件冒泡
- .capture 事件在捕获阶段触发
- .once 事件只执行一次
- .self 只有触发自身的事件才会触发
- 键盘事件修饰符:
- .enter 回车
- .esc 退出
- .delete 退格
- .space 空格
- .tab tab键
- .left 左
- .right 右
- .up 上
- .down 下
示例代码
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Title</title><style>#app {font-size: 40px;color: red;}</style></head><body><div id="app"><div @click="parent">parent<div @click="child">child<div @click.stop="grandchild">grandchild</div></div></div><a href="/" v-on:click.prevent="fn">请点击</a><input type="text" @keydown.up="add" v-model="num"></div><script src="vue.js"></script><script>// 事件修饰符// .prevent 阻止元素的默认行为// .stop 阻止事件冒泡// .capture 事件在捕获阶段触发// .once 事件只执行一次// .self 只有触发自身的事件才会触发// 键盘事件修饰符:// .enter 回车// .esc 退出// .delete 退格// .space 空格// .tab tab键// .left 左// .right 右// .up 上// .down 下let vm = new Vue({el: '#app',data: {msg: '帅',num: 1},methods: {fn(e) {console.log(1)},parent() {console.log('parent');},child() {console.log('child');},grandchild() {console.log('grandchild')},add(e) {this.num++; // 在方法中使用数据,需要使用 this.xxx 的方式获取,并且操作这些值,页面中的值也会跟着改变console.log('加')}}})</script></body></html>
四、练习-简易 todoList
需求
- todoList 是待处理任务表,在 input 的框中输入一条任务,回车即可加入任务列表;在任务列表中每一行都有一个删除按钮,点击删除按钮即可从任务列表中删除该任务;
示例代码
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Title</title></head><body><div id="app"><input type="text" @keydown.enter="add" v-model="todo"><ul><li v-for="(item, index) in todoList" :key="index">{{item}} <button @click="remove(index)">删除</button></li></ul></div><script src="vue.js"></script><script>let vm = new Vue({el: '#app',data: {todoList: [],todo: ''},methods: {add () {// methods 里面的方法中的 this 都指向当前 Vue 的实例;// 把用户输入的内容添加到数组中this.todoList.push(this.todo);this.todo = '';},remove(index) {// Vue 是数据驱动的,想要移除某一个 li,只需要从 todoList 中删除对应的数据即可,Vue 是双向数据绑定,一旦数据发生变化,Vue 会按照最新的数据映射视图;this.todoList.splice(index, 1);}}})</script></body></html>
五、过滤器
过滤器是什么?
过滤器:用于处理数据,但是并不会改变原来的数据的一种处理方式;
创建过滤器:
- 全局过滤器: Vue.filter(过滤器名字, 函数)
Vue.filter('toDollar', val => '$' + val);
- 局部过滤器
let obj = {el: '#app',filters: {toFixed (val, num = 2) {// 返回一个保留 num 位的数字return val.toFixed(num);},toRMB(val) {return '¥' + val;}}};let vm = new Vue(obj);
使用过滤器
{{1.22222 | toFixed | toRMB}} <br>{{1.22222 | toFixed(3)}} <br>{{1.22222 | toFixed | toRMB}} <br>
示例代码
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Title</title></head><body><div id="app">{{1.22222 | toFixed | toRMB}} <br>{{1.22222 | toFixed(3)}} <br>{{1.22222 | toFixed | toRMB}} <br><!-- | 称为管道符,管道符会把其前面的值传给过滤器函数的第一个参数--><!--过滤器可以连续使用,后面过滤器的第一个参数是前面过滤器处理后的结果 --></div><script src="vue.js"></script><script>// 过滤器:用于处理数据,但是并不会改变原来的数据的一种处理方式;// 注册全局过滤器:这种过滤器在任何地方都能用// Vue.filter(过滤器名字, 函数)Vue.filter('toDollar', val => '$' + val);// 局部过滤器:只能在当前组件可以使用let vm = new Vue({el: '#app',filters: {toFixed (val, num = 2) {// 返回一个保留 num 位的数字return val.toFixed(num);},toRMB(val) {return '¥' + val;}}})</script></body></html>
六、radio 和 v-model
单选框中使用 v-model;会把这些绑定 sex 的分为一组,一次只能选中一个
示例:
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Title</title></head><body><div id="app"><!--单选框中使用 v-model;会把这些绑定 sex 的分为一组,一次只能选中一个--><label>男 <input type="radio" v-model="sex" value="男"></label><label>女 <input type="radio" v-model="sex" value="女"></label><label>其他 <input type="radio" v-model="sex" value="其他"></label><br>{{sex}}</div><script src="vue.js"></script><script>let vm = new Vue({el: '#app',data: {sex: '男'}})</script></body></html>
七、checkbox
- 在复选框中,如果只有一个,会将值默认转换成布尔值;
<label>游泳:<input type="checkbox" v-model="val" /></label>
- 如果多个 checkbox 绑定同一个值,vue 会把选中的值放到一个数组中
<label>睡觉:<input type="checkbox" v-model="hobby" value="睡觉" /></label><label>吃饭:<input type="checkbox" v-model="hobby" value="吃饭" /></label><label>约会:<input type="checkbox" v-model="hobby" value="约会" /></label>
示例代码
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Title</title></head><body><div id="app"><!--在复选框中,如果只有一个,会将值默认转换成布尔值--><label>游泳:<input type="checkbox" v-model="val" /></label><br><!--如果多个 checkbox 绑定同一个值,Vue 会把选中的值放到一个数组中--><label>睡觉:<input type="checkbox" v-model="hobby" value="睡觉" /></label><label>吃饭:<input type="checkbox" v-model="hobby" value="吃饭" /></label><label>约会:<input type="checkbox" v-model="hobby" value="约会" /></label><br><div>{{hobby}}</div></div><script src="vue.js"></script><script>let vm = new Vue({el: '#app',data: {val: 1,hobby: []}})</script></body></html>
八、select
- select v-model 的值和下面 option 的值相同时会选中该 option;
示例代码
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Title</title></head><body><div id="app"><select v-model="hobby"><option value="1">篮球</option><option value="2">羽毛球</option><option value="3">乒乓球</option></select><br>{{hobby}}</div><script src="vue.js"></script><script>let vm = new Vue({el: '#app',data: {hobby: '3'}})</script></body></html>
九、axios-vue
在 Vue 中使用 axios
- 在 Vue 中使用 ajax 请求数据,一般放到 created 钩子函数中
示例代码
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Title</title></head><body><div id="app"><ul><li v-for="(item, index) in arr" :key="index">{{item.name}}<ul><li v-for="(sItem, sIndex) in item.list" :key="sIndex">{{sItem}}</li></ul></li></ul></div><script src="axios.js"></script><script src="vue.js"></script><script>let vm = new Vue({el: '#app',data: {arr: []},created () {// 当 Vue 的实例创建成功以后会执行这个函数,Vue 中所有的 ajax 请求都在这里发送console.log(this); // this 是 vm 的实例this.getData(); // this.getData() 就是 methods 中的 getData() 方法},methods: {getData() {axios.get('list.json').then(({data}) => {this.arr = data; // 我们直接把 arr 赋值成一个新的数组,因为 Vue 是响应式的,会自动更新页面}).catch(e => {console.log(e)})}}})</script></body></html>
十、bootstrap
bootstrap 是 css 框架,依靠类名来控制 css 样式;
- bootstrap 采用的是栅格布局,把页面宽度分为12份
- bootstrap使用类名控制页面的样式
- .container 容器元素,左右居中
- .row 行
- .col-lg-数字 大屏幕
- .col-md-数字 中等屏幕
- .col-sm-数字 小屏幕
- .col-xs-数字 最小屏幕
- 示例代码
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Title</title><link rel="stylesheet" href="node_modules/bootstrap/dist/css/bootstrap.min.css"><style>.row div {border: 1px solid #000;}</style></head><body><!--bootstrap 采用的是栅格布局,把页面宽度分为12份--><!--bootstrap 使用类名控制页面的样式--><!--.container 容器元素,左右居中.row 行.col-lg-x 大屏幕.col-md-x 中等屏幕.col-sm-x 小屏幕.col-xs-x 最小屏幕--><div class="container"><div class="row"><div class="col-md-3">哈哈</div><div class="col-md-3">嘿嘿</div><div class="col-md-6">呵呵</div><div class="col-md-12">嘻嘻</div></div><table class="table table-bordered table-hover table-striped"><tr><td>第一项</td><td>第二项</td><td>第三项</td></tr><tr><td>第一项</td><td>第二项</td><td>第三项</td></tr><tr><td>第一项</td><td>第二项</td><td>第三项</td></tr><tr><td>第一项</td><td>第二项</td><td>第三项</td></tr></table></div></body></html>
十一、练习-购物车案例
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Title</title><link rel="stylesheet" href="node_modules/bootstrap/dist/css/bootstrap.min.css"></head><body><div id="app"><!--caption 只能放在 table 中使用:表头--><!--bootstrap--><div class="container"><div class="row"><h2 class="text-center text-danger">珠峰购物车</h2><table class="table table-bordered"><tr><td>全选 <input type="checkbox" v-model="checkAll" @change="changeAll"/></td><td>商品</td><td>单价</td><td>数量</td><td>小计</td><td>操作</td></tr><tr v-for="(product, index) in products" :key="index"><!-- {"isSelected": true,"productCover": "https://img10.360buyimg.com/cms/s80x80_jfs/t6094/107/710811867/382815/4d54717/592bf165N755a88f0.jpg","productName": "深入浅出Node.js","productInfo": "颜色:Node.js学习","productPrice": 57.8,"productCount": 3}--><td><input type="checkbox" v-model="product.isSelected" @change="changeOne"></td><td><img :src="product.productCover" :title="product.productName" alt="">{{product.productInfo}}</td><td>{{product.productPrice}}</td><td><input type="number" v-model="product.productCount" min="1"/></td><td>{{product.productPrice * product.productCount | toFixed(2)}}</td><td><button class="btn btn-danger" @click="remove(product)">删除</button></td></tr><tr><td colspan="6">总价格:{{sum() | toFixed}}</td></tr></table></div></div></div><script src="axios.js"></script><script src="vue.js"></script><script>let vm = new Vue({el: '#app',data: {products: [],checkAll: true},filters: {toFixed(val, num = 2) {return '¥' + val.toFixed(num)}},created() {this.getData();},methods: {getData() {axios.get('carts.json').then(({data}) => {this.products = data;})},remove(val) {// val 点击时删除的 productthis.products = this.products.filter(item => item !== val);},changeAll() {// 如果全选为 true,即 this.checkAll 为 true,下面的商品的 checkbox 都要选中,如果是全选是 false,那么商品的 checkbox 也是 falsethis.products.forEach(item => item.isSelected = this.checkAll)},changeOne() {// 点击每一个 input 的复选框时,去校验是否有是所有的 product 中的 isSelected 都为 true,如果都是 true,那么 checkAll 结果也是 true,如果有一个是 false,那么 checkAll 就是 false,使用 every 方法this.checkAll = this.products.every(item => item.isSelected);},sum() {/* let total = 0;this.products.filter(item => item.isSelected).forEach(item => total += (item.productPrice * item.productCount));return total;*/return this.products.filter(item => item.isSelected).reduce((prev, next) => {return prev + next.productPrice * next.productCount;}, 0)}}})</script></body></html>
【发上等愿,结中等缘,享下等福,择高处立,寻平处住,向宽处行】
