VueJS 模板语法

VueJS 模板语法

Mustache

  • 如何将data中的文本数据,插入到HTML中呢?

    • 我们已经学习过了,可以通过Mustache语法(也就是双大括号)。
    • Mustache: 胡子/胡须.
  • 我们可以像下面这样来使用,并且数据是响应式的

    <!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">
          <h1>{{10+20}}</h1>
          <h1>{{'hello'+'world'}}</h1>
          <h1>{{isExists?'存在':'不存在'}}</h1>
        </div>
      </body>
      <script src="../vue.js"></script>
      <script>
        const app = new Vue({
          el: "#app",
          data: {
            isExists: true,
          },
        });
      </script>
    </html>
    

    在这里插入图片描述

v-once

  • 在某些情况下,我们可能不希望界面随意的跟随改变

    • 这个时候,我们就可以使用一个Vue的指令
  • v-once:

    • 该指令后面不需要跟任何表达式(比如之前的v-for后面是由跟表达式的)
    • 该指令表示元素和组件(组件后面才会学习)只渲染一次,不会随着数据的改变而改变。
  • 代码如下:

    <!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">
          <h1 v-once>{{msg}}</h1>
          <h1>{{msg}}</h1>
        </div>
      </body>
      <script src="../vue.js"></script>
      <script>
        const app = new Vue({
          el: "#app",
          data: {
            msg: "hello Vuejs",
          },
        });
      </script>
    </html>
    

    在这里插入图片描述

v-html

  • 某些情况下,我们从服务器请求到的数据本身就是一个HTML代码

    • 如果我们直接通过{{}}来输出,会将HTML代码也一起输出。
    • 但是我们可能希望的是按照HTML格式进行解析,并且显示对应的内容。
  • 如果我们希望解析出HTML展示

    • 可以使用v-html指令

      • 该指令后面往往会跟上一个string类型

      • 会将stringhtml解析出来并且进行渲染

        <!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">
              <h1>{{link}}</h1>
              <h1 v-html="link"></h1>
            </div>
          </body>
          <script src="../vue.js"></script>
          <script>
            const app = new Vue({
              el: "#app",
              data: {
                link: '<a href="http://www.baidu.com/">百度一下</a>',
              },
            });
          </script>
        </html>
        

        在这里插入图片描述

v-text

  • v-text作用和Mustache比较相似:都是用于将数据显示在界面中

  • v-text会将接收到的值展示到界面中

    <!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">
          <h1>{{msg}}</h1>
          <h1 v-text="msg"></h1>
        </div>
      </body>
      <script src="../vue.js"></script>
      <script>
        const app = new Vue({
          el: "#app",
          data: {
            msg: "hello Vuejs",
          },
        });
      </script>
    </html>
    

    在这里插入图片描述

v-pre

  • v-pre用于跳过这个元素和它子元素的编译过程,用于显示原本的Mustache语法。

  • 比如下面的代码:

    • 第一个h1元素中的内容会被编译解析出来对应的内容

    • 第二个h1元素中会直接显示{{message}}

      <!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">
            <h1>{{10+20}}</h1>
            <h1 v-pre>{{10+20}}</h1>
          </div>
        </body>
        <script src="../vue.js"></script>
        <script>
          const app = new Vue({
            el: "#app",
            data: {},
          });
        </script>
      </html>
      

      在这里插入图片描述

v-bind介绍

  • 前面我们学习的指令主要作用是将值插入到我们模板的内容当中。

  • 但是,除了内容需要动态来决定外,某些属性我们也希望动态来绑定。

    • 比如动态绑定a元素的href属性
    • 比如动态绑定img元素的src属性
  • 这个时候,我们可以使用v-bind指令:

    • 作用:动态绑定属性
    • 缩写::
    • 预期:any (with argument) | Object (without argument)
    • 参数:attrOrProp (optional)

v-bind 基础

  • v-bind用于绑定一个或多个属性值,或者向另一个组件传递props值(这个学到组件时再介绍)

  • 在开发中,有哪些属性需要动态进行绑定呢?

    • 还是有很多的,比如图片的链接src、网站的链接href、动态绑定一些类、样式等等

    • 比如通过Vue实例中的data绑定元素的srchref,代码如下:

      <!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">
            <a href="link">百度</a>
            <a v-bind:href="link">百度</a>
            <img v-bind:src="avatar" width="100px" height="100px" />
            <img v-bind:src="avatar" v-bind:width="width" v-bind:height="height" />
          </div>
        </body>
        <script src="../vue.js"></script>
        <script>
          const app = new Vue({
            el: "#app",
            data: {
              link: "https://www.baidu.com/",
              avatar: "https://lmg.jj20.com/up/allimg/tp09/210Z614150050M-0-lp.jpg",
              width: "100px",
              height: "100px",
            },
          });
        </script>
      </html>
      

      在这里插入图片描述

v-bind 语法糖

  • v-bind有一个对应的语法糖,也就是简写方式

    • 在开发中,我们通常会使用语法糖的形式,因为这样更加简洁。
  • 简写方式如下:

    <!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">
          <a href="link">百度</a>
          <!-- v-bind 的语法糖 : -->
          <a :href="link">百度</a>
          <img :src="avatar" width="100px" height="100px" />
          <img :src="avatar" :width="width" :height="height" />
        </div>
      </body>
      <script src="../vue.js"></script>
      <script>
        const app = new Vue({
          el: "#app",
          data: {
            link: "https://www.baidu.com/",
            avatar: "https://lmg.jj20.com/up/allimg/tp09/210Z614150050M-0-lp.jpg",
            width: "100px",
            height: "100px",
          },
        });
      </script>
    </html>
    

v-bind 绑定 class(一)

  • 很多时候,我们希望动态的来切换class,比如:

    • 当数据为某个状态时,字体显示红色。
    • 当数据另一个状态时,字体显示黑色。
  • 绑定class有两种方式:

    • 对象语法
    • 数组语法

v-bind 绑定 class(二)

  • 绑定方式:对象语法

    • 对象语法的含义是:class后面跟的是一个对象。
  • 对象语法有下面这些用法:

    • 用法一:直接通过{}绑定一个类

      <!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>
          <style>
            .title {
              font-size: 18px;
              font-weight: 700;
            }
            .active {
              color: red;
            }
          </style>
        </head>
        <body>
          <div id="app">
            <h1 class="active">{{msg}}</h1>
            <h1 :class="{active:true}">{{msg}}</h1>
            <h1 class="title" :class="{active:false}">{{msg}}</h1>
            <h1 class="title" :class="{active:true}">{{msg}}</h1>
            <!-- 直接通过 {} 绑定一个类 也可以与普通 class 进行合并 -->
            <h1 class="title" :class="{active:isActive}">{{msg}}</h1>
          </div>
        </body>
        <script src="../vue.js"></script>
        <script>
          const app = new Vue({
            el: "#app",
            data: {
              msg: "Hello world",
              isActive: true,
            },
          });
        </script>
      </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>Document</title>
          <style>
            .title {
              font-size: 18px;
              font-weight: 700;
            }
            .active {
              color: red;
            }
            .line {
              text-decoration: underline;
            }
          </style>
        </head>
        <body>
          <div id="app">
            <!-- 用法二:也可以通过判断,代入多个值 -->
            <p :class="{active:isActive,line:isLine}">{{msg}}</p>
          </div>
        </body>
        <script src="../vue.js"></script>
        <script>
          const app = new Vue({
            el: "#app",
            data: {
              msg: "Hello world",
              isActive: true,
              isLine: true,
            },
          });
        </script>
      </html>
      

      在这里插入图片描述

    • 用法三:和普通的类同时存在,并不冲突

      • 注:如果isActiveisLine都为true,那么会有title/active/line三个类
      <!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>
          <style>
            .title {
              font-size: 18px;
              font-weight: 700;
            }
            .active {
              color: red;
            }
            .line {
              text-decoration: underline;
            }
          </style>
        </head>
        <body>
          <div id="app">
            <p class="title" :class="{active:isActive,line:isLine}">{{msg}}</p>
          </div>
        </body>
        <script src="../vue.js"></script>
        <script>
          const app = new Vue({
            el: "#app",
            data: {
              msg: "Hello world",
              isActive: true,
              isLine: true,
            },
          });
        </script>
      </html>
      

      在这里插入图片描述

    • 用法四:如果过于复杂,可以放在一个methods或者computed

      • 注:customClass2是一个计算属性
      <!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>
          <style>
            .title {
              font-size: 18px;
              font-weight: 700;
            }
            .active {
              color: red;
            }
            .line {
              text-decoration: underline;
            }
          </style>
        </head>
        <body>
          <div id="app">
            <!-- methods -->
            <p class="title" :class="customClass()">{{msg}}</p>
            <!-- computed -->
            <p class="title" :class="customClass2">{{msg}}</p>
          </div>
        </body>
        <script src="../vue.js"></script>
        <script>
          const app = new Vue({
            el: "#app",
            data: {
              msg: "Hello world",
              isActive: true,
              isLine: true,
            },
            computed: {
              customClass2() {
                return {
                  active: this.isActive,
                  line: this.isLine,
                };
              },
            },
            methods: {
              customClass() {
                return {
                  active: this.isActive,
                  line: this.isLine,
                };
              },
            },
          });
        </script>
      </html>
      

      在这里插入图片描述

v-bind 绑定 class(三)

  • 绑定方式:数组语法

    • 数组语法的含义是:class后面跟的是一个数组。
  • 数组语法有下面这些用法:

    • 用法一:直接通过[]定一个类

      <!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>
          <style>
            .title {
              font-size: 18px;
              font-weight: 700;
            }
          </style>
        </head>
        <body>
          <div id="app">
            <!-- 用法一:直接通过[]定一个类 -->
            <p :class="['title']">{{msg}}</p>
          </div>
        </body>
        <script src="../vue.js"></script>
        <script>
          const app = new Vue({
            el: "#app",
            data: {
              msg: "Hello world",
            },
          });
        </script>
      </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>Document</title>
          <style>
            .title {
              font-size: 18px;
              font-weight: 700;
            }
            .active {
              color: red;
            }
            .line {
              text-decoration: underline;
            }
          </style>
        </head>
        <body>
          <div id="app">
            <!-- 用法二:也可以传入多个值 -->
            <p :class="['title','active','line']">{{msg}}</p>
          </div>
        </body>
        <script src="../vue.js"></script>
        <script>
          const app = new Vue({
            el: "#app",
            data: {
              msg: "Hello world",
            },
          });
        </script>
      </html>
      

      在这里插入图片描述

    • 用法三:和普通的类同时存在,并不冲突

      • 注:会有title/active/line三个类
      <!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>
          <style>
            .title {
              font-size: 18px;
              font-weight: 700;
            }
            .active {
              color: red;
            }
            .line {
              text-decoration: underline;
            }
          </style>
        </head>
        <body>
          <div id="app">
            <!-- 和普通的类同时存在,并不冲突 -->
            <p class="title" :class="['active','line']">{{msg}}</p>
          </div>
        </body>
        <script src="../vue.js"></script>
        <script>
          const app = new Vue({
            el: "#app",
            data: {
              msg: "Hello world",
            },
          });
        </script>
      </html>
      
      

      在这里插入图片描述

    • 用法四:如果过于复杂,可以放在一个methods或者computed

      • 注:classes是一个计算属性
      <!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>
          <style>
            .title {
              font-size: 18px;
              font-weight: 700;
            }
            .active {
              color: red;
            }
            .line {
              text-decoration: underline;
            }
          </style>
        </head>
        <body>
          <div id="app">
            <!-- methods -->
            <p class="title" :class="customClass()">{{msg}}</p>
            <!-- computed -->
            <p class="title" :class="customClass2">{{msg}}</p>
          </div>
        </body>
        <script src="../vue.js"></script>
        <script>
          const app = new Vue({
            el: "#app",
            data: {
              msg: "Hello world",
              isActive: true,
              isLine: true,
            },
            computed: {
              customClass2() {
                return ["active", "line"];
              },
            },
            methods: {
              customClass() {
                return ["active", "line"];
              },
            },
          });
        </script>
      </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>Document</title>
          <style>
            .title {
              font-size: 18px;
              font-weight: 700;
            }
            .active {
              color: red;
            }
            .line {
              text-decoration: underline;
            }
          </style>
        </head>
        <body>
          <div id="app">
            <!-- 数组对象 -->
            <p class="title" :class="[{active:isActive},{line:isLine}]">{{msg}}</p>
          </div>
        </body>
        <script src="../vue.js"></script>
        <script>
          const app = new Vue({
            el: "#app",
            data: {
              msg: "Hello world",
              isActive: true,
              isLine: true,
            },
          });
        </script>
      </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>Document</title>
          <style>
            .active {
              color: red;
            }
          </style>
        </head>
        <body>
          <div id="app">
            <!-- 三元表达式 -->
            <p :class="[isActive?'active':'']">{{msg}}</p>
          </div>
        </body>
        <script src="../vue.js"></script>
        <script>
          const app = new Vue({
            el: "#app",
            data: {
              msg: "Hello world",
              isActive: true,
              isLine: true,
            },
          });
        </script>
      </html>
      

      在这里插入图片描述

v-bind 绑定 style(一)

  • 我们可以利用v-bind:style来绑定一些CSS内联样式。

  • 在写CSS属性名的时候,比如font-size

    • 我们可以使用驼峰式 (camelCase) fontSize
    • 或短横线分隔 (kebab-case,记得用单引号括起来) ‘font-size’
  • 绑定style有两种方式:

    • 对象语法
    • 数组语法

v-bind绑定style(二)

  • 绑定方式一:对象语法

    <!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">
          <p :style="{color:'red',fontSize:'30px'}">{{msg}}</p>
          <p :style="{color:'red','font-size':'30px'}">{{msg}}</p>
          <p :style="{color:isActive?'red':'blue',fontSize}">{{msg}}</p>
        </div>
      </body>
      <script src="../vue.js"></script>
      <script>
        const app = new Vue({
          el: "#app",
          data: {
            msg: "hello world",
            isActive: false,
            fontSize: "30px",
          },
        });
      </script>
    </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>Document</title>
      </head>
      <body>
        <div id="app">
          <p :style="[a]">{{msg}}</p>
        </div>
      </body>
      <script src="../vue.js"></script>
      <script>
        const app = new Vue({
          el: "#app",
          data: {
            msg: "hello world",
            a: {
              color: "red",
              fontSize: "30px",
            },
          },
        });
      </script>
    </html>
    

    在这里插入图片描述

什么是计算属性?

  • 我们知道,在模板中可以直接通过插值语法显示一些data中的数据。

  • 但是在某些情况,我们可能需要对数据进行一些转化后再显示,或者需要将多个数据结合起来进行显示

    • 比如我们有firstNamelastName两个变量,我们需要显示完整的名称。
    • 但是如果多个地方都需要显示完整的名称,我们就需要写多个{{firstName}} {{lastName}}
  • 我们可以将上面的代码换成计算属性:

    • OK,我们发现计算属性是写在实例的computed选项中的。
    <!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">
          <h1>{{firstName+lastName}}</h1>
          <h1>{{firstName}}{{lastName}}</h1>
          <!-- 计算属性:计算属性使用的时候不加() -->
          <h1>{{fulleName}}</h1>
        </div>
      </body>
      <script src="../vue.js"></script>
      <script>
        const app = new Vue({
          el: "#app",
          data: {
            firstName: "张",
            lastName: "三",
          },
          computed: {
            fulleName() {
              return this.firstName + this.lastName;
            },
          },
        });
      </script>
    </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>Document</title>
      </head>
      <body>
        <div id="app">
          <h1>所有图书的总价格:{{totalPrice}}</h1>
        </div>
      </body>
      <script src="../vue.js"></script>
      <script>
        const app = new Vue({
          el: "#app",
          data: {
            books: [
              { id: 1, title: "Vuejs开发", price: "70.8", num: 3 },
              { id: 2, title: "Nodejs", price: "65.5", num: 2 },
              { id: 3, title: "Java", price: "25.5", num: 6 },
              { id: 4, title: "JavaScript", price: "35", num: 9 },
            ],
          },
          computed: {
            totalPrice() {
              // let tPrice = 0;
              // for (const item of this.books) {
              //   tPrice += item.price * item.num;
              // }
              const tPrice = this.books.reduce((pre, item) => {
                return pre + item.price * item.num;
              }, 0);
              return tPrice;
            },
          },
        });
      </script>
    </html>
    

    在这里插入图片描述

计算属性的 setter 和 getter

  • 每个计算属性都包含一个getter和一个setter

    • 在上面的例子中,我们只是使用getter来读取。

    • 在某些情况下,你也可以提供一个setter方法(不常用)。

    • 在需要写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>Document</title>
        </head>
        <body>
          <div id="app">
            <h1>{{fullName}}</h1>
          </div>
        </body>
        <script src="../vue.js"></script>
        <script>
          const app = new Vue({
            el: "#app",
            data: {
              firstName: "张",
              lastName: "三",
            },
            computed: {
              fullName: {
                get() {
                  console.log("getter");
                  return this.firstName + this.lastName;
                },
                set(value) {
                  // console.log("setter");
                  // console.log(value);
                  const valueArray = value.split(" ");
                  this.firstName = valueArray[0];
                  this.lastName = valueArray[1];
                },
              },
            },
          });
        </script>
      </html>
      

      在这里插入图片描述

计算属性的缓存

  • 我们可能会考虑这样的一个问题:

    • methodscomputed看起来都可以实现我们的功能,
    • 那么为什么还要多一个计算属性这个东西呢?
    • 原因:计算属性会进行缓存,如果多次使用时,计算属性只会调用一次。
  • 我们来看下面的代码:

    <!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">
          计算属性:
          <h1>{{fullName}}</h1>
          <h1>{{fullName}}</h1>
          <h1>{{fullName}}</h1>
          <h1>{{fullName}}</h1>
          <h1>{{fullName}}</h1>
    
          方法:
          <h1>{{fullName2()}}</h1>
          <h1>{{fullName2()}}</h1>
          <h1>{{fullName2()}}</h1>
          <h1>{{fullName2()}}</h1>
          <h1>{{fullName2()}}</h1>
        </div>
      </body>
      <script src="../vue.js"></script>
      <script>
        const app = new Vue({
          el: "#app",
          data: {
            firstName: "张",
            lastName: "三",
          },
          computed: {
            fullName() {
              console.log("计算属性:fullName");
              return this.firstName + this.lastName;
            },
          },
          methods: {
            fullName2() {
              console.log("methods:fullName2");
              return this.firstName + this.lastName;
            },
          },
        });
      </script>
    </html>
    

    在这里插入图片描述

事件监听

  • 在前端开发中,我们需要经常和用于交互。

  • 这个时候,我们就必须监听用户发生的时间,比如点击、拖拽、键盘事件等等

  • Vue中如何监听事件呢?使用v-on指令

  • v-on介绍

    • 作用:绑定事件监听器
    • 缩写:@
    • 预期:Function | Inline Statement | Object
    • 参数:event
  • 下面,我们就具体来学习v-on的使用。

v-on 基础

  • 这里,我们用一个监听按钮的点击事件,来简单看看v-on的使用

    • 下面的代码中,我们使用了v-on:click="counter++”

    • 另外,我们可以将事件指向一个在methods中定义的函数

      <!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>
          <style>
            #app {
              text-align: center;
            }
            button {
              border: none;
              width: 100px;
              height: 35px;
            }
          </style>
        </head>
        <body>
          <div id="app">
            <h1>当前计数:{{counter}}</h1>
            <button v-on:click="increment">+</button>
            <button v-on:click="decrement">-</button>
          </div>
        </body>
        <script src="../vue.js"></script>
        <script>
          const app = new Vue({
            el: "#app",
            data: {
              counter: 0,
            },
            methods: {
              increment(event) {
                this.counter++;
              },
              decrement(event) {
                this.counter--;
              },
            },
          });
        </script>
      </html>
      

      在这里插入图片描述

  • 注:v-on也有对应的语法糖:

    • v-on:click可以写成@click

      <!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>
          <style>
            #app {
              text-align: center;
            }
            button {
              border: none;
              width: 100px;
              height: 35px;
            }
          </style>
        </head>
        <body>
          <div id="app">
            <h1>当前计数:{{counter}}</h1>
            <button @click="increment">+</button>
            <button @click="decrement">-</button>
          </div>
        </body>
        <script src="../vue.js"></script>
        <script>
          const app = new Vue({
            el: "#app",
            data: {
              counter: 0,
            },
            methods: {
              increment(event) {
                this.counter++;
              },
              decrement(event) {
                this.counter--;
              },
            },
          });
        </script>
      </html>
      

v-on 参数

  • 当通过methods中定义方法,以供@click调用时,需要注意参数问题

  • 情况一:如果该方法不需要额外参数,那么方法后的()可以不添加。

    • 但是注意:如果方法本身中有一个参数,那么会默认将原生事件event参数传递进去

      <!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">
            <!-- 当没有传参数 默认会将事件对象传入 -->
            <button @click="btnClick">按钮1</button>
            <button @click="btnClick2(10,'hello')">按钮2</button>
          </div>
        </body>
        <script src="../vue.js"></script>
        <script>
          const app = new Vue({
            el: "#app",
            methods: {
              btnClick(event) {
                console.log(event);
              },
              btnClick2(a, b) {
                console.log(a, b);
              },
            },
          });
        </script>
      </html>
      

      在这里插入图片描述

  • 情况二:如果需要同时传入某个参数,同时需要event时,可以通过$event传入事件。

    <!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">
          <!-- 传入其他参数的时候,还想使用事件对象,就将$event传入 -->
          <button @click="btnClick3(10,'hello',$event)">按钮3</button>
        </div>
      </body>
      <script src="../vue.js"></script>
      <script>
        const app = new Vue({
          el: "#app",
          methods: {
            btnClick3(a, b, event) {
              console.log(a, b, event);
            },
          },
        });
      </script>
    </html>
    
    

    在这里插入图片描述

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>Document</title>
    <style>
      .box {
        width: 50px;
        height: 50px;
        background: pink;
      }
    </style>
  </head>
  <body>
    <div id="app">
      <input type="text" @input="handleInput" />
      <div class="box" @mouseover="handleMouseover"></div>
    </div>
  </body>
  <script src="../vue.js"></script>
  <script>
    const app = new Vue({
      el: "#app",
      methods: {
        handleInput() {
          console.log("handleInput");
        },
        handleMouseover() {
          console.log("handleMouseover");
        },
      },
    });
  </script>
</html>

在这里插入图片描述

v-on 修饰符

  • 在某些情况下,我们拿到event的目的可能是进行一些事件处理。

  • Vue提供了修饰符来帮助我们方便的处理一些事件:

    • .stop - 调用event.stopPropagation()

      <!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">
            <!-- shop 阻止事件的冒泡 -->
            <div
              style="width: 150px; height: 150px; background: red"
              @click="redClick"
            >
              <div
                style="width: 100px; height: 100px; background: black"
                @click.stop="blackClick"
              >
                <div
                  style="width: 50px; height: 50px; background: pink"
                  @click="pinkClick"
                ></div>
              </div>
            </div>
          </div>
        </body>
        <script src="../vue.js"></script>
        <script>
          const app = new Vue({
            el: "#app",
            data: {},
            methods: {
              redClick() {
                console.log("redClick");
              },
              blackClick() {
                console.log("blackClick");
              },
              pinkClick(event) {
                console.log("pinkClick");
                event.stopPropagation();
              },
            },
          });
        </script>
      </html>
      

      在这里插入图片描述

    • .prevent - 调用event.preventDefault()

      <!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">
            <!-- .prevent  阻止默认行为 -->
            <form action="http://www.baidu.com" @submit.prevent="handleSubmit">
              <input type="submit" />
            </form>
            <!-- preventDefault() 阻止默认行为  -->
            <form action="http://www.baidu.com" @submit="handleSubmit2">
              <input type="submit" />
            </form>
          </div>
        </body>
        <script src="../vue.js"></script>
        <script>
          const app = new Vue({
            el: "#app",
            methods: {
              handleSubmit() {
                console.log("提交");
              },
              handleSubmit2(event) {
                console.log("提交2");
                event.preventDefault();
              },
            },
          });
        </script>
      </html>
      

      在这里插入图片描述

    • .{keyCode | keyAlias} - 只当事件是从特定键触发时才触发回调。

      <!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">
            <input type="text" @keyup.13="handleKeyup" />
            <input type="text" @keyup.enter="handleKeyup" />
          </div>
        </body>
        <script src="../vue.js"></script>
        <script>
          const app = new Vue({
            el: "#app",
            data: {},
            methods: {
              handleKeyup() {
                console.log("handleKeyup");
              },
            },
          });
        </script>
      </html>
      

      在这里插入图片描述

    • .native - 监听组件根元素的原生事件。

    • .once - 只触发一次回调。

      <!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">
            <button @click.once="redClick">按钮</button>
          </div>
        </body>
        <script src="../vue.js"></script>
        <script>
          const app = new Vue({
            el: "#app",
            data: {},
            methods: {
              redClick() {
                console.log("redClick");
              },
            },
          });
        </script>
      </html>
      

      在这里插入图片描述

v-if、v-else-if、v-else

  • v-ifv-else-ifv-else

    • 这三个指令与JavaScript的条件语句ifelseelse if类似。
    • Vue的条件指令可以根据表达式的值在DOM中渲染或销毁元素或组件
  • 简单的案例演示:

    <!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">
          <p v-if="score>=90">优秀</p>
          <p v-else-if="score>=70">良好</p>
          <p v-else-if="score>=60">及格</p>
          <p v-else>不及格</p>
        </div>
      </body>
      <script src="../vue.js"></script>
      <script>
        const app = new Vue({
          el: "#app",
          data: {
            score: 98,
          },
        });
      </script>
    </html>
    

    在这里插入图片描述

  • v-if的原理:

    • v-if后面的条件为false时,对应的元素以及其子元素不会渲染。
    • 也就是根本没有不会有对应的标签出现在DOM中。

条件渲染案例

  • 我们来做一个简单的小案例:

    • 用户再登录时,可以切换使用用户账号登录还是邮箱地址登录。

    • 类似如下情景:

      在这里插入图片描述

    • 案例小问题

      • 小问题:
        • 如果我们在有输入内容的情况下,切换了类型,我们会发现文字依然显示之前的输入的内容。
        • 但是按道理讲,我们应该切换到另外一个input元素中了。
        • 在另一个input元素中,我们并没有输入内容。
        • 为什么会出现这个问题呢?
      • 问题解答:
        • 这是因为Vue在进行DOM渲染时,出于性能考虑,会尽可能的复用已经存在的元素,而不是重新创建新的元素。
        • 在上面的案例中,Vue内部会发现原来的input元素不再使用,直接作为else中的input来使用了。
      • 解决方案:
        • 如果我们不希望Vue出现类似重复利用的问题,可以给对应的input添加key
        • 并且我们需要保证key的不同
    • 代码展示

      <!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">
            <label for="" v-if="type == 'username'">
              用户账号:
              <input type="text" placeholder="用户账号" key="username" />
              <button @click="handleChange">切换类型</button>
            </label>
            <label for="" v-else>
              邮箱地址:
              <input type="text" placeholder="邮箱地址" key="email" />
              <button @click="handleChange">切换类型</button>
            </label>
          </div>
        </body>
        <script src="../vue.js"></script>
        <script>
          const app = new Vue({
            el: "#app",
            data: {
              type: "username",
            },
            methods: {
              handleChange() {
                this.type = this.type == "username" ? "email" : "username";
              },
            },
          });
        </script>
      </html>
      

v-show

  • v-show的用法和v-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>Document</title>
      </head>
      <body>
        <div id="app">
          <h1 v-show="isShow">hello</h1>
          <button @click="toggleHide">切换显示</button>
          <!-- if 和 v-show 的区别 -->
          <!-- 1. v-if 切换重新创建或者销毁元素或者组件
             v-show 设置display属性
          2. v-if 性能消耗大
             v-show 性能消耗小
          3. 当切换频率高的时候,使用v-show
             当切换频率低的时候,使用v-if -->
        </div>
      </body>
      <script src="../vue.js"></script>
      <script>
        const app = new Vue({
          el: "#app",
          data: {
            isShow: true,
          },
          methods: {
            toggleHide() {
              this.isShow = !this.isShow;
            },
          },
        });
      </script>
    </html>
    

    在这里插入图片描述

  • v-ifv-show对比

  • v-ifv-show都可以决定一个元素是否渲染,那么开发中我们如何选择呢?

    • v-if当条件为false时,压根不会有对应的元素在DOM中。

    • v-show当条件为false时,仅仅是将元素的display属性设置为none而已。

      在这里插入图片描述

  • 开发中如何选择呢?

    • 当需要在显示与隐藏之间切片很频繁时,使用v-show
    • 当只有一次切换时,通过使用v-if

v-for 遍历数组

  • 当我们有一组数据需要进行渲染时,我们就可以使用v-for来完成。

    • v-for的语法类似于JavaScript中的for循环。
    • 格式如下:item in items的形式。
  • 我们来看一个简单的案例:

    <!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">
          <ul>
            <li v-for="(item,index) in movies">{{index}}.{{item}}</li>
          </ul>
        </div>
      </body>
      <script src="../vue.js"></script>
      <script>
        const app = new Vue({
          el: "#app",
          data: {
            movies: ["盗梦空间", "西游记", "三国演义", "红楼梦"],
          },
        });
      </script>
    </html>
    

    在这里插入图片描述

  • 如果在遍历的过程中不需要使用索引值

    • v-for="item in movies"
    • 依次从movies中取出item,并且在元素的内容中,我们可以使用Mustache语法,来使用item
  • 如果在遍历的过程中,我们需要拿到元素在数组中的索引值呢?

    • 语法格式:v-for=(item, index) in items
    • 其中的index就代表了取出的item在原数组的索引值。

v-for 遍历对象

  • v-for可以用户遍历对象:

  • 比如某个对象中存储着你的个人信息,我们希望以列表的形式显示出来。

    <!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">
          <p v-for="(value,key,index) in person">{{index}}-{{key}}-{{value}}</p>
        </div>
      </body>
      <script src="../vue.js"></script>
      <script>
        const app = new Vue({
          el: "#app",
          data: {
            person: {
              name: "张三",
              age: 18,
              height: 188,
            },
          },
        });
      </script>
    </html>
    

    在这里插入图片描述

检测数组更新

  • 因为Vue是响应式的,所以当数据发生变化时,Vue会自动检测数据变化,视图会发生对应的更新。

  • Vue中包含了一组观察数组编译的方法,使用它们改变数组也会触发视图的更新。

    • push()
    • pop()
    • shift()
    • unshift()
    • splice()
    • sort()
    • reverse()
  • 代码案例展示

    <!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">
          <h1>{{names}}</h1>
          <h1>{{abc}}</h1>
          <button @click="handleEditClick">更新数组</button>
        </div>
      </body>
      <script src="../vue.js"></script>
      <script>
        const app = new Vue({
          el: "#app",
          data: {
            names: ["张三", "李四"],
            abc: [1, 11, 23, 10, 8, 3, 9],
          },
          methods: {
            handleEditClick() {
              // 添加元素
              // this.names.push("王五", "赵六");
    
              // 删除最后一个
              // this.names.pop();
    
              // 删除第一个元素
              // this.names.shift();
    
              // 在数组的首位添加一个元素
              // this.names.unshift("小刘")
    
              // 删除
              this.names.splice(1, 1);
              // 插入
              this.names.splice(1, 0, "赵六");
              // 替换
              this.names.splice(1, 1, "马奇");
    
              // 排序
              this.abc.sort((a, b) => a - b);
    
              // 数组反转
              this.abc.reverse();
            },
          },
        });
      </script>
    </html>
    

数组的注意事项(Vue.set)

  • <!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">
          <h1>{{names}}</h1>
          <h1>{{obj}}</h1>
          <button @click="handleEditClick">更新数组</button>
          <button @click="handleEditAgeClick">更新年龄</button>
        </div>
      </body>
      <script src="../vue.js"></script>
      <script>
        const app = new Vue({
          el: "#app",
          data: {
            names: ["张三", "李四"],
            obj: {},
          },
          methods: {
            handleEditClick() {
              // 这个操作是不行的
              // this.names[1] = "王五";
              // 数据发了改变但是页面没有发生改变 说明数据没有实现双向绑定
              // console.log(this.names); // ['张三', '王五', __ob__: Observer]
    
              // 数组: Vue.set(数组, 下标, value)
              Vue.set(this.names, 1, "王五");
    
              // this.obj.age = 19 这种方式添加的属性是不具备双向绑定能力的
              // 对象: Vue.set(对象, key, value);
              Vue.set(this.obj, "age", 19);
            },
            // 更改对象中的属性
            handleEditAgeClick() {
              this.obj.age = 100;
            },
          },
        });
      </script>
    </html>
    

过滤器-filters

  • Vue.js允许你自定义过滤器,可被用于一些常见的文本格式化。过滤器可以用在两个地方:双花括号插值和v-bind表达式 (后者从2.1.0+开始支持)。过滤器应该被添加在JavaScript表达式的尾部,由“管道”(|)符号指示:

    • v-bind中使用

      <!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>
          <link
            rel="stylesheet"
            href="https://at.alicdn.com/t/c/font_3464777_0ncyua7qfzac.css"
          />
        </head>
        <body>
          <div id="app">
            <h1 :class="'xiezi'| fontIcon"></h1>
            <h1 :class="'dianpu'| fontIcon"></h1>
          </div>
        </body>
        <script src="../vue.js"></script>
        <script>
          const app = new Vue({
            el: "#app",
            data: {},
            filters: {
              fontIcon(icon) {
                console.log(icon);
                return "iconfont icon-" + icon;
              },
            },
          });
        </script>
      </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>Document</title>
        </head>
        <body>
          <div id="app">
            <h1>{{80|showPrice}}</h1>
          </div>
        </body>
        <script src="../vue.js"></script>
        <script>
          const app = new Vue({
            el: "#app",
            data: {},
            filters: {
              showPrice(price) {
                return "¥" + price.toFixed(2);
              },
            },
          });
        </script>
      </html>
      

      在这里插入图片描述

过滤器-参数问题

  • 过滤器函数总接收表达式的值 (之前的操作链的结果) 作为第一个参数。在上述例子中,showPrice过滤器函数将会收到message的值作为第一个参数

  • 过滤器是JavaScript函数,因此可以接收参数:

  • 这里,showPrice被定义为接收三个参数的过滤器函数。其中80的值作为第一个参数,普通字符串10作为第二个参数,表达式admin的值作为第三个参数

    <!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">
          <p>{{80|showPrice(10,'admin')}}</p>
        </div>
      </body>
      <script src="../vue.js"></script>
      <script>
        const app = new Vue({
          el: "#app",
          data: {},
          filters: {
            showPrice(price, a, b) {
              console.log(price, a, b);
              return price;
            },
          },
        });
      </script>
    </html>
    

    在这里插入图片描述

串联-过滤器

  • 过滤器可以串联:

  • 在这个例子中,filterA被定义为接收单个参数的过滤器函数,表达式message的值将作为参数传入到函数中。然后继续调用同样被定义为接收单个参数的过滤器函数filterB,将filterA的结果传递到filterB中。

    <!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">
          <p>{{80|filterA|filterB}}</p>
        </div>
      </body>
      <script src="../vue.js"></script>
      <script>
        const app = new Vue({
          el: "#app",
          data: {},
          filters: {
            filterA(a) {
              return a + 10;
            },
            filterB(b) {
              return b + 10;
            },
          },
        });
      </script>
    </html>
    

    在这里插入图片描述

表单绑定 v-model

  • 表单控件在实际开发中是非常常见的。特别是对于用户信息的提交,需要大量的表单。

  • Vue中使用v-model指令来实现表单元素和数据的双向绑定。

  • 案例的解析:

  • 当我们在输入框输入内容时

  • 因为input中的v-model绑定了message,所以会实时将输入的内容传递给messagemessage发生改变。

  • message发生改变时,因为上面我们使用Mustache语法,将message的值插入到DOM中,所以DOM会发生响应的改变。

  • 所以,通过v-model实现了双向的绑定。

  • 当然,我们也可以将v-model用于textarea元素

    <!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">
          <input type="text" v-model="message" />
          <textarea v-model="message"></textarea>
          <h1>{{ message }}</h1>
        </div>
      </body>
      <script src="../vue.js"></script>
      <script>
        const app = new Vue({
          el: "#app",
          data: {
            message: "Hello World",
          },
        });
      </script>
    </html>
    

    在这里插入图片描述

v-model 原理

  • v-model其实是一个语法糖,它的背后本质上是包含两个操作:

    • 1.v-bind绑定一个value属性
    • 2.v-on指令给当前元素绑定input事件
  • 也就是说下面的代码:等同于下面的代码:

    <!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">
          <input type="text" v-model="message" />
          <input type="text" :value="message" @input="handleModel" />
          <input
            type="radio"
            value=""
            :checked="gander==''"
            @change="handelChange"
          />
          <input
            type="radio"
            value=""
            :checked="gander==''"
            @change="handelChange"
          />
          <h1>{{ message }}</h1>
        </div>
      </body>
      <script src="../vue.js"></script>
      <script>
        const app = new Vue({
          el: "#app",
          data: {
            message: "Hello World",
            gander: "男",
          },
          methods: {
            handleModel(event) {
              this.message = event.target.value;
            },
            handelChange(event) {
              this.gander = event.target.value;
            },
          },
        });
      </script>
    </html>
    

    在这里插入图片描述

v-model:radio

  • 当存在多个单选框时

    <!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">
          <!-- 多个单选框 -->
          <label for="">
            唱:<input type="radio" value="" v-model="like" />
          </label>
          <label for="">
            跳:<input type="radio" value="" v-model="like" />
          </label>
          <label for="">
            rap:<input type="radio" value="rap" v-model="like" />
          </label>
          <label for="">
            篮球:<input type="radio" value="篮球" v-model="like" />
          </label>
          <p>{{like}}</p>
          <label for="">
            男:<input type="radio" value="" v-model="gander" />
          </label>
          <label for="">
            女:<input type="radio" value="" v-model="gander" />
          </label>
          <p>{{gander}}</p>
        </div>
      </body>
      <script src="../vue.js"></script>
      <script>
        const app = new Vue({
          el: "#app",
          data: {
            like: "",
            gander: "",
          },
        });
      </script>
    </html>
    

    在这里插入图片描述

v-model:checkbox

  • 复选框分为两种情况:单个勾选框和多个勾选框

  • 单个勾选框:

    • v-model即为布尔值。

    • 此时inputvalue并不影响v-model的值。

      <!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">
            <!-- 单个复选框 复选框单选 -->
            <label for="">
              <input type="checkbox" v-model="checked" />
            </label>
            <p>{{checked}}</p>
          </div>
        </body>
        <script src="../vue.js"></script>
        <script>
          const app = new Vue({
            el: "#app",
            data: {
              checked: false,
            },
          });
        </script>
      </html>
      

      在这里插入图片描述

  • 多个复选框:

    • 当是多个复选框时,因为可以选中多个,所以对应的data中属性是一个数组。

    • 当选中某一个时,就会将inputvalue添加到数组中。

      <!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">
            <!-- 复选框多选 -->
            <label for="">
              吃饭:<input type="checkbox" value="吃饭" v-model="like" />
            </label>
            <label for="">
              睡觉:<input type="checkbox" value="睡觉" v-model="like" />
            </label>
            <label for="">
              写代码:<input type="checkbox" value="写代码" v-model="like" />
            </label>
            <p>{{like}}</p>
          </div>
        </body>
        <script src="../vue.js"></script>
        <script>
          const app = new Vue({
            el: "#app",
            data: {
              like: [],
            },
          });
        </script>
      </html>
      

      在这里插入图片描述

v-model:select

  • checkbox一样,select也分单选和多选两种情况。

  • 单选:只能选中一个值。

    • v-model绑定的是一个值。

    • 当我们选中option中的一个时,会将它对应的value赋值到mySelect

      <!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>
          <style>
            select {
              width: 100%;
              border: 1px solid aqua;
              outline: 1px solid aqua;
            }
          </style>
        </head>
        <body>
          <div id="app">
            <select v-model="city">
              <option value="西安">西安</option>
              <option value="宝鸡">宝鸡</option>
              <option value="咸阳">咸阳</option>
            </select>
            <p>{{city}}</p>
          </div>
        </body>
        <script src="../vue.js"></script>
        <script>
          const app = new Vue({
            el: "#app",
            data: {
              city: "",
            },
          });
        </script>
      </html>
      

      在这里插入图片描述

修饰符

  • lazy修饰符:

    • 默认情况下,v-model默认是在input事件中同步输入框的数据的。

    • 也就是说,一旦有数据发生改变对应的data中的数据就会自动发生改变。

    • lazy修饰符可以让数据在失去焦点或者回车时才会更新:

      <!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">
            <input type="text" v-model.lazy="message" />
            <p>{{message}}</p>
          </div>
        </body>
        <script src="../vue.js"></script>
        <script>
          const app = new Vue({
            el: "#app",
            data: {
              message: "消息",
            },
          });
        </script>
      </html>
      

      在这里插入图片描述

  • number修饰符:

    • 默认情况下,在输入框中无论我们输入的是字母还是数字,都会被当做字符串类型进行处理。

    • 但是如果我们希望处理的是数字类型,那么最好直接将内容当做数字处理。

    • number修饰符可以让在输入框中输入的内容自动转成数字类型:

      <!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">
            <input type="text" v-model.number="counter" />
            <p>{{typeof counter}}</p>
          </div>
        </body>
        <script src="../vue.js"></script>
        <script>
          const app = new Vue({
            el: "#app",
            data: {
              counter: 0,
            },
          });
        </script>
      </html>
      

      在这里插入图片描述

  • trim修饰符:

    • 如果输入的内容首尾有很多空格,通常我们希望将其去除

    • trim修饰符可以过滤内容左右两边的空格

      <!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">
            <input type="text" v-model.trim="message" />
            <p>{{ message.length }}</p>
          </div>
        </body>
        <script src="../vue.js"></script>
        <script>
          const app = new Vue({
            el: "#app",
            data: {
              message: "消息",
            },
          });
        </script>
      </html>
      

      在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值