zoukankan      html  css  js  c++  java
  • 3-vue基础语法2

    一、计算属性

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

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

        比如我们有firstName和lastName两个变量,我们需要显示完整的名称。

        但是如果多个地方都需要显示完整的名称,我们就需要写多个{{firstName}} {{lastName}}


    我们可以将上面的代码换成计算属性:

        OK,我们发现计算属性是写在实例的computed选项中的。


    1、基本使用

    <body>
    <div id="app">
      <h2>{{firstName + ' ' + lastName}}</h2>
      <h2>{{firstName}} {{lastName}}</h2>
      <h2>{{fullName}}</h2>  //使用计算属性
    </div>
    
    <script src="../js/vue.js"></script>
    <script>
     const app = new Vue({
       el: '#app',
       data: {
         firstName: 'LeBron',
         lastName: 'James'
       },
       computed: {  //计算属性
         fullName: function () {
           return this.firstName + ' ' + this.lastName
         }
       }
     })
    </script>
    </body>


    2、计算属性的复杂操作

    计算图书的总价:

    <body>
    <div id="app">
      <h2>图书总价: {{totalPrice}}</h2>
    </div>
    
    <script src="../js/vue.js"></script>
    <script>
      const app = new Vue({
        el: '#app',
        data: {
          books: [
            {id: '01', name: 'book1', price: 39},
            {id: '01', name: 'book2', price: 49},
            {id: '01', name: 'book3', price: 59}
          ]
        },
        computed: {
          totalPrice: function () {
            let result = 0
            for (let i in this.books) {
              result += this.books[i].price
            }
            return result
          },
        }
      })
    </script>
    </body>


    计算属性的 setter 和 getter:

    每个计算属性都包含一个 getter 和一个 setter,getter 用来读取值,setter 用来设置值(但 setter 不常用);

    <body>
    <div id="app">
      <h2>{{fullName}}</h2>
    </div>
    
    <script src="../js/vue.js"></script>
    <script>
      const app = new Vue({
        el: '#app',
        data: {
          firstName: 'jieLun',
          lastName: 'zhou'
        },
        computed: {
          fullName: {
            set: function (newValue) {
              let newName = newValue.split(' ')
              this.firstName = newName[0]
              this.lastName = newName[1]
            },
            get: function () {
              return this.firstName + '.' + this.lastName
            }
          }
        }
      })
    </script>
    </body>


    3、couputed 与 methods 的区别

    methods 和 computed 看起来都可以实现我们的功能,那么为什么还要多一个计算属性这个东西呢?

    原因:计算属性会进行缓存,如果多次使用时,计算属性只会调用一次


    computed 区别于 methods 的核心:

    在官方文档中,强调了computed 区别于 methods 最重要的两点

    1. computed 是属性调用,而 methods 是函数调用
    2. computed 带有缓存功能,而 methods 没有
    • computed 定义的方法,我们是以属性访问的形式调用的,{{computedTest}},但是 methods 定义的方法,我们必须要加上()来调用,如{{methodTest()}}
    • 我们可以将同一函数定义为一个方法而不是一个计算属性,两种方式的最终结果确实是完全相同的然而,不同的是计算属性是基于它们的响应式依赖进行缓存的,

                只在相关响应式依赖发生改变时它们才会重新求值,这就意味着只要 text 还没有发生改变,多次访问 getText 计算属性会立即返回之前的计算结果,而不必再次执行函数,

                而方法只要页面中的属性发生改变就会重新执行 ;

    • 对于任何复杂逻辑,都应当使用计算属性
    • computed 依赖于 data 中的数据,只有在它的相关依赖数据发生改变时才会重新求值


    二、ES6补充

    1、let/var

    事实上var的设计可以看成JavaScript语言设计上的错误. 但是这种错误多半不能修复和移除, 以为需要向后兼容.

         大概十年前, Brendan Eich就决定修复这个问题, 于是他添加了一个新的关键字: let.

         我们可以将let看成更完美的var

    块级作用域

         JS中使用var来声明一个变量时, 变量的作用域主要是和函数的定义有关.

         针对于其他块定义来说是没有作用域的,比如if/for等,这在我们开发中往往会引起一些问题。

    image

    image


    2、const

    const关键字

         在很多语言中已经存在, 比如C/C++中, 主要的作用是将某个变量修饰为常量.

         在JavaScript中也是如此, 使用const修饰的标识符为常量, 不可以再次赋值.


    什么时候使用const呢?

          当我们修饰的标识符不会被再次赋值时, 就可以使用const来保证数据的安全性.

    建议: 在ES6开发中,优先使用const, 只有需要改变某一个标识符的时候才使用let.


    const的注意

    const注意一:

    image

    const注意二:

    image


    3、对象增强操作

    ES6中,对对象字面量进行了很多增强。

    属性初始化简写和方法的简写:

    image     image


    三、事件监听

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

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

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


    v-on介绍:

         作用:绑定事件监听器

        缩写:@

        预期:Function | Inline Statement | Object

        参数:event


    1、计数器案例

    <body>
    <div id="app">
      <h2>{{counter}}</h2>
      <button v-on:click="increment()">+</button>
      <!--语法糖 v-on:click可写成@click-->
      <button @click="decrement()">-</button>
    </div>
    
    <script src="../js/vue.js"></script>
    <script>
      const app = new Vue({
        el: '#app',
        data: {
          counter: 0
        },
        methods: {
          increment() {
            this.counter++
          },
          decrement() {
            this.counter--
          }
        }
      })
    </script>
    </body>


    2、v-on参数

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

    • 如果该方法不需要额外参数,那么方法后的 () 可以不添加,但如果方法本身中有一个参数,那么会默认将原生事件 event 参数传递进去
    • 如果需要同时传入某个参数,同时需要 event 时,可以通过 $event 传入事件


    <body>
    <div id="app">
      <h2>{{counter}}</h2>
    <!--  <button @click="btnClick">按钮1</button>-->
      <button @click="btnClick($event, 10)">按钮1</button>
    </div>
    
    <script src="../js/vue.js"></script>
    <script>
     const app = new Vue({
       el: '#app',
       data: {
         counter: 0
       },
       methods: {
         btnClick(event, num) {
           console.log(event, num);
           this.counter += 10;
         }
       }
     })
    </script>
    </body>


    3、v-on修饰符

    在某些情况下,我们拿到 event 的目的可能是进行一些事件处理,vue 提供了修饰符来帮助我们方便的处理一些事件:

    • .stop :调用 event.stopPropagation()
    • .prevent :调用 event.preventDefault()
    • .{keyCode | keyAlias} :只当事件是从特定键触发时才触发回调
    • .native :监听组件根元素的原生事件
    • .once :只触发一次回调


    <body>
    <div class="app">
      <!-- 1 .stop:停止冒泡 -->
      <div @click="divClick">divdiv
        <button @click.stop="btnClick">按钮</button>
      </div>
    
      <!-- 2. .prevent:阻止默认行为 -->
      <form action="baidu" method="post">
        <input type="submit" value="提交" @click.prevent="submitClick">
      </form>
    
      <!-- 3. .enter:监听enter按键 -->
      <input type="text" @keyup.enter="enterClick">
    
      <!-- 4. .once:点击回调只会触发一次 -->
      <button @click.once="btnClick2">按钮2</button>
    
    </div>
    <script src="../js/vue.js"></script>
    <script>
      const app = new Vue({
        el: '.app',
        data: {
          counter: 0
        },
        methods: {
          btnClick() {
            console.log("btnClick...")
          },
          divClick() {
            console.log("divClick...")
          },
          submitClick() {
            console.log("submitClick...")
          },
          enterClick() {
            console.log("enterClick...")
          },
          btnClick2() {
            console.log("btnClick2...")
          }
        }
      })
    </script>
    </body>


    四、条件判断

    1、

    v-if、v-else-if、v-else 这三个指令与 JavaScript 的条件语句 if、else、else if 类似;

    vue 的条件指令可以根据表达式的值在 DOM 中渲染或销毁元素或组件;


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

    <body>
    <div id="app">
      <p v-if="score >= 90">优秀</p>
      <p v-else-if="score >= 75">良好</p>
      <p v-else-if="score >= 60">及格</p>
      <p v-else="score >=80">不及格</p>
    </div>
    
    <script src="../js/vue.js"></script>
    <script>
      const app = new Vue({
        el: '#app',
        data: {
          score: 98
        }
      })
    </script>
    </body>


    切换用户账号案例:

    <body>
    <div class="app">
      <span v-if="isUser">
        <label for="username">用户账号</label>
        <input type="text" id="username" placeholder="用户账号" key="username">
      </span>
      <span v-else>
        <label for="email">用户邮箱</label>
        <input type="text" id="email" placeholder="用户邮箱" key="email">
      </span>
      <button @click="isUser = !isUser">切换类型</button>
    </div>
    <script src="../js/vue.js"></script>
    <script>
      const app = new Vue({
        el: '.app',
        data: {
          isUser: true
        }
      })
    </script>
    </body>


    2、v-show

    v-show 的用法和 v-if 非常相似,也用于决定一个元素是否渲染;

    v-show 和 v-if 的区别:

    • v-if 是真正的条件渲染,会确保在切换过程中,条件块内的事件和子组件被销毁和重建(组件被重建将会调用created) ;
    • -show 不论如何,都会被渲染在 DOM 中,当条件为真值时,将会修改条件的 css 样式;
    • v-if 有更高的切换开销,v-show 有更高的初始渲染开销 ;
    • -if 是动态的向 DOM 树内添加或者删除 DOM 元素,v-show 是通过设置 DOM 元素的 display 样式属性控制显隐 ;
    • -if 切换有一个局部编译/卸载的过程,切换过程中合适地销毁和重建内部的事件监听和子组件,v-show 只是简单的基于 css 切换 ;
    • -if 是惰性的,如果初始条件为假,则什么也不做,只有在条件第一次变为真时才开始局部编译,v-show 是在任何条件下(首次条件是否为真)都被编译,

                然后被缓存,而且 DOM 元素保留 ;

    • v-if 有更高的切换消耗,v-show 有更高的初始渲染消耗 ;
    • -if 适合运营条件不大可能改变,v-show适合频繁切换;

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


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

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


    结论:

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


    五、循环遍历

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

    v-for 的语法类似于 JavaScript 中的 for 循环:item in items

    1、遍历数组

    <body>
    <div id="app">
      <ul>
        <!--遍历数组的值-->
        <li v-for="i in books">{{i}}</li>
        <!--遍历数组的索引和值-->
        <li v-for="(i, index) in books">{{index}}.{{i}}</li>
      </ul>
    </div>
    
    <script src="../js/vue.js"></script>
    <script>
      const app = new Vue({
        el: '#app',
        data: {
          books: ['book1', 'book2', 'book3']
        }
      })
    </script>
    </body>


    2、遍历对象

    <body>
    <div id="app">
      <ul>
        <li v-for="i in info">{{i}}</li>
        <hr>
        <li v-for="(i, key) in info">{{key}}:{{i}}</li>
        <hr>
        <li v-for="(i, key, index) in info">{{index}}.{{key}}:{{i}}</li>
      </ul>
    
    </div>
    
    <script src="../js/vue.js"></script>
    <script>
      const app = new Vue({
        el: '#app',
        data: {
          info: {
            name: 'Jay',
            age: 18,
            gender: ''
          }
        }
      })
    </script>
    </body>


    3、组件的key属性

    官方推荐我们在使用 v-for 时,给对应的元素或组件添加上一个 :key 属性

    为什么需要这个 key 属性呢,其实和 Vue 的虚拟 DOM 的 Diff 算法有关系,这里借用 React’s diff algorithm 中的一张图来简单说明一下:

    图片.png

    当某一层有很多相同的节点时,也就是列表节点时,我们希望插入一个新的节点

    图片.png

    我们希望可以在 B 和 C 之间加一个 F,Diff 算法默认执行起来是这样的:

    即把 C 更新成 F,D 更新成 C,E 更新成 D,最后再插入 E:

    图片.png

    是不是很没有效率?

    所以我们需要使用 key 来给每个节点做一个唯一标识,Diff 算法就可以正确的识别此节点,找到正确的位置区插入新的节点,所以,key 的作用主要是为了高效的更新虚拟 DOM

    图片.png

    图片.png

    <li v-for="item in info" :key="item">{{item}}</li>


    4、检测数组更新

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

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

    push()

    pop()

    shift()

    unshift()

    splice()

    sort()

    reverse()


    image


    六、案例

    案例1:

    默认第一项是红色,然后选中哪一个哪一个就变红;

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>Title</title>
      <style>
        .active {
          color: #ff1c24;
        }
      </style>
    </head>
    <body>
    <div id="app">
      <ul>
        <li v-for="(item, index) in movies"
            :class="{active: currentIndex === index}"
            @click="liClick(index)">
          {{index}}.{{item}}
        </li>
      </ul>
    </div>
    
    <script src="../js/vue.js"></script>
    <script>
      const app = new Vue({
        el: '#app',
        data: {
          movies: ['海王', '海贼王', '海尔兄弟'],
          currentIndex: 0
        },
        methods: {
          liClick(index) {
            this.currentIndex = index
          }
        }
      })
    </script>
    </body>
    </html>


    案例2:

    图书购物车

    HTML

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>Title</title>
      <link rel="stylesheet" href="style.css">
    </head>
    <body>
    
    <div id="app">
      <!--加一层div作判断,当购物车为空时,显示“购物车为空”-->
      <div v-if="books.length">
        <table>
          <thead>
          <tr>
            <th>ID</th>
            <th>书籍名称</th>
            <th>出版日期</th>
            <th>价格</th>
            <th>购买数量</th>
            <th>操作</th>
          </tr>
          </thead>
          <tbody>
          <tr v-for="(item, index) in books">
            <td>{{item.id}}</td>
            <td>{{item.name}}</td>
            <td>{{item.date}}</td>
            <!--使用过滤器-->
            <td>{{item.price | showPrice}}</td>
            <td>
              <!--当书籍数量小于等于1时,禁用此按钮-->
              <button @click="decrement(index)" v-bind:disabled="item.count <= 1">-</button>
              {{item.count}}
              <button @click="increment(index)">+</button>
            </td>
            <td>
              <button @click="removeHandle(index)" class="remove">移除</button>
            </td>
          </tr>
          </tbody>
        </table>
        <!--使用过滤器-->
        <h2>总价格: {{totalPrice | showPrice}}</h2>
      </div>
      <h2 v-else>购物车为空</h2>
    </div>
    
    <script src="../js/vue.js"></script>
    <script src="main.js"></script>
    <script>
    </script>
    </body>
    </html>
    HTML代码


    JS

    const app = new Vue({
      el: '#app',
      data: {
        books: [
          {
            id: 1,
            name: '《算法导论》',
            date: '2006-9',
            price: 85.00,
            count: 1
          },
          {
            id: 2,
            name: '《UNIX编程艺术》',
            date: '2006-2',
            price: 59.00,
            count: 1
          },
          {
            id: 3,
            name: '《编程珠玑》',
            date: '2008-10',
            price: 39.00,
            count: 1
          },
          {
            id: 4,
            name: '《代码大全》',
            date: '2006-3',
            price: 128.00,
            count: 1
          },
        ]
      },
      methods: {
        // 普通方法处理价格
        // getFinalPrice(price) {
        //   return '¥' + price.toFixed(2)
        // }
        increment(index) {
          this.books[index].count++
        },
        decrement(index) {
          this.books[index].count--
        },
        removeHandle(index) {
          this.books.splice(index, 1)
        }
      },
      computed: {
        totalPrice() {
          let totalPrice = 0
          //方式1.普通for循环
          // for (let i = 0; i < this.books.length; i++) {
          //   totalPrice += this.books[i].price * this.books[i].count
          // }
          // return totalPrice
    
          //方式2.for(let i in this.books)
          // for (let i in this.books) {
          //   totalPrice += this.books[i].price * this.books[i].count
          // }
          // return totalPrice
    
          //方式3.reduce高阶函数
          this.books.reduce(function (preValue, book) {
            totalPrice += book.price * book.count
          }, 0)
          return totalPrice
        }
      },
      // 过滤器方法处理价格
      filters: {
        showPrice(price) {
          return '¥' + price.toFixed(2)
        }
      }
    })
    
    JS代码


    CSS

    table {
      border: 1px solid #e9e9e9;
      border-collapse: collapse;
      border-spacing: 0;
    }
    
    th, td {
      padding: 8px 16px;
      border: 1px solid #e9e9e9;
      text-align: left;
    }
    
    th {
      background-color: #f7f7f7;
      color: #5c6b77;
      font-weight: 600;
    }
    
    .remove {
      border-style: solid;
      border-color: orange;
      background: orange;
      color: white;
    }
    CSS代码


    七、v-model

    表单控件在实际开发中是非常常见的,特别是对于用户信息的提交,需要大量的表单,vue 中使用 v-model 指令来实现表单元素和数据的双向绑定;


    1、案例

    <body>
    <div id="app">
      <!--v-model使用-->
      <input type="text" v-model="message"> {{message}}
      <hr>
      <!--将v-model用于textarea元素-->
      <textarea v-model="message"></textarea>
      <p>输入的内容是:{{message}}</p>
    </div>
    
    <script src="../js/vue.js"></script>
    <script>
      const app = new Vue({
        el: '#app',
        data: {
          message: '账号'
        }
      })
    </script>
    </body>
    案例代码


    1


    案例解析:

    当我们在输入框输入内容时,因为 input 中的 v-model 绑定了 message,所以会实时将输入的内容传递给 message,

    message 发生改变,当 message 发生改变时,因为使用了 Mustache 语法,所以将 message 的值插入到 DOM 中,

    所以 DOM 会发生响应的改变,所以通过 v-model 实现了双向绑定;


    2、v-model原理

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

    1. v-bind 绑定一个 value 属性
    2. v-on 指令给当前元素绑定 input 事件


    <body>
    <div id="app">
      <!--以下两种写法实现的功能一样-->
      <!--<input type="text" v-bind:value="message" v-on:input="valueChange">-->
      <input type="text" v-bind:value="message" v-on:input="message = $event.target.value">
      <h2>{{message}}</h2>
    </div>
    
    <script src="../js/vue.js"></script>
    <script>
      const app = new Vue({
        el: '#app',
        data: {
          message: 'hello'
        },
        methods: {
          // event
          valueChange(event) {
            //event.target.value; value里面保存的就是最新的input值
            this.message = event.target.value;
          }
        }
      })
    </script>
    </body>
    案例代码


    3、v-model结合radio使用

    <body>
    <div id="app">
      <label for="male">
        <input type="radio" v-model="gender" id="male" value="男"></label>
      <label for="female">
        <input type="radio" v-model="gender" id="female" value="女"></label>
      <h2>你选择的性别是:{{gender}}</h2>
    </div>
    
    <script src="../js/vue.js"></script>
    <script>
     const app = new Vue({
       el: '#app',
       data: {
         gender: '男'
       }
     })
    </script>
    </body>
    案例代码


    4、v-model结合checkbox

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


    单个勾选框:

         v-model即为布尔值。

        此时input的value并不影响v-model的值。

    <body>
    <div id="app">
      <label for="agree">
        <input type="checkbox" id="agree" v-model="isAgree">同意协议
      </label>
      <h2>你选择的是:{{isAgree}}</h2>
      <!--只有当同意协议后才能点击下一步的按钮-->
      <button :disabled="! isAgree">下一步</button>
    </div>
    
    <script src="../js/vue.js"></script>
    <script>
      const app = new Vue({
        el: '#app',
        data: {
          isAgree: false
        }
      })
    </script>
    </body>
    单选框代码


    多个复选框:

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

         当选中某一个时,就会将input的value添加到数组中。

    <body>
    <div id="app">
      <input type="checkbox" value="篮球" v-model="hobbies">篮球
      <input type="checkbox" value="足球" v-model="hobbies">足球
      <input type="checkbox" value="棒球" v-model="hobbies">棒球
      <h3>您的爱好是:{{hobbies}}</h3>
    </div>
    
    <script src="../js/vue.js"></script>
    <script>
      const app = new Vue({
        el: '#app',
        data: {
          hobbies: []
        }
      })
    </script>
    </body>
    单选框代码


    5、v-model结合select

    <body>
    <div id="app">
    <!--  单选-->
      <select name="abc" v-model="fruit">
        <option value="香蕉">香蕉</option>
        <option value="苹果">苹果</option>
        <option value="葡萄">葡萄</option>
        <option value="橘子">橘子</option>
      </select>
      <h2>您选择的是:{{fruit}}</h2>
    
      <!--  多选-->
      <!--加上multiple-->
      <select name="abc" v-model="fruits" multiple>
        <option value="香蕉">香蕉</option>
        <option value="苹果">苹果</option>
        <option value="葡萄">葡萄</option>
        <option value="橘子">橘子</option>
      </select>
      <h2>您选择的是:{{fruits}}</h2>
    </div>
    
    <script src="../js/vue.js"></script>
    <script>
     const app = new Vue({
       el: '#app',
       data: {
         fruit: '香蕉',
         fruits: []
       }
     })
    </script>
    </body>
    代码


    6、v-model修饰符

    • lazy 修饰符
      • 默认情况下,v-model 是在 input 事件中同步输入框的数据,也就是说,一旦有数据发生改变,对应的 data 中的数据就会自动发生改变
      • lazy 修饰符可以让数据在失去焦点或者回车时才会更新
    • number 修饰符
      • 默认情况下,在输入框中无论输入的是字母还是数字,都会被当做字符串类型来处理,但是如果我们希望处理的是数字类型,那么最好直接将内容当做数字处理
      • number 修饰符可以让在输入框中输入的内容自动转成数字类型
    • trim 修饰符
      • 如果输入的内容首尾有很多空格,通常我们希望将其去除
      • trim 修饰符可以过滤内容左右两边的空格


    <body>
    <div id="app">
    <!--  lazy-->
      <input type="text" v-model.lazy="message">
      <h2>{{message}}</h2>
    
    <!--  number-->
      <input type="text" v-model.number="age">
      <h2>{{age}}-{{typeof age}}</h2>
    
      <!--trim-->
      <input type="text" v-model.trim="name">
      <h2>您输入的名字是:{{name}}</h2>
    </div>
    
    <script src="../js/vue.js"></script>
    <script>
     const app = new Vue({
       el: '#app',
       data: {
         message: 'hello',
         age: 0,
         name: ''
       }
     })
    </script>
    </body>
    代码
  • 相关阅读:
    第一课 GCC入门
    第二课客户端链接Linux系统
    2014目标!!!!
    第一课Linux系统安装知识(2)
    android开发系列之ContentObserver
    android开发系列之数据存储
    android开发系列之视频断点续传
    稻盛和夫系列之活法一
    android开发系列之使用xml自定义控件
    android开发系列之MVP设计模式
  • 原文地址:https://www.cnblogs.com/weiyiming007/p/13535273.html
Copyright © 2011-2022 走看看