大学生涯vueVue学习笔记(一)
Jie模板语法
Vue 使用一种基于 HTML 的模板语法,使我们能够声明式地将其组件实例的数据绑定到呈现的 DOM 上。所有的 Vue 模板都是语法层面合法的 HTML,可以被符合规范的浏览器和 HTML 解析器解析。
文本插值
最基本的数据绑定形式是文本插值,它使用的是“Mustache”语法(即双大括号):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <script> export default { name: 'hello' data() { return { msg: "神奇的语法", hello: "Hello World" } } } </script>
<template> <h3>模板语法</h3> <p>{{ msg }}</p> <p>{{ hello }}</p> </template>
|
使用 JavaScript 表达式
每个绑定仅支持单一表达式,也就是一段能够被求值的 JavaScript 代码。一个简单的判断方法是否可以合法地写在return后面。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| <script> export default { name: "HelloWorld", data() { return { msg: "神奇的语法", number: 10, ok: true, message: "大家好" } } } </script>
<template> <h3>模板语法</h3> <p>{{ msg }}</p> <p>{{ number + 1 }}</p> <p>{{ ok ? 'Yes' : 'No' }}</p> <p>{{ message.split('').reverse().join('') }}</p> </template>
|
注意
以下这些表达式会在当前活动实例的数据作用域下作为 JavaScript 被解析。有个限制就是,每个绑定都只能包含单个表达式,所以下面的例子都不会生效。
1 2 3 4 5
| <!-- 这是语句,不是表达式:--> {{ var a = 1 }}
<!-- 流程控制也不会生效,请使用三元表达式 --> {{ if (ok) { return message } }}
|
原始 HTML
双大括号将会将数据插值为纯文本,而不是 HTML。若想插入 HTML,需要使用 v-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
| <script> export default { name: "HelloWorld", data() { return { msg: "神奇的语法", number: 10, ok: true, message: "大家好", rawHtml: "<a href='https://www.baidu.com'>百度</a>", } } } </script>
<template> <h3>模板语法</h3> <p>{{ msg }}</p> <p>{{ number + 1 }}</p> <p>{{ ok ? 'Yes' : 'No' }}</p> <p>{{ message.split('').reverse().join('') }}</p> <p>{{ rawHtml }}</p> <p v-html="rawHtml"></p> </template>
|
运行截图:
属性绑定
双大括号不能再 HTML attributes 中使用。想要响应式地绑定一个 attributte,应该使用 v-bind
指令
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| <script> export default { data() { return { dynamicClass: "appclass", dynamicId: "appId", dynamicTitle: null } } } </script>
<template> <div v-bind:id="dynamicId" v-bind:class="dynamicClass" v-bind:title="dynamicTitle">测试</div> </template>
<style>
.appclass{ color: red; font-size: 30px; } </style>
|
v-bind
指令指示 Vue 将元素的 id
attribute 与组件的 dybanucId
属性保持一致。如果绑定的值是 null
或者 undefined
,那么该 attribute 将会从渲染的的元素上移除。
简写
因为 v-bind
非常常用,我们提供了特定的简写语法 :
,即直接将 v-bind
省去
1
| <div :id="dynamicId" :class="dynamicClass" :title="dynamicTitle">测试</div>
|
布尔型 attribute
布尔型 attribute 依据 true/false 值来决定 attribute 是否应该存在于该元素上,disabled
就是最常见的例子之一。
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
| <script> export default { data() { return { dynamicClass: "appclass", dynamicId: "appId", dynamicTitle: undefined, isButtonDisabled: false } } } </script>
<template> <div :id="dynamicId" :class="dynamicClass" :title="dynamicTitle">测试</div> <button :disabled="isButtonDisabled">Button</button> </template>
<style>
.appclass{ color: red; font-size: 30px; } </style>
|
动态绑定多个值
如果你有像这样的一个包含多个 attribute 的 JavaScript 对象
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
| <script> export default { data() { return { dynamicClass: "appclass", dynamicId: "appId", dynamicTitle: undefined, isButtonDisabled: false, objectOfAttrs: { id: "appId", class: "appclass" } } } } </script>
<template> <div :id="dynamicId" :class="dynamicClass" :title="dynamicTitle">测试1</div> <button :disabled="isButtonDisabled">Button</button> <div v-bind:="objectOfAttrs">测试2</div> </template>
<style>
.appclass{ color: red; font-size: 30px; } </style>
|
条件渲染
在 Vue
中,提供了条件渲染,这类似于 JavaScript
中的条件语句。
v-if
v-else
v-else-if
v-show
v-if
v-if
指令用于条件性地渲染一块内容。这块内容只会在指令的表达式返回 true
值的时候被渲染。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <script> export default { data() { return { flag: true } } } </script>
<template> <h3>条件渲染</h3> <div v-if="flag">你能看见我吗</div> </template>
|
v-else
你可以使用 v-else
指令来表示 v-if
的“else 块”
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <script> export default { data() { return { flag: false } } } </script>
<template> <h3>条件渲染</h3> <div v-if="flag">你能看见我吗</div> <div v-else>那你还是看看我吧!</div> </template>
|
v-else-if
顾名思义,v-else-if
提供的是相应于 v-if
的 else if 区块。它可以连续多次重复使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <script> export default { data() { return { flag: false, type: "D", } } } </script>
<template> <h3>条件渲染</h3> <div v-if="flag">你能看见我吗</div> <div v-else>那你还是看看我吧!</div> <div v-if="type==='A'">A</div> <div v-else-if="type==='B'">B</div> <div v-else-if="type==='C'">C</div> <div v-else>Not A/B/C</div> </template>
|
v-show
另一个用于条件性展示元素的选项是 v-show
指令
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| <script> export default { data() { return { flag: true, type: "D", } } } </script>
<template> <h3>条件渲染</h3> <div v-if="flag">你能看见我吗</div> <div v-else>那你还是看看我吧!</div> <div v-if="type==='A'">A</div> <div v-else-if="type==='B'">B</div> <div v-else-if="type==='C'">C</div> <div v-else>Not A/B/C</div> <div v-show="flag">你可以看看我吗?</div> </template>
|
v-if
vs v-show
的区别
v-if
是“真正”的条件渲染,因为它会确保在切换过程中,条件块内的事件监听器和子组件适当地被销毁和重建。
v-if
也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。
相比之下,v-show
就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。
一般来说,v-if
有更高的切换开销,而 v-show
有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show
较好;如果在运行时条件很少改变,则使用 v-if
较好
列表渲染
我们可以用 v-for
指令基于一个数组来渲染一个列表。v-for
指令需要使用 item in items
形式的特殊语法,其中 items 是源数据数组,而 item
则是被迭代的数组元素的别名。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <script> export default { data() { return{ names: ["潘家辉","大佬","真强","!"] } } } </script>
<template> <h3>列表渲染</h3> <p v-for="item in names">{{ item }}</p> </template>
|
复杂数据
大多数情况下,我们渲染的数据源来于网络请求,也就是 JSON
格式。
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
| <script> export default { data() { return{ names: ["潘家辉","大佬","真强","!"], result: [{ "id": 2261677, "name": "我不是药神", "score": 9.7, "release_date": "2018-07-05", "cover_url": "https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2561305377.jpg" }, { "id": 26752088, "name": "疯狂动物城", "score": 9.2, "release_date": "2016-03-04", "cover_url": "https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2315672647.jpg" }, { "id": 1295644, "name": "阿甘正传", "score": 9.4, "release_date": "1994-06-23", "cover_url": "https://img3.doubanio.com/view/photo/s_ratio_poster/public/p510876377.jpg" }], } } } </script>
<template> <h3>列表渲染</h3> <p v-for="item in names">{{ item }}</p> <div v-for="item in result"> <p>{{ item.name }}</p> <p>{{ item.score }}</p> <p>{{ item.release_date }}</p> <img :src="item.cover_url" alt="tu"> </div> </template>
|
v-for
也支持使用可选的第二个参数表示当前项的位置索引
1 2 3
| <p v-for="(item,index) in names"> {{ item }}-{{ index }} </p>
|
也可以使用 of
作为分隔符来替代 in
,这更接近 JavaScript 的迭代器语法
1 2 3
| <p v-for="(item,index) of names"> {{ item }}-{{ index }} </p>
|
v-for 与对象
也可以使用 v-for
来遍历一个对象的所有属性。
1 2 3 4 5 6 7 8
| userInfo: { name: "潘家辉", age: 18, sex: "男" } <div> <p v-for="(value,key,index) of userInfo">{{ value }}-{{ key }}-{{ index }}</p> </div>
|
运行截图
补充-通过 key 管理状态
当 Vue 正在更新使用 v-for
渲染的元素列表时,它默认使用“就地更新”的策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序,而是就地更新每个元素,并且确保它们在每个索引位置正确渲染。
为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一的 key
attribute:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <script> export default { data(){ return{ names: ['Alice', 'Bob', 'Cathy'] } } } </script>
<template> <h3>Key属性添加到v-for中</h3> <p v-for="(item,index) in names" :key="index">{{ item }}</p> </template>
|
温馨提示
key
在这里是通过一个 v-bind
绑定的特殊 attribute。- 推荐在任何可行的时候为
v-for
提供一个 key
attribute。 key
绑定的值期望是一个基础类型的值,例如字符串或 number 类型。
key 的来源
不要使用 index
作为 key
的值,我们要确保每一条数据的唯一索引不会发生变化。
一般使用数据库的唯一 id