沉梦手记 沉梦手记
首页
  • 基础篇
  • 集合篇
  • 并发篇
  • JVM
  • 新特性
  • 计算机网络
  • 操作系统
  • 数据结构与算法
  • 数据库基础
  • MySql
  • Redis
  • 达梦数据库
  • Spring
  • SpringBoot
  • Mybatis
  • Shiro
  • 设计须知
  • UML画图
  • 权限校验
  • 设计模式
  • API网关
  • 网络通信
  • 消息队列
  • SpringCloud
  • 分布式事务
  • 云存储
  • 搜索引擎
  • 前端基础
  • Vue
  • React
  • 开发工具篇
  • 工具库篇
  • 开发技巧篇
  • 工具类系列
  • 运维与部署
  • 音视频处理
  • 随笔
  • 博客搭建
  • 网站收藏箱
  • 断墨寻径摘录
  • 费曼学习法
Github (opens new window)

沉梦听雨

时间是最好的浸渍剂,而沉淀是最好的提纯器🚀
首页
  • 基础篇
  • 集合篇
  • 并发篇
  • JVM
  • 新特性
  • 计算机网络
  • 操作系统
  • 数据结构与算法
  • 数据库基础
  • MySql
  • Redis
  • 达梦数据库
  • Spring
  • SpringBoot
  • Mybatis
  • Shiro
  • 设计须知
  • UML画图
  • 权限校验
  • 设计模式
  • API网关
  • 网络通信
  • 消息队列
  • SpringCloud
  • 分布式事务
  • 云存储
  • 搜索引擎
  • 前端基础
  • Vue
  • React
  • 开发工具篇
  • 工具库篇
  • 开发技巧篇
  • 工具类系列
  • 运维与部署
  • 音视频处理
  • 随笔
  • 博客搭建
  • 网站收藏箱
  • 断墨寻径摘录
  • 费曼学习法
Github (opens new window)
  • 前端基础

  • Vue

    • Vue-Router入门
    • Pinia入门
    • Vue3入门

      • Vue3简介与环境搭建
      • TypeScript基础
      • 模板语法与指令
        • 核心语法
          • 1 文本插值
          • 2 原始 HTML
          • 3 属性绑定
        • 条件渲染和 template
          • 1 v-if 指令
          • 2 template
          • 3 v-show 指令
        • 循环渲染
          • 1 v-for 输出项
          • 2 索引和值
          • 3 v-for 和 v-if
        • 样式绑定
          • 1 Class 指令
          • 2 内联样式
        • Composition API 写法
        • 属性绑定
        • 条件与列表
      • 计算属性与侦听器
      • 事件处理与表单输入
      • 组件与响应式API
      • 网络请求
      • UI组件库与项目实战
    • Vue3进阶
  • React

  • 前端学习
  • Vue
  • Vue3入门
沉梦听雨
2023-07-07
目录

模板语法与指令

# 模板语法与指令

Vue 使用基于 HTML 的模板语法,允许开发者声明式地将 DOM 绑定至底层组件实例的数据。本章介绍文本插值、属性绑定、条件渲染、列表渲染和样式绑定等核心指令。

# 核心语法

想学一门编程语言,就要先整明白它的语法规则。Vue 使用了基于 HTML 的模板语法,允许开发者声明式地将 DOM 绑定至底层组件实例的数据。所有 Vue 的模板都是合法的 HTML,所以能被遵循规范的浏览器和 HTML 解析器解析。

# 1 文本插值

数据绑定最常见的形式就是使用双大括号 {{}} 的文本插值,如果你要用不常见的,那可用 <span v-text=""></span> 的方式。

在 Vue 中,带有 v- 前缀的特殊属性,称为指令。

无论选择哪一个插值方式绑定到组件(HTML标签)上,在组件实例上的值发生了改变,插值处的内容都会更新,这便是数据驱动的方式。

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title>Vue3.0核心语法</title>
    <script src="vue.global.js"></script>
</head>

<body>
    <div id="hello"> 
      <input id="name" v-model="msg" placeholder="输入文本内容" />
      <p>用双大括号实现文本插值:{{ msg }}</p>
      <p>用v-text指定实现插值:<span v-text="msg"></span></p>
    </div>
    <script>
        // 第1步:data数据;
        // 第2步:vue实例,
        // 第3步:绑定元素     
        Vue.createApp({
            data() {
                return { msg: '' }
            }
        }).mount("#hello") 
    </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

# 2 原始 HTML

在开发过程中,有时会输出有格式的动态内容,比如输出带颜色文本。如果用插值的方式,输出的为文本内容,显然满足不了要求。这时就要用到 v-html 指令了。

温馨提醒:原始 HTML,尽量不要用在输入上,因为它很容易导致 XSS 攻击。

XSS 攻击通常指的是:通过利用网页开发时留下的漏洞,通过巧妙的方法注入恶意指令代码到网页中。

<!DOCTYPE html>
<html>
  
  <head>
    <meta charset="UTF-8">
    <title>Vue3.0核心语法</title>
    <script src="vue.global.js"></script>
  </head>
  
  <body>
    <div id="vh">
      <p>文本插值结果: {{ msg }}</p>
      <p>原始HTML结果: <span v-html="msg"></span></p>
    </div>
    <script>
      // 第1步:data数据;
      // 第2步:vue实例,
      // 第3步:绑定元素     
      Vue.createApp({
        data() {
          return {
            msg: '<span style="color: red">vue.js 3.0</span>'
          }
        }
      }).mount("#vh") 
    </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

# 3 属性绑定

在 Vue 中,

  • 对 HTML 属性的绑定,采用 v-bind(可缩写为":")指令,
  • 对事件的绑定,采用 v-on(可缩写为"@")指令。

这里说下 v-bind 的应用,v-on 在讲事件时再细讲。

你可能会奇怪,绑定属性有什么用?我随便举一个例子,你就秒懂了。

当美女程序员看我的文章时,系统就给她推荐有漂亮图表的文章链接地址;当男性程序员看我的文章时,系统就给推荐有漂亮MM的文章链接地址,以此来提高阅读量。

<!-- 完整语法 --> <a v-bind:href="url"> ... </a>

<!-- 缩写 --> <a :href="url"> ... </a>

<!DOCTYPE html>
<html>
  
  <head>
    <meta charset="UTF-8">
    <title>Vue3.0核心语法</title>
    <script src="vue.global.js"></script>
  </head>
  
  <body>
    <div id="vh">
      <p>文本插值结果: {{ msg }}</p>
      <p>原始HTML结果: <span v-html="msg" ></span></p>
      <a :href="site">跳转</a>
    </div>
    <script>
      // 第1步:data数据;
      // 第2步:vue实例,
      // 第3步:绑定元素     
      Vue.createApp({
        data() {
          return {
            msg: '<span style="color: red">vue.js 3.0</span>',
            site: 'http://www.sohu.com'
          }
        }
      }).mount("#vh") 
    </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

# 条件渲染和 template

所谓的条件,指的就是满足什么条件,允许做什么事,不满足时,是不允许做的。如共享单车,规定满 12 周岁或以上才可以骑行,没满的则不被允许。学每门编程语言,条件语句都是必须熟练掌握的,Vue3.0 的也不例外。

# 1 v-if 指令

在 Vue3.0 中,条件语句是通过 v-if 指令实现的。

如果判断条件为 True,就执行 v-if 语句里的内容,否则什么都不执行。

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title>vue3.0条件语法</title>
    <script src="vue.global.js"></script>
</head>

<body>
    <div id="app">
        <h1 v-if='cool'>前端编程</h1>
    </div>
    <script>
        Vue.createApp({
            data() {
                return { cool: true }
            }
        }).mount("#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
22
23

如果 v-if 为 false 时,你不想输出空气,不想什么都不执行,那就其后面加上 v-else 指令。

v-if 和 v-else 搭在一起使用,规则是:v-if 的条件为 true 时,执行 v-if 里的内容,否则执行 v-else 里的。

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title>vue3.0条件语法</title>
    <script src="vue.global.js"></script>
</head>

<body>
    <div id="app">
        <h1 v-if='cool'>前端编程</h1>
        <h1 v-else>不学前端,还可以学后端嘛</h1>
    </div>
    <script>
        Vue.createApp({
            data() {
                return { cool: false }
            }
        }).mount("#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
22
23
<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title>vue3.0条件语法</title>
    <script src="vue.global.js"></script>
</head>

<body>
    <div id="app">
        <h1 v-if="program === 'Vue3.0'">vue3.0 很酷,很酷 </h1>
        <h1 v-else-if="program === '前端'">前端,很酷</h1>
        <h1 v-else-if="program === 'Java'">Java,很酷</h1>
        <h1 v-else-if="program === 'App'">App,很酷</h1>
        <h1 v-else>Python,也酷</h1>
    </div>
    <script>
        Vue.createApp({
            data() {
                return {
                    program: 'Vue3.0'
                }
            }
        }).mount("#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
22
23
24
25
26
27
28
29

# 2 template

长得有点(不是特别)酷的你,可能早就注意到了,v-if 指令,都是附加在一个元素上的;

如果想要实现切换多个元素,该如何?

可以将 v-if 放在 <template> 元素中。

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title>vue3.0条件语法</title>
    <script src="vue.global.js"></script>
</head>

<body>
    <div id="app">
        <template v-if="show">
            <h1>编程</h1>
            <p>编程都用啥工具<br />
                工具不重要,重要的是思想<br />
                Python,前端(小程序)、Java和App 都是工具<br />
                用啥都可以好程序</p>
        </template>
    </div>
    <script>
        Vue.createApp({
            data() {
                return {
                    show: true
                }
            }
        }).mount("#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
22
23
24
25
26
27
28
29
30
31

# 3 v-show 指令

  • 如果你要实现业务方面的条件判断,用 v-if 指令就可以了;
  • 如果只是想切换一下 CSS 的内容,那你可以用 v-show 指令。

v-show 只是简单地切换元素的 CSS 属性值,不支持 v-else,也不支持 <template> 元素,它常用于隐藏或显示某个元素。

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title>vue3.0条件语法</title>
    <script src="vue.global.js"></script>
    <style>
        .show {
            margin-top: 20px;
            width: 600px;
            height: 50px;
            background: darkcyan;
        }
    </style>
</head>

<body>
    <div id="app">
        <input type="button" value="按下就报幕" v-on:click="show"> <br />
        <div class="show" v-show="report">报幕~~~</div>
    </div>
    <script>
        Vue.createApp({
            data() {
                return {
                    report: false
                }
            },
            methods: {
                show() {
                    this.report = true;
                }
            }
        }).mount("#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
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

# 循环渲染

开发一个Web系统,如果没有涉及到列表功能的话,那真的有点奇葩了,而循环输出列表内容,不用for循环语句的话,那我真不知道该用什么了。在Vue3.0中,v-for指令基于一个数组来渲染输出一个列表内容。

# 1 v-for 输出项

Vue 的 v-for 指令使用 item in items 形式的特殊语法,同其他编程语言(如Python)并没有多大区别。

其中 items 是源数据数组,而 item 则是被迭代的数组元素的别名。

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Vue3.0循环语法</title>
    <script src="vue.global.js"></script>
    <style>
        .lang {
            border: 1px solid darkcyan;
            width: 600px;
            height: 200px;
        }
    </style>
</head>
<body>
<div class="lang">
    Vue.js 3.0 系列教程
    <ol id="program">
        <li v-for="item in items">
            {{ item.lang }}
        </li>
    </ol>
</div>
<script>
    Vue.createApp({
        data() {
            return {
                items: [{lang: 'Python'}, {lang: '前端'},
                    {lang: 'Vue3.0'}, {lang: 'koa2'},
                    {lang: 'Java'}, {lang: 'App'}]
            }
        }
    }).mount("#program")
</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

# 2 索引和值

数据列表在表格输出时,常常需要用到序号。

v-for 指令支持输出下标,将下标+1,即可获得序号。

为了更接近 JavaScript 迭代器的语法,Vue3.0 支持用 of 替代 in 作为分隔。

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Vue3.0循环语法</title>
    <script src="vue.global.js"></script>
    <style>
        h1 {
            text-align: center;
        }

        table {
            width: 600px;
            margin: 0 auto;
            text-align: center;
            height: 200px;
        }

        td, th {
            border: 1px solid #bcbcbc;
            padding: 5px 10px;
        }

        th {
            background: #42b983;
            font-size: 1.2rem;
            font-weight: 400;
            color: #fff;
            cursor: pointer;
        }

        tr:nth-of-type(odd) {
            background: #fff;
        }

        tr:nth-of-type(even) {
            background: #eee;
        }
    </style>
</head>
<body>
<h1>vue.js 3.0 系列教程</h1>
<table id="program">
    <thead>
    <tr>
        <th>序号</th>
        <th>编程语言</th>
        <th>备注</th>
    </tr>
    </thead>
    <tr v-for="(item,index) of items">
        <td>{{ index + 1 }}</td>
        <td>{{ item.lang }}</td>
        <td>{{ item.remark }}</td>
    </tr>
</table>

<script>
    Vue.createApp({
        data() {
            return {
                items: [
                    {lang: 'Python', remark: '入门、数据分析、爬虫'},
                    {lang: '前端', remark: '网页三贱客'},
                    {lang: 'Vue3.0', remark: '能在项目中应用'},
                    {lang: 'Koa2', remark: '企业实战项目'},
                    {lang: 'Java', remark: '从0开始入门'},
                    {lang: 'App', remark: '安卓和iOS等开发'}]
            }
        }
    }).mount("#program")
</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

# 3 v-for 和 v-if

由于当 v-if 和 v-for 处于同一节点时,v-if 的优先级比 v-for 更高,这意味着 v-if 将没有权限访问 v-for 里的变量,就是说不可以将 v-if 和 v-for 放在同一个元素里。

<!-- v-for 和 v-if 不可以放在同一个元素内 -->
<li v-for="item in items" v-if="item==true">
    {{ good }}
</li>
1
2
3
4

为了解决 v-for 和 v-if 同一水平的问题,你可以把 v-for 移动到 <template> 标签中进行修正。就是将 v-if 放到 v-for 内部去的意思。

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Vue3.0循环语法</title>
    <script src="vue.global.js"></script>
    <style>
        h1 {
            text-align: center;
            color: darkorange;
        }

        table {
            width: 600px;
            margin: 0 auto;
            text-align: center;
            height: 200px;
        }

        td, th {
            border: 1px solid #bcbcbc;
            padding: 5px 10px;
        }

        th {
            background: #42b983;
            font-size: 1.2rem;
            font-weight: 400;
            color: #fff;
            cursor: pointer;
        }

        tr:nth-of-type(odd) {
            background: #fff;
        }

        tr:nth-of-type(even) {
            background: #eee;
        }
    </style>
</head>
<body>
<h1>Vue.js 3.0 系列教程</h1>
<table id="program">
    <thead>
    <tr>
        <th>序号</th>
        <th>编程语言</th>
        <th>完成情况</th>
    </tr>
    </thead>
    <template v-for="(item,index) in items">
        <tr>
            <td>
                {{ index + 1 }}
            </td>
            <td>
                {{ item.lang }}
            </td>
            <td>
                <span v-if="item.todo==1">
                    已完成
                </span>
                <span v-else-if="item.todo==2">
                 进行中
                </span>
                <span v-else>
                   将启动
                </span>
            </td>
        </tr>
    </template>
</table>
<script>
    Vue.createApp({
        data() {
            return {
                items: [
                    {lang: 'Python', todo: 1,},
                    {lang: '前端', todo: 1},
                    {lang: 'Vue3.0', todo: 2},
                    {lang: 'Koa2', todo: 3},
                    {lang: 'Java', todo: 3},
                    {lang: 'App', todo: 3}]
            }
        }
    }).mount("#program")
</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

# 样式绑定

为了方便 CSS 对页面的美化,Vue3.0 特意提供了操作元素的 class 和内联样式的指令。

因为它们都是元素,所以我们可以用 v-bind(属性绑定) 进行处理。

由于字符串拼接麻烦且易错,所有 Vue3.0 在 v-bind 用于 class 和 style 时,做了专门的增强,表达式结果的类型除了字符串之外,还可以是对象或数组。

# 1 Class 指令

Vue 用 v-bind:class(简写为:class)指令,用于解决动态切换 class 的需求。

如果你不清楚用在什么哪方面的需求,就想一下提示信息的应用,在错误发生时,用红色字体,否则用绿色。

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Vue3.0 class指令</title>
    <script src="vue.global.js"></script>
    <style>
        .b {
            font-weight: bold;
        }

        .error {
            color: red;
        }
    </style>
</head>
<body>
<span id="app">
<h1 class="b" :class="{ 'error': hasError }">红色字体,好看么?</h1>
</span>
<script>
    Vue.createApp({
        data() {
            return {
                hasError: true
            }
        }
    }).mount("#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
22
23
24
25
26
27
28
29
30
31

渲染结果(生成的代码)

<h1 class="b error">红色字体,好看么?</h1>
1

思考:如何通过单击按钮来切换颜色?

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Vue3.0 class指令</title>
    <script src="vue.global.js"></script>
    <style>
        .b {
            font-weight: bold;
        }

        .error {
            color: red;
        }
    </style>
</head>
<body>
<span id="app">
    <button @click="change">改变颜色</button>
	  <h1 class="b" :class="{ 'error': hasError }">红色字体,好看么?</h1>
</span>
<script>
    Vue.createApp({
        data() {
            return {
                hasError: true
            }
        },
        methods:{
            change(){
                this.hasError = !this.hasError
            }
        }
    }).mount("#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
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

如果你想同时满足多个 class,你可以用 class 的数组语法。这个语法,可读性更强一些。

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Vue3.0 class指令</title>
    <script src="vue.global.js"></script>
    <style>
        .b {
            font-weight: bold;
        }

        .big-text {
            font-size: 60px;
        }

        .error {
            color: red;
        }
    </style>
</head>
<body>
<span id="app">
<p class="b" :class="[fontSize, errorInfo]">
    程序员<br/>
    除了会编程之外,还会什么?<br/>
    当然是敲代码了。
</p>
</span>
<script>
    Vue.createApp({
        data() {
            return {
                fontSize: 'big-text',
                errorInfo: 'error'
            }
        }
    }).mount("#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
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

渲染结果(生成的代码)

<span id="app"><p class="b big-text error"> 程序员<br> 
  除了会编程之外,还会什么?<br> 当然是敲代码了。 </p></span>
1
2

你可以用三元表达式,根据条件切换列表中的 class。

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Vue3.0 class指令</title>
    <script src="vue.global.js"></script>
    <style>
        .b {
            font-weight: bold;
            font-size: 50px;
        }

        .yes {
            color: #008CBA;
        }

        .no {
            color: red;
        }
    </style>
</head>
<body>
<span id="app">
<p class="b" :class="[isCool ? 'yes' :'no']">
    蓝色字体才好看。
</p>
</span>
<script>
    Vue.createApp({
        data() {
            return {
                isCool: true
            }
        }
    }).mount("#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
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

# 2 内联样式

在 HTML 中,在元素上用 style 的话,结果是不可改变的,为此 Vue3.0 加上了:style 指令。

注意,你别看这个指令看起来十分直观,看着非常像 CSS,但其实是一个 JavaScript 对象来的。

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Vue3.0 style指令</title>
    <script src="vue.global.js"></script>
</head>
<body>
<span id="app">
<p :style="{ color: textColor, fontSize: fontSize + 'px' }">
    程序员,都忙得跟狗一样,哈哈~
</p>
</span>
<script>
    Vue.createApp({
        data() {
            return {
                textColor: '#008CBA',
                fontSize: 50
            }
        }
    }).mount("#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
22
23
24
25

你可以用样式对象的方式。这样的写法,是不是更舒服了一些,输出结果和上面是一模一样的。

<span id="app">
<p :style="styleOj">
    程序员,都忙得跟狗一样都忙得跟狗一样,哈哈~
</p>
</span>
<script>
    Vue.createApp({
        data() {
            return {
                styleOj: {
                    color: '#008CBA',
                    fontSize: '50px'
                }
            }
        }
    }).mount("#app")
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

既然 class 可以用数组语法,:style 当然也可以。

:style 的数组语法可以将多个样式对象应用到同一个元素上。输出结果和上面的还是一样的。

<span id="app">
<p :style="[textColor, fontSize]">
    程序员,都忙得跟狗一样,哈哈~
</p>
</span>
<script>
    Vue.createApp({
        data() {
            return {
                textColor: {
                    color: '#008CBA',
                },
                fontSize: {
                    'font-size': '50px'
                }
            }
        }
    }).mount("#app")
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# Composition API 写法

以上是 Options API 的写法。在 Composition API + SFC 工程化项目中,属性绑定和条件列表渲染的写法如下。

# 属性绑定

<script setup lang="ts">
import { ref } from 'vue'
const path = ref('/src/assets/vue.svg')

</script>

<template>
  <img :src="path" alt="">
</template>
1
2
3
4
5
6
7
8
9
  • 【:属性名】用来将标签属性与【响应式】变量绑定

# 条件与列表

首先,新增模型数据 src/model/Model8080.ts

export interface Student {
  id: number;
  name: 沉梦听雨
  sex: string;
  age: number;
}

// 如果 spring 错误,返回的对象格式
export interface SpringError {
  timestamp: string,
  status: number,
  error: string,
  message: string,
  path: string
}

// 如果 spring 成功,返回 list 情况
export interface SpringList<T> {
  data: T[],
  message?: string,
  code: number
}

// 如果 spring 成功,返回 page 情况
export interface SpringPage<T> {
  data: { list: T[], total: number },
  message?: string,
  code: number
}

// 如果 spring 成功,返回 string 情况
export interface SpringString {
  data: string,
  message?: string,
  code: number
}

import { AxiosResponse } from 'axios'
export interface AxiosRespError extends AxiosResponse<SpringError> { }
export interface AxiosRespList<T> extends AxiosResponse<SpringList<T>> { }
export interface AxiosRespPage<T> extends AxiosResponse<SpringPage<T>> { }
export interface AxiosRespString extends AxiosResponse<SpringString> { }
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

其中

  • AxiosRespPage 代表分页时的响应类型
  • AxiosRespList 代表返回集合时的响应类型
  • AxiosRespString 代表返回字符串时的响应类型
  • AxiosRespError 代表 Spring 出错时时的响应类型
<script lang="ts" setup>
import { ref, onMounted } from "vue";
import axios from "../api/request";
import { Student, SpringList } from "../model/Model8080";

// 说明 students 数组类型为 Student[]
const students = ref<Student[]>([]);

async function getStudents() {
  // 说明 resp.data 类型是 SpringList<Student>
  const resp = await axios.get<SpringList<Student>>("/api/students");  
  console.log(resp.data.data);
  students.value = resp.data.data;
}

onMounted(() => getStudents());
</script>
<template>
  <div class="outer">
    <div class="title">学生列表</div>
    <div class="thead">
      <div class="row bold">
        <div class="col">编号</div>
        <div class="col">姓名</div>
        <div class="col">性别</div>
        <div class="col">年龄</div>
      </div>
    </div>
    <div class="tbody">
      <div v-if="students.length === 0">暂无数据</div>
      <template v-else>
        <div class="row" v-for="s of students" :key="s.id">
          <div class="col">{{ s.id }}</div>
          <div class="col">{{ s.name }}</div>
          <div class="col">{{ s.sex }}</div>
          <div class="col">{{ s.age }}</div>
        </div>
      </template>
    </div>
  </div>
</template>
<style scoped>
.outer {
  font-family: 华文行楷;
  font-size: 20px;
  width: 500px;
}

.title {
  margin-bottom: 10px;
  font-size: 30px;
  color: #333;
  text-align: center;
}

.row {
  background-color: #fff;
  display: flex;
  justify-content: center;
}

.col {
  border: 1px solid #f0f0f0;
  width: 15%;
  height: 35px;
  text-align: center;
  line-height: 35px;
}

.bold .col {
  background-color: #f1f1f1;
}
</style>
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
  • 加入泛型是为了更好的提示
  • v-if 与 v-else 不能和 v-for 处于同一标签
  • template 标签还有一个用途,就是用它少生成一层真正 html 代码
  • 可以看到将结果封装为响应式数据还是比较繁琐的,后面会使用 useRequest 改进
上次更新: 2026/11/5 11:56:09
TypeScript基础
计算属性与侦听器

← TypeScript基础 计算属性与侦听器→

Theme by Vdoing | Copyright © 2023-2026 沉梦听雨 | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式