一、v-for练习

  • v-for 是列表渲染的指令;

请用如下数据生成一个列表

  1. {
  2. fruits: [
  3. {
  4. name: '苹果',
  5. color: ['green', 'yellow']
  6. },
  7. {
  8. name: '香蕉',
  9. color: ['red', 'green', 'yellow']
  10. },
  11. {
  12. name: '芒果',
  13. color: ['green', 'yellow']
  14. }
  15. ]
  16. }
  • vue 代码
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. </head>
  7. <body>
  8. <div id="app">
  9. <ul>
  10. <!--要循环谁,就把 v-for 写在谁身上-->
  11. <li v-for="(item, index) in fruits" :key="index">
  12. {{index + 1}}{{item.name}}
  13. <ul>
  14. <li v-for="(color, cIndex) in item.color" :key="cIndex">{{cIndex + 1}} {{color}}</li>
  15. </ul>
  16. </li>
  17. </ul>
  18. </div>
  19. <script src="vue.js"></script>
  20. <script>
  21. let vm = new Vue({
  22. el: '#app',
  23. data: {
  24. fruits: [
  25. {
  26. name: '苹果',
  27. color: ['green', 'yellow']
  28. },
  29. {
  30. name: '香蕉',
  31. color: ['red', 'green', 'yellow']
  32. },
  33. {
  34. name: '芒果',
  35. color: ['green', 'yellow']
  36. }
  37. ]
  38. }
  39. });
  40. // vue 是数据映射视图,数据的结构就决定了 html 的结构;
  41. </script>
  42. </body>
  43. </html>

二、vue中的事件绑定

使用 v-on 指令

  • Vue 使用 v-on 绑定事件,无需获取 DOM,直接在模板中绑定
  1. <button v-on:click="fn($event, 1, 2)">点我试试</button>

事件函数

  • Vue 的事件函数写在 methods 属性中
  1. let obj = {
  2. el: '#app',
  3. data: {
  4. msg: '你很帅'
  5. },
  6. methods: {
  7. fn (a, b, c) {
  8. // 1. 如果在绑定时,fn 不带小括号,那么函数会默认接收一个事件对象作为参数
  9. // 2. 如果绑定时带有小括号,那么默认不接收事件对象
  10. // 3. 如果既要事件对象,又要传递参数,需要在小括号中写一个 $event 用来标识事件对象,后面才是真正的参数;
  11. console.log(a);
  12. console.log(b);
  13. console.log(c);
  14. }
  15. }
  16. }

示例代码:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. </head>
  7. <body>
  8. <div id="app">
  9. <button v-on:click="fn($event, 1, 2)">点我试试</button>
  10. </div>
  11. <script src="vue.js"></script>
  12. <script>
  13. let vm = new Vue({
  14. el: '#app',
  15. data: {
  16. msg: '你很帅'
  17. },
  18. methods: {
  19. fn (a, b, c) {
  20. // 1. 如果在绑定时,fn 不带小括号,那么函数会默认接收一个事件对象作为参数
  21. // 2. 如果绑定时带有小括号,那么默认不接收事件对象
  22. // 3. 如果既要事件对象,又要传递参数,需要在小括号中写一个 $event 用来标识事件对象,后面才是真正的参数;
  23. console.log(a);
  24. console.log(b);
  25. console.log(c);
  26. }
  27. }
  28. });
  29. // v-on:事件名 绑定事件
  30. // v-on 可以加简写成@
  31. </script>
  32. </body>
  33. </html>

三、事件修饰符

事件修饰符是什么?

  • 为了方便 Vue 的事件处理,Vue 中增加了事件修饰符;
  • 用法:v-on:事件名.修饰符
    示例:
  1. <a href="/" v-on:click.prevent="fn">请点击</a>

常见的事件修饰符

  • 事件修饰符
    • .prevent 阻止元素的默认行为
    • .stop 阻止事件冒泡
    • .capture 事件在捕获阶段触发
    • .once 事件只执行一次
    • .self 只有触发自身的事件才会触发
  • 键盘事件修饰符:
    • .enter 回车
    • .esc 退出
    • .delete 退格
    • .space 空格
    • .tab tab键
    • .left 左
    • .right 右
    • .up 上
    • .down 下

示例代码

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. <style>
  7. #app {
  8. font-size: 40px;
  9. color: red;
  10. }
  11. </style>
  12. </head>
  13. <body>
  14. <div id="app">
  15. <div @click="parent">
  16. parent
  17. <div @click="child">
  18. child
  19. <div @click.stop="grandchild">
  20. grandchild
  21. </div>
  22. </div>
  23. </div>
  24. <a href="/" v-on:click.prevent="fn">请点击</a>
  25. <input type="text" @keydown.up="add" v-model="num">
  26. </div>
  27. <script src="vue.js"></script>
  28. <script>
  29. // 事件修饰符
  30. // .prevent 阻止元素的默认行为
  31. // .stop 阻止事件冒泡
  32. // .capture 事件在捕获阶段触发
  33. // .once 事件只执行一次
  34. // .self 只有触发自身的事件才会触发
  35. // 键盘事件修饰符:
  36. // .enter 回车
  37. // .esc 退出
  38. // .delete 退格
  39. // .space 空格
  40. // .tab tab键
  41. // .left 左
  42. // .right 右
  43. // .up 上
  44. // .down 下
  45. let vm = new Vue({
  46. el: '#app',
  47. data: {
  48. msg: '帅',
  49. num: 1
  50. },
  51. methods: {
  52. fn(e) {
  53. console.log(1)
  54. },
  55. parent() {
  56. console.log('parent');
  57. },
  58. child() {
  59. console.log('child');
  60. },
  61. grandchild() {
  62. console.log('grandchild')
  63. },
  64. add(e) {
  65. this.num++; // 在方法中使用数据,需要使用 this.xxx 的方式获取,并且操作这些值,页面中的值也会跟着改变
  66. console.log('加')
  67. }
  68. }
  69. })
  70. </script>
  71. </body>
  72. </html>

四、练习-简易 todoList

需求

  • todoList 是待处理任务表,在 input 的框中输入一条任务,回车即可加入任务列表;在任务列表中每一行都有一个删除按钮,点击删除按钮即可从任务列表中删除该任务;

示例代码

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. </head>
  7. <body>
  8. <div id="app">
  9. <input type="text" @keydown.enter="add" v-model="todo">
  10. <ul>
  11. <li v-for="(item, index) in todoList" :key="index">
  12. {{item}} <button @click="remove(index)">删除</button>
  13. </li>
  14. </ul>
  15. </div>
  16. <script src="vue.js"></script>
  17. <script>
  18. let vm = new Vue({
  19. el: '#app',
  20. data: {
  21. todoList: [],
  22. todo: ''
  23. },
  24. methods: {
  25. add () {
  26. // methods 里面的方法中的 this 都指向当前 Vue 的实例;
  27. // 把用户输入的内容添加到数组中
  28. this.todoList.push(this.todo);
  29. this.todo = '';
  30. },
  31. remove(index) {
  32. // Vue 是数据驱动的,想要移除某一个 li,只需要从 todoList 中删除对应的数据即可,Vue 是双向数据绑定,一旦数据发生变化,Vue 会按照最新的数据映射视图;
  33. this.todoList.splice(index, 1);
  34. }
  35. }
  36. })
  37. </script>
  38. </body>
  39. </html>

五、过滤器

过滤器是什么?

过滤器:用于处理数据,但是并不会改变原来的数据的一种处理方式;

创建过滤器:

  • 全局过滤器: Vue.filter(过滤器名字, 函数)
  1. Vue.filter('toDollar', val => '$' + val);
  • 局部过滤器
  1. let obj = {
  2. el: '#app',
  3. filters: {
  4. toFixed (val, num = 2) {
  5. // 返回一个保留 num 位的数字
  6. return val.toFixed(num);
  7. },
  8. toRMB(val) {
  9. return '¥' + val;
  10. }
  11. }
  12. };
  13. let vm = new Vue(obj);

使用过滤器

  1. {{1.22222 | toFixed | toRMB}} <br>
  2. {{1.22222 | toFixed(3)}} <br>
  3. {{1.22222 | toFixed | toRMB}} <br>

示例代码

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. </head>
  7. <body>
  8. <div id="app">
  9. {{1.22222 | toFixed | toRMB}} <br>
  10. {{1.22222 | toFixed(3)}} <br>
  11. {{1.22222 | toFixed | toRMB}} <br>
  12. <!-- | 称为管道符,管道符会把其前面的值传给过滤器函数的第一个参数-->
  13. <!--过滤器可以连续使用,后面过滤器的第一个参数是前面过滤器处理后的结果 -->
  14. </div>
  15. <script src="vue.js"></script>
  16. <script>
  17. // 过滤器:用于处理数据,但是并不会改变原来的数据的一种处理方式;
  18. // 注册全局过滤器:这种过滤器在任何地方都能用
  19. // Vue.filter(过滤器名字, 函数)
  20. Vue.filter('toDollar', val => '$' + val);
  21. // 局部过滤器:只能在当前组件可以使用
  22. let vm = new Vue({
  23. el: '#app',
  24. filters: {
  25. toFixed (val, num = 2) {
  26. // 返回一个保留 num 位的数字
  27. return val.toFixed(num);
  28. },
  29. toRMB(val) {
  30. return '¥' + val;
  31. }
  32. }
  33. })
  34. </script>
  35. </body>
  36. </html>

六、radio 和 v-model

单选框中使用 v-model;会把这些绑定 sex 的分为一组,一次只能选中一个

示例:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. </head>
  7. <body>
  8. <div id="app">
  9. <!--单选框中使用 v-model;会把这些绑定 sex 的分为一组,一次只能选中一个-->
  10. <label><input type="radio" v-model="sex" value="男"></label>
  11. <label><input type="radio" v-model="sex" value="女"></label>
  12. <label>其他 <input type="radio" v-model="sex" value="其他"></label>
  13. <br>
  14. {{sex}}
  15. </div>
  16. <script src="vue.js"></script>
  17. <script>
  18. let vm = new Vue({
  19. el: '#app',
  20. data: {
  21. sex: '男'
  22. }
  23. })
  24. </script>
  25. </body>
  26. </html>

七、checkbox

  • 在复选框中,如果只有一个,会将值默认转换成布尔值;
  1. <label>游泳:<input type="checkbox" v-model="val" /></label>
  • 如果多个 checkbox 绑定同一个值,vue 会把选中的值放到一个数组中
  1. <label>睡觉:<input type="checkbox" v-model="hobby" value="睡觉" /></label>
  2. <label>吃饭:<input type="checkbox" v-model="hobby" value="吃饭" /></label>
  3. <label>约会:<input type="checkbox" v-model="hobby" value="约会" /></label>

示例代码

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. </head>
  7. <body>
  8. <div id="app">
  9. <!--在复选框中,如果只有一个,会将值默认转换成布尔值-->
  10. <label>游泳:<input type="checkbox" v-model="val" /></label>
  11. <br>
  12. <!--如果多个 checkbox 绑定同一个值,Vue 会把选中的值放到一个数组中-->
  13. <label>睡觉:<input type="checkbox" v-model="hobby" value="睡觉" /></label>
  14. <label>吃饭:<input type="checkbox" v-model="hobby" value="吃饭" /></label>
  15. <label>约会:<input type="checkbox" v-model="hobby" value="约会" /></label>
  16. <br>
  17. <div>
  18. {{hobby}}
  19. </div>
  20. </div>
  21. <script src="vue.js"></script>
  22. <script>
  23. let vm = new Vue({
  24. el: '#app',
  25. data: {
  26. val: 1,
  27. hobby: []
  28. }
  29. })
  30. </script>
  31. </body>
  32. </html>

八、select

  • select v-model 的值和下面 option 的值相同时会选中该 option;

示例代码

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. </head>
  7. <body>
  8. <div id="app">
  9. <select v-model="hobby">
  10. <option value="1">篮球</option>
  11. <option value="2">羽毛球</option>
  12. <option value="3">乒乓球</option>
  13. </select>
  14. <br>
  15. {{hobby}}
  16. </div>
  17. <script src="vue.js"></script>
  18. <script>
  19. let vm = new Vue({
  20. el: '#app',
  21. data: {
  22. hobby: '3'
  23. }
  24. })
  25. </script>
  26. </body>
  27. </html>

九、axios-vue

在 Vue 中使用 axios

  • 在 Vue 中使用 ajax 请求数据,一般放到 created 钩子函数中

示例代码

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. </head>
  7. <body>
  8. <div id="app">
  9. <ul>
  10. <li v-for="(item, index) in arr" :key="index">
  11. {{item.name}}
  12. <ul>
  13. <li v-for="(sItem, sIndex) in item.list" :key="sIndex">
  14. {{sItem}}
  15. </li>
  16. </ul>
  17. </li>
  18. </ul>
  19. </div>
  20. <script src="axios.js"></script>
  21. <script src="vue.js"></script>
  22. <script>
  23. let vm = new Vue({
  24. el: '#app',
  25. data: {
  26. arr: []
  27. },
  28. created () {
  29. // 当 Vue 的实例创建成功以后会执行这个函数,Vue 中所有的 ajax 请求都在这里发送
  30. console.log(this); // this 是 vm 的实例
  31. this.getData(); // this.getData() 就是 methods 中的 getData() 方法
  32. },
  33. methods: {
  34. getData() {
  35. axios.get('list.json').then(({data}) => {
  36. this.arr = data; // 我们直接把 arr 赋值成一个新的数组,因为 Vue 是响应式的,会自动更新页面
  37. }).catch(e => {
  38. console.log(e)
  39. })
  40. }
  41. }
  42. })
  43. </script>
  44. </body>
  45. </html>

十、bootstrap

bootstrap 是 css 框架,依靠类名来控制 css 样式;

  • bootstrap 采用的是栅格布局,把页面宽度分为12份
  • bootstrap使用类名控制页面的样式
  • .container 容器元素,左右居中
  • .row 行
  • .col-lg-数字 大屏幕
  • .col-md-数字 中等屏幕
  • .col-sm-数字 小屏幕
  • .col-xs-数字 最小屏幕
  • 示例代码
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. <link rel="stylesheet" href="node_modules/bootstrap/dist/css/bootstrap.min.css">
  7. <style>
  8. .row div {
  9. border: 1px solid #000;
  10. }
  11. </style>
  12. </head>
  13. <body>
  14. <!--bootstrap 采用的是栅格布局,把页面宽度分为12份-->
  15. <!--bootstrap 使用类名控制页面的样式-->
  16. <!--
  17. .container 容器元素,左右居中
  18. .row 行
  19. .col-lg-x 大屏幕
  20. .col-md-x 中等屏幕
  21. .col-sm-x 小屏幕
  22. .col-xs-x 最小屏幕
  23. -->
  24. <div class="container">
  25. <div class="row">
  26. <div class="col-md-3">哈哈</div>
  27. <div class="col-md-3">嘿嘿</div>
  28. <div class="col-md-6">呵呵</div>
  29. <div class="col-md-12">嘻嘻</div>
  30. </div>
  31. <table class="table table-bordered table-hover table-striped">
  32. <tr>
  33. <td>
  34. 第一项
  35. </td>
  36. <td>
  37. 第二项
  38. </td>
  39. <td>
  40. 第三项
  41. </td>
  42. </tr>
  43. <tr>
  44. <td>
  45. 第一项
  46. </td>
  47. <td>
  48. 第二项
  49. </td>
  50. <td>
  51. 第三项
  52. </td>
  53. </tr>
  54. <tr>
  55. <td>
  56. 第一项
  57. </td>
  58. <td>
  59. 第二项
  60. </td>
  61. <td>
  62. 第三项
  63. </td>
  64. </tr>
  65. <tr>
  66. <td>
  67. 第一项
  68. </td>
  69. <td>
  70. 第二项
  71. </td>
  72. <td>
  73. 第三项
  74. </td>
  75. </tr>
  76. </table>
  77. </div>
  78. </body>
  79. </html>

十一、练习-购物车案例

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. <link rel="stylesheet" href="node_modules/bootstrap/dist/css/bootstrap.min.css">
  7. </head>
  8. <body>
  9. <div id="app">
  10. <!--caption 只能放在 table 中使用:表头-->
  11. <!--bootstrap-->
  12. <div class="container">
  13. <div class="row">
  14. <h2 class="text-center text-danger">珠峰购物车</h2>
  15. <table class="table table-bordered">
  16. <tr>
  17. <td>
  18. 全选 <input type="checkbox" v-model="checkAll" @change="changeAll"/>
  19. </td>
  20. <td>
  21. 商品
  22. </td>
  23. <td>
  24. 单价
  25. </td>
  26. <td>
  27. 数量
  28. </td>
  29. <td>
  30. 小计
  31. </td>
  32. <td>
  33. 操作
  34. </td>
  35. </tr>
  36. <tr v-for="(product, index) in products" :key="index">
  37. <!-- {
  38. "isSelected": true,
  39. "productCover": "https://img10.360buyimg.com/cms/s80x80_jfs/t6094/107/710811867/382815/4d54717/592bf165N755a88f0.jpg",
  40. "productName": "深入浅出Node.js",
  41. "productInfo": "颜色:Node.js学习",
  42. "productPrice": 57.8,
  43. "productCount": 3
  44. }-->
  45. <td><input type="checkbox" v-model="product.isSelected" @change="changeOne"></td>
  46. <td>
  47. <img :src="product.productCover" :title="product.productName" alt="">
  48. {{product.productInfo}}
  49. </td>
  50. <td>
  51. {{product.productPrice}}
  52. </td>
  53. <td>
  54. <input type="number" v-model="product.productCount" min="1"/>
  55. </td>
  56. <td>
  57. {{product.productPrice * product.productCount | toFixed(2)}}
  58. </td>
  59. <td>
  60. <button class="btn btn-danger" @click="remove(product)">删除</button>
  61. </td>
  62. </tr>
  63. <tr>
  64. <td colspan="6">
  65. 总价格:{{sum() | toFixed}}
  66. </td>
  67. </tr>
  68. </table>
  69. </div>
  70. </div>
  71. </div>
  72. <script src="axios.js"></script>
  73. <script src="vue.js"></script>
  74. <script>
  75. let vm = new Vue({
  76. el: '#app',
  77. data: {
  78. products: [],
  79. checkAll: true
  80. },
  81. filters: {
  82. toFixed(val, num = 2) {
  83. return '¥' + val.toFixed(num)
  84. }
  85. },
  86. created() {
  87. this.getData();
  88. },
  89. methods: {
  90. getData() {
  91. axios.get('carts.json').then(({data}) => {
  92. this.products = data;
  93. })
  94. },
  95. remove(val) {
  96. // val 点击时删除的 product
  97. this.products = this.products.filter(item => item !== val);
  98. },
  99. changeAll() {
  100. // 如果全选为 true,即 this.checkAll 为 true,下面的商品的 checkbox 都要选中,如果是全选是 false,那么商品的 checkbox 也是 false
  101. this.products.forEach(item => item.isSelected = this.checkAll)
  102. },
  103. changeOne() {
  104. // 点击每一个 input 的复选框时,去校验是否有是所有的 product 中的 isSelected 都为 true,如果都是 true,那么 checkAll 结果也是 true,如果有一个是 false,那么 checkAll 就是 false,使用 every 方法
  105. this.checkAll = this.products.every(item => item.isSelected);
  106. },
  107. sum() {
  108. /* let total = 0;
  109. this.products.filter(item => item.isSelected).forEach(item => total += (item.productPrice * item.productCount));
  110. return total;*/
  111. return this.products.filter(item => item.isSelected).reduce((prev, next) => {
  112. return prev + next.productPrice * next.productCount;
  113. }, 0)
  114. }
  115. }
  116. })
  117. </script>
  118. </body>
  119. </html>