Evan's blog Evan's blog
首页
关于
  • 分类
  • 标签
  • 归档
  • H5&CSS3
  • JS
  • TS
  • Node
  • Webpack
  • Vue2
  • Vue3
  • 微信小程序
  • Andorid
  • Flutter
推荐
GitHub (opens new window)

conanan

真相只有一个
首页
关于
  • 分类
  • 标签
  • 归档
  • H5&CSS3
  • JS
  • TS
  • Node
  • Webpack
  • Vue2
  • Vue3
  • 微信小程序
  • Andorid
  • Flutter
推荐
GitHub (opens new window)
  • 基础

    • 入门
    • 插值语法
      • Mustache 语法 🔥
      • v-once 指令 🔥
      • v-text 指令
      • v-html 指令 🔥
      • v-pre 指令 🔥
      • v-cloak 指令
      • 过滤器 🔥
    • 绑定属性
    • 计算属性和侦听器
    • 事件监听
    • 条件和循环
    • 表单双向绑定
  • 组件

  • Vue CLI

  • Vue Router

  • Vue2.x
  • 基础
xugaoyi
2020-12-27
目录

插值语法

# 插值语法—文本

将 data 中数据插入到 HTML 模版内容中

# Mustache 语法 🔥

Mustache 语法,双大括号

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Vue</title>
  </head>

  <body>
    <div id="app">
      <h2>{{message}}</h2>
      <h2>{{message}}李银河</h2>
      <!-- 表达式 -->
      <h2>{{lastName + firstName}}</h2>
      <h2>{{lastName + " "+firstName}}</h2>
      <h2>{{lastName}}@{{firstName}}</h2>
      <h2>{{count*2}}</h2>
    </div>

    <script src="./lib/vue.js"></script>
    <script>
      const vm = new Vue({
        el: "#app",
        data: {
          message: "你好!",
          firstName: "三",
          lastName: "张",
          count: 100,
        },
      });
    </script>
  </body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

Mustache 标签将会被替代为对应 data 数据对象上属性的值。

无论何时,绑定的 data 数据对象上属性发生了改变,插值处的内容都会更新。

Mustache 中存放的是变量对象,也可以放表达式、方法(最后需带括号)(不推荐),若用引号引用则视作字符串不再解析。

# v-once 指令 🔥

只渲染元素和组件一次。随后的重新渲染,元素/组件及其所有的子节点将被视为静态内容并跳过。这可以用于优化更新性能。通过使用 v-once 指令 (opens new window),你也能执行一次性地插值,当数据改变时,插值处的内容不会更新。但请留心这会影响到该节点上的其它数据绑定

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Title</title>
  </head>

  <body>
    <div id="app">
      <!-- 单个元素 -->
      <h2>This will change: {{message}}</h2>
      <h2 v-once>This will never change: {{message}}</h2>

      <!-- 有子元素 -->
      <div>
        <h2>{{message}}</h2>
      </div>
      <div v-once>
        <h2>{{message}}</h2>
      </div>

      <!-- 组件 -->
      <my-component v-once :comment="message"></my-component>
      <my-component :comment="message"></my-component>

      <!-- `v-for` 指令-->
      <ul>
        <li v-for="i in list" :key="i">{{i}}</li>
      </ul>
      <ul>
        <li v-for="i in list" :key="i" v-once>{{i}}</li>
      </ul>
    </div>

    <script src="/lib/vue.js"></script>
    <script>
      // 这里写的组件必须在 new Vue() 前定义!
      Vue.component("my-component", {
        data: function () {
          return {
            count: 0,
          };
        },
        props: {
          comment: "",
        },
        template: "<h1>{{comment}} my-component</h1>",
      });

      const vm = new Vue({
        el: "#app",
        data: {
          message: "Test 1",
          list: [1, 2, 3],
        },
        methods: {},
      });
    </script>
  </body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61

# v-text 指令

作用和 Mustache 相似,更新元素的 textContent。但是会覆盖该标签的内容!不灵活,一般使用较少!如果要更新部分的 textContent ,需要使用 插值。

# v-html 指令 🔥

双大括号会将数据解释为普通文本,而非 HTML 代码。为了输出真正的 HTML,你需要使用 v-html 指令 (opens new window):

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Title</title>
  </head>

  <body>
    <div id="app">
      mustache:
      <span>{{url}}</span><br />

      v-html:
      <span v-html="url"></span><br />

      v-text:
      <span v-text="url"></span><br />
    </div>

    <script src="/lib/vue.js"></script>
    <script>
      const vm = new Vue({
        el: "#app",
        data: {
          message: "Hello",
          url: '<a href="https://www.qq.com">QQ</a>',
        },
        methods: {},
      });
    </script>
  </body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

属性值会直接作为 HTML——会忽略解析属性值中的数据绑定。注意,你不能使用 v-html 来复合局部模板,因为 Vue 不是基于字符串的模板引擎。反之,对于用户界面 (UI),组件更适合作为可重用和可组合的基本单位。

# v-pre 指令 🔥

如<pre>,跳过这个元素和它的子元素的编译过程。可用来显示原始 Mustache 标签。跳过大量没有指令的节点会加快编译。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Title</title>
  </head>

  <body>
    <div id="app">
      <span v-pre>{{ this will not be compiled }}</span>
    </div>

    <script src="/lib/vue.js"></script>
    <script>
      const vm = new Vue({
        el: "#app",
      });
    </script>
  </body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

# v-cloak 指令

cloak

披风; 斗篷; 大衣; 氅。这里为挡住之类的意思。

区别 clock 时钟

这个指令保持在元素上直到关联实例结束编译,可以据此来实现判断。

上述含义为,在 Vue 编译完前 HTML 中有 v-cloak 属性,在 Vue 编译完后该属性被删掉。

基本也不会使用,以后这个模版会渲染为函数,和虚拟DOM有关,不会显示 mustache 语法的。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Title</title>
    <style>
      /* 属性选择器 */
      [v-cloak] {
        display: none;
      }
    </style>
  </head>

  <body>
    <div id="app">
      <h2 v-cloak>{{message}}</h2>
    </div>

    <script src="/lib/vue.js"></script>
    <script>
      setTimeout(() => {
        const vm = new Vue({
          el: "#app",
          data: {
            message: "Hello",
          },
          methods: {},
        });
      }, 2000);
    </script>
  </body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

# 过滤器 🔥

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Vue</title>
    <style>
      table {
        /* 合并细线边框 */
        border-collapse: collapse;
        /* 单元格之间水平、垂直距离,与 border-collapse 冲突,不常用 */
        /*border-spacing: 10px 20px;*/
        /* 表格居中 */
        margin: 100px auto;
      }
      th,
      td {
        /* 边框 */
        border: 1px solid skyblue;
        /* 内边距 */
        padding: 20px;
        /* 让td居中,th本来就是居中的 */
        text-align: center;
        /* 默认情况下元素在th,td中是垂直居中的,也可以通过 vertical-align 来修改*/
        /* 由此可得,对一个父元素设置 display: table-cell,可以直接使用 vertical-align 来垂直居中*/
      }
    </style>
  </head>

  <body>
    <div id="app">
      <div v-if="books.length >= 1">
        <table>
          <thead>
            <tr>
              <th></th>
              <th>书籍名称</th>
              <th>出版日期</th>
              <th>价格</th>
              <th>购买数量</th>
              <th>操作</th>
            </tr>
          </thead>
          <tbody>
            <tr v-for="(book,index) in books" :key="book.id">
              <td>{{book.id}}</td>
              <td>{{book.name}}</td>
              <td>{{book.time}}</td>
              <!-- <td>{{'¥'+book.price.toFixed(2)}}</td> -->
              <!-- 这么多地方使用,可以复用 -->
              <!-- 方式1:方法。计算属性也可以 -->
              <!-- <td>{{formartPrice(book.price)}}</td> -->
              <!-- 方式2:过滤器 -->
              <td>{{book.price | formartPrice}}</td>

              <td>
                <button @click="decrement(book)" :disabled="book.count === 1">
                  -
                </button>
                {{book.count}}
                <button @click="increment(book)">+</button>
              </td>
              <td><button @click="remove(index)">移除</button></td>
            </tr>
          </tbody>
        </table>
        <!-- 总价:{{'¥'+totalPrice.toFixed(2)}} -->
        <!-- 总价:{{formartPrice(totalPrice)}} -->
        总价:{{totalPrice | formartPrice}}
      </div>
      <div v-else>
        购物车为空
      </div>
    </div>

    <script src="/lib/vue.js"></script>
    <script>
      // vue.js文件中定义了 Vue 对象,使用时可以 new 构造出,并且它还有参数(对象类型)
      const vm = new Vue({
        el: "#app",
        // 声明式编程(声明式渲染),不再使用命令式
        data: {
          books: [
            { id: 1, name: "Java", time: "2006-02", price: 110.0, count: 1 },
            { id: 2, name: "Kotlin", time: "2016-03", price: 120.0, count: 1 },
            { id: 3, name: "Clojure", time: "2008-12", price: 112.0, count: 1 },
            { id: 4, name: "JVM", time: "2002-8", price: 200.0, count: 1 },
          ],
        },
        methods: {
          increment(book) {
            book.count++;
          },
          decrement(book) {
            // if (book.count === 1) {
            //   return;
            // }
            book.count--;
          },
          remove(index) {
            this.books.splice(index, 1);
          },
          formartPrice(price) {
            return "¥" + price.toFixed(2);
          },
        },
        computed: {
          totalPrice() {
            // let totalPrice = 0;
            // this.books.forEach((item) => {
            //   totalPrice += item.price * item.count;
            // });
            // return totalPrice;

            return this.books.reduce((previous, current, index, arr) => {
              return previous + current.price * current.count;
            }, 0);
          },
        },
        filters: {
          formartPrice(price) {
            return "¥" + price.toFixed(2);
          },
        },
      });
    </script>
  </body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
编辑 (opens new window)
上次更新: 2022/03/23, 17:55:39
入门
绑定属性

← 入门 绑定属性→

最近更新
01
重点
04-12
02
搭建项目
04-04
03
TS补充
03-30
更多文章>
Theme by Vdoing | Copyright © 2019-2022 conanan | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式