ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

第 2 节 Mustache、v-bind、计算属性、v-on、v-if、v-for、响应式方法

2021-10-30 10:58:40  阅读:172  来源: 互联网

标签:index -- bind app 元素 语法 响应 books Mustache


第2节 Mustache语法、v-bind、计算属性、v-on、v-if、v-for、响应式方法

Mustache语法(双大括号)

直接写变量或者写一些简单的表达式。

<h2>{{message}}</h2>
<h2>{{firstName}} {{lastName}}</h2>
<h2>{{firstName + ' ' + lastName}}</h2>
<h2>{{counter * 2}}</h2>

其他指令

1、v-once
(1)该指令不需要跟任何表达式
(2)表示元素和组件只渲染一次,不会随着数据的改变而改变。
2、v-html
(1)该指令后面往往会跟上一个string类型
(2)会将string的html解析出来并且进行渲染

<h2 v-html="url"></h2>   <!-- 其中,url: '<a href = "http://www.baidu.com">百度一下</a>' -->

3、v-text
该指令后面往往会跟上一个string类型,很少用,会用 mustache语句替代。
4、v-pre
用于跳过这个元素和它子元素的变异过程,用于显示原本的Mustache语句。

<h2>{{message}}</h2>  <!-- 解析message中对应的内容 -->
<h2 v-pre>{{message}}</h2>  <!-- 直接显示{{message}} -->

5、v-cloak
在某些情况下,浏览器可能会直接显示出未编译的Mustache标签。
在vue解析前,有这个属性,但是在解析之后就没有了,在解析的过程中会被删除。

v-bind(动态绑定属性)

v-bind基本使用

<div id="app">
        <img v-bind:src="imgURL" alt="">  <!-- v-bind命令 -->
        <a v-bind:href="aHref">百度一下</a>
    </div>

    <script src="../js/vue.js"></script>

    <script>
        const app = new Vue({
            el: '#app',
            data: {
                imgURL: 'https://img10.360buyimg.com/img/jfs/t1/160510/16/25709/36032/616cea7eEd14780cc/43b0d9ed8c9e9ab0.png',
                aHref: 'http://www.baidu.com'
            }
        })
    </script>

语法糖的写法:

<img :src="imgURL" alt="">  <!-- v-bind命令 -->
<a :href="aHref">百度一下</a>

v-bind 动态绑定class

对象语法

语法格式:

<h2 :class="{类名: 布尔值}">{{message}}</h2>

数组语法

用法一:传入的是变量
<h2 class="title" :class="[active, line]">{{message}}</h2>  //active 和 line是变量,不需要写单引号

用法二:过于复杂时,可以放在一个methods或者computed中
<h2 class="title" :class="getClasses()">{{message}}</h2>  //getClasses()方法

作业(v-bind 和 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=script, initial-scale=1.0">
  <title>Document</title>
  <style>
    .active {
      color: red;
    }
  </style>
</head>

<body>
  <div id="app">
    <ul>
      <li v-for="(item,index) in books" :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: {
        books: ['西游记', '红楼梦', '三国演义', '水浒传'],
        // 利用状态变量 currentIndex
        currentIndex: 0
      },
      methods: {
        liClick(index) {
          this.currentIndex = index;
        }
      }
    })
  </script>
</body>

</html>

v-bind 绑定 style

对象语法

语法格式:

<h2 :style = "{key(属性名): value(属性值)}">{{message}}</h2>

<h2 :style="{fontSize:'50px'}">{{message}}</h2>  //'50px'必须加上单引号,否则被当做变量去解析

数组语法(很少使用)

语法格式:

<h2 :style="[baseStyle, overridingStyles]"></h2>

计算属性

计算属性的操作

1、基本使用

<div id="app">
        <h2>{{fullName}}</h2>
    </div>

    <script src="../js/vue.js"></script>

    <script>
        const app = new Vue({
            el: '#app',
            data: {
                firstName: 'Lee',
                lastName: 'James'
            },
            // computed: 计算属性()
            computed: {
                fullName: function () {
                    return this.firstName + ' ' + this.lastName
                }
            }
        })
    </script>

2、复杂操作

<div id="app">
        <h2>总价格:{{totalPrice}}</h2>
    </div>

    <script src="../js/vue.js"></script>

    <script>
        const app = new Vue({
            el: '#app',
            data: {
                books: [
                    { id: 110, name: '西游记', price: 119 },
                    { id: 111, name: '红楼梦', price: 105 },
                    { id: 112, name: '三国演义', price: 98 },
                    { id: 113, name: '水浒传', price: 87 }
                ]
            },
            computed: {
                totalPrice: function () {
                    let result = 0
                    for (let i = 0; i < this.books.length; i++) {
                        result += this.books[i].price
                    }
                    return result
                }
            }

        })
    </script>

计算属性的 setter 和 getter

每一个计算属性都包含以个 getter 和 setter。一般没有 set 方法,只读属性。

<div id="app">
    <h2>{{fullName}}</h2>
</div>

<script src="../js/vue.js"></script>

<script>
    const app = new Vue({
        el: '#app',
        data: {
            firstName: 'Lee',
            lastName: 'Jane'
        },
        computed: {
            fullName: {
                set: function (newValue) {
                    const names = newValue.split(' ');
                    this.firstName = names[0];
                    this.lastName = names[1];
                },
                get: function () {
                    return this.firstName + ' ' + this.lastName
                }
            }
        }

    })
</script>

计算属性和methods的对比

计算属性的性能会比 methods 高,由于计算属性会进行缓存,所以如果在多次使用时,计算属性只会调用一次

事件监听

v-on 的基本使用和语法糖

使用 v-on 指令,监听用户发生的事件,比如点击、拖拽、键盘等等。

<body>
  <div id="app">
    <h2>{{counter}}</h2>
    <!-- <button v-on:click="increment">+</button> -->
    <!-- <button v-on:click="decrement">-</button> -->
    
    <!-- 采用 v-on 的语法糖:-->
    <button @click="increment">+</button>
    <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>

v-on 也有对应的语法糖。v-on:click 可以写成 @click

v-on 的参数传递问题

事件监听时,

<body>
  <div id="app">
    <!-- 1、事件调用的方法没有参数 -->
    <button @click="btn1Click">按钮1</button>
    <button @click="btn1Click()">按钮2</button>

    <!-- 2、事件定义时,方法本身需要一个参数 -->
    <button @click="btn2Click(123)">按钮3</button>
    <button @click="btn2Click()">按钮4</button>
    <!-- 在事件定义时,写方法是省略了小括号,但是方法本身是需要一个参数的, -->
    <!-- 这时Vue会默认将浏览器生成的event事件对象作为参数传入到方法中 -->
    <button @click="btn2Click">按钮5</button>

    <!-- 3、方法定义时,需要event对象,同时又需要其他参数 -->
    <!-- 手动获取到浏览器参数的event对象:$event -->
    <button @click="btn3Click(">按钮6</button>
  </div>

  <script src="../js/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      methods: {
        btn1Click() {
          console.log("btn1Click");
        },
        btn2Click(event) {
          console.log('--------', event);
        },
        btn3Click(abc, event) {
          console.log('+++++++++', abc)
        }

      }
    })
  </script>
</body>

v-on 修饰符使用

<body>
  <div id="app">
    <!-- 1、.stop修饰符的使用:阻止事件的冒泡 -->
    <div @click="divClick">
      <!-- <button @click="btnClick">按钮</button> -->
      <button @click.stop="btnClick">按钮</button>
    </div>

    <!-- 2、.prevent修饰符的使用:阻止默认事件 -->
    <form action="baidu">
      <!-- <input type="submit" value="提交" @click="submitClick"> -->
      <input type="submit" value="提交" @click.prevent="submitClick">
    </form>

    <!-- 3、监听某个键盘的键帽 -->
    <!-- 监听回车键 -->
    <input type="text" @keyup.enter="keyUp">

    <!-- 4、.once修饰符的使用 -->
    <button @click.once="btn2Click">按钮2</button>
  </div>

  <script src="../js/vue.js"></script>

  <script>
    const app = new Vue({
      el: '#app',
      methods: {
        btnClick() {
          console.log("btnClick");
        },
        divClick() {
          console.log("divClick");
        },
        submitClick() {
          console.log('submitClick');
        },
        keyUp() {
          console.log('keyUp');
        },
        btn2Click() {
          console.log('btn2Click');
        }
      }
    })
  </script>
</body>

条件判断

v-ifv-else-ifv-else

<body>

  <div id="app">
    <!-- <h2 v-if=isShow>{{message}}</h2> -->
    <!-- <h2 v-else=isShow>isShow为false时,显示我</h2> -->

    <!-- <h2 v-if="score>=90">优秀</h2> -->
    <!-- <h2 v-else-if="score>=80">良好</h2> -->
    <!-- <h2 v-else-if="score>=60">及格</h2> -->
    <!-- <h2 v-else>不及格</h2> -->

    <!-- 复杂逻辑推荐使用computed -->
    <h2>{{result}}</h2>

  </div>

  <script src="../js/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        message: '你好呀',
        isShow: true,
        score: 99
      },
      computed: {
        result() {
          let showMessage = ' ';
          if (this.score >= 90) {
            showMessage = '优秀';
          } else if (this.score >= 80) {
            showMessage = '良好';
          } else if (this.score >= 60) {
            showMessage = '及格';
          } else {
            showMessage = '不及格';
          }

          return showMessage;
        }
      }
    })
  </script>

</body>

用户登录切换案例

<body>

  <div id="app">
    <span v-if="isUser">
      <label for="username">用户账号</label>
      <!-- placeholder:文本框中灰色显示的提示文字 -->
      <!-- <input type="text" id="username" placeholder="用户账号"> -->
      <input type="text" id="username" placeholder="用户账号" key="username">
    </span>

    <span v-else>
      <label for="email">用户邮箱</label>
      <!-- <input type="text" id="email" placeholder="用户邮箱"> -->
      <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>

案例中,存在一个小问题,通过增加不同的 key 来解决 复用 问题

v-if 和 v-show 的区别

循环遍历

v-for 遍历数组

在遍历过程中,获取索引值(下标值)

<!-- 在遍历过程中,获取索引值(下标值) -->
<li v-for="(item,index) in names">
  {{index + 1}}-{{item}}
</li>

v-for 遍历对象

<!-- 1、在遍历对象的过程中,如果只是获取一个值,那么获取到的是value -->
<ul>
  <li v-for="item in info">{{item}}</li>
</ul>

<!-- 2、获取key和value 格式:(value, key) -->
<ul>
  <li v-for="(value,key) in info">
    {{key}}-{{value}}
  </li>
</ul>

<!-- 3、获取key、value和index -->
<ul v-for="(value,key,index) in info">
  <li>
    {{index}}-{{key}}-{{value}}
  </li>
</ul>

v-for绑定和非绑定key的区别

数组中的响应式方法

响应式

1、push():在数组末尾加入一个或多个元素

this.letters.push('aaa', 'bbb')

2、pop():删除数组中最后一个元素

this.letters.pop()

3、shift():删除数组中第一个元素

this.letters.shift()

4、unshift():在数组最前面添加一个或多个元素

this.letters.unshift('aaa', 'bbb')

5、splice():删除/插入/替换元素
1)第一个参数:开始的位置(索引值)
2)第二个参数:
(1)删除元素:表示要 删除的元素个数(如果没有传,则删除后面的所有元素)

this.letters.splice(0,1) //从第一元素开始,删除一个元素

(2)替换元素:表示要 替换的元素个数,后面是用于替换前面的元素

this.letters.splice(0,2,'aaa','bbb')  //替换从第一个元素开始和其后的一个元素为'aaa','bbb'

(3)插入元素:为 0,并且后面跟上要插入的元素

this.letters.splice(1, 0, 'aaa')  //在第二个元素前面插入一个元素'aaa'

6、sort():排序

7、reverse():翻转

8、set(要修改的对象, 索引值, 修改后的值) (重要)

Vue.set(this.letters, 0, 'bbb')  //将letters中的第一个元素修改为'bbb'

非响应式

通过索引值修改数组中的元素,是非响应式,修改后不会在网页中显示出来。

this.letters[0] = 'bbbb'

购物车案例

当购物车中书籍全被移除时,显示“购物车为空”。购买数量至少为1

1、index.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>
  <link rel="stylesheet" href="style.css">
</head>

<body>

  <div id="app">
    <div v-if="books.length">
      <table>
        <thead>
          <tr>
            <th></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>
              <button @click="decrement(index)">-</button>
              {{item.count}}
              <button @click="increment(index)">+</button>
            </td>
            <td><button @click="removeHandler(index)">移除</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>

</body>

</html>

2、style.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;
}

3、main.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: {
    increment(index) {
      this.books[index].count++;
    },
    decrement(index) {
      this.books[index].count--;
      if (this.books[index].count < 1) {
        this.books[index].count = 1;
      }
    },
    removeHandler(index) {
      this.books.splice(index, 1);
    }
  },
  computed: {
    totalPrice() {
      let totalPrice = 0;
      for (let i = 0; i < this.books.length; i++) {
        totalPrice += this.books[i].price * this.books[i].count
      }
      return totalPrice
    }
  },
  //过滤器
  filters: {
    showPrice(price) {
      return '¥' + price.toFixed(2)
    }
  }

})

标签:index,--,bind,app,元素,语法,响应,books,Mustache
来源: https://blog.csdn.net/qq_48015123/article/details/121015407

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有