1.声明式渲染
Vue 的核心功能是声明式渲染:简要的说,当js的状态改变时,HTML 会自动更新,也就是响应式
声明响应式状态:
- reactive:用于对象(包括数组和内置类型,如map和set)
- ref:接受任何类型,通过.value属性设置内部值
<script setup>
import { ref,reactive } from 'vue'
const counter = reactive({
count:0
})
const message = ref("Hello World")
counter.count++
</script>
<template>
<h1>Make me dynamic!</h1>
<h3>{{message}}</h3>
<p>
{{counter.count}}
</p>
</template>
2.Attribute 绑定
双大括号只能用于文本插值,如果想插入Html,需要使用V-bind
绑定规则:
同名简写
如果 attribute 的名称与绑定的 JavaScript 值的名称相同,那么可以进一步简化语法,省略 attribute 值:
<!-- 与 :id="id" 相同 -->
<div :id></div>
<!-- 这也同样有效 -->
<div v-bind:id></div>
布尔型 Attribute
布尔型根据true/false的值来决定Attribute是否应该在元素上,典型应用是disable
<button :disabled="isButtonDisabled">Button</button>
当isButtonDisabled为真或一个字符串时,则该元素的disabled值为true 如果为假,则为false
动态绑定多个值
如果你有像这样的一个包含多个 attribute 的 JavaScript 对象:
const objectOfAttrs = {
id: 'container',
class: 'wrapper',
style: 'background-color:green'
}
<div v-bind="objectOfAttrs"></div>
使用 JavaScript 表达式
调用函数
可以在绑定的表达式中使用一个组件暴露的方法:
<time :title="toTitleDate(date)" :datetime="date">
{{ formatDate(date) }}
</time>
指令
指令是带有 v- 前缀的特殊 attribute,如 v-bind 和 v-html。
v-if
<p v-if="seen">Now you see me</p>
v-if会基于seen的值的真假来移除/插入该p元素
参数
:href
某些指令会需要一个“参数”,在指令名后通过一个冒号隔开做标识。例如用 v-bind 指令来响应式地更新一个 HTML attribute:
<a v-bind:href="url"> ... </a>
<!-- 简写 -->
<a :href="url"> ... </a>
这里 href 就是一个参数,它告诉 v-bind 指令将表达式 url 的值绑定到元素的 href attribute 上。
@click
v-on指令:监听Dom事件:
<a v-on:click="doSomething"> ... </a>
<!-- 简写 -->
<a @click="doSomething"> ... </a>
这里的参数是要监听的事件名称:click。v-on 有一个相应的缩写,即 @ 字符
动态参数
同样在指令参数上也可以使用一个 JavaScript 表达式,需要包含在一对方括号内:
<!--
注意,参数表达式有一些约束,
参见下面“动态参数值的限制”与“动态参数语法的限制”章节的解释
-->
<a v-bind:[attributeName]="url"> ... </a>
<!-- 简写 -->
<a :[attributeName]="url"> ... </a>
这里的 attributeName 会作为一个 JavaScript 表达式被动态执行,计算得到的值会被用作最终的参数。举例来说,如果你的组件实例有一个数据属性 attributeName,其值为 "href",那么这个绑定就等价于 v-bind:href。
动态参数中表达式的值应当是一个字符串,或者是 null。特殊值 null 意为显式移除该绑定。其他非字符串的值会触发警告。
修饰符 Modifiers
修饰符是以点开头的特殊后缀,表明指令需要以一些特殊的方式被绑定。例如 .prevent 修饰符会告知 v-on 指令对触发的事件调用 event.preventDefault():
<form @submit.prevent="onSubmit">...</form>
总结
冒号后面的部分 (:id) 是指令的“参数”。此处,元素的 id attribute 将与组件状态里的 dynamicId 属性保持同步。
由于 v-bind 使用地非常频繁,它有一个专门的简写语法:
<div :id="dynamicId"></div>
例子:
<script setup>
import { ref } from 'vue'
const titleClass = ref('title')
</script>
<template>
<h1 :class="titleClass">Make me red</h1> <!-- 此处添加一个动态 class 绑定 -->
</template>
<style>
.title {
color: red;
}
</style>
事件监听
我们可以使用 v-on 指令监听 DOM 事件:
<button v-on:click="increment">{{ count }}</button>
<!-- 或者 -->
<button @click="increment">{{ count }}</button>
此处,increment 引用了一个在 <script setup> 中声明的函数:
<script setup>
import { ref } from 'vue'
const count = ref(0)
function increment() {
// 更新组件状态
count.value++
}
</script>
例子:
<script setup>
import { ref } from 'vue'
const count = ref(0)
function increment(){
count.value ++
}
</script>
<template>
<!-- 使此按钮生效 -->
<button @click="increment">Count is: {{ count }}</button>
</template>
表单绑定
我们可以同时使用 v-bind 和 v-on 来在表单的输入元素上创建双向绑定:
<input :value="text" @input="onInput">
function onInput(e) {
// v-on 处理函数会接收原生 DOM 事件
// 作为其参数。
text.value = e.target.value
}
例子:
<script setup>
import { ref } from 'vue'
const text = ref('')
function onInput(e) {
text.value = e.target.value
}
</script>
<template>
<input :value="text" @input="onInput" placeholder="Type here">
<p>{{ text }}</p>
</template>
为了简化双向绑定,vue提供了v-model语法糖
<input v-model="text">
v-model 会将被绑定的值与 <input> 的值自动同步,这样我们就不必再使用事件处理函数了。
v-model 不仅支持文本输入框,也支持诸如多选框、单选框、下拉框之类的输入类型
<script setup>
import { ref } from 'vue'
const text = ref('')
</script>
<template>
<input v-model="text" placeholder="Type here">
<p>{{ text }}</p>
</template>
条件渲染
我们可以使用 v-if 指令来有条件地渲染元素:
<h1 v-if="awesome">Vue is awesome!</h1>
awesome为真值时,渲染h1 awesome为假值时,从dom中移除h1
我们也可以使用 v-else 和 v-else-if 来表示其他的条件分支:
<h1 v-if="awesome">Vue is awesome!</h1>
<h1 v-else>Oh no 😢</h1>
示例:
<script setup>
import { ref } from 'vue'
const awesome = ref(true)
function toggle() {
// ...
awesome.value = !awesome.value
}
</script>
<template>
<button @click="toggle">Toggle</button>
<h1 v-if="awesome">Vue is awesome!</h1>
<h1 v-else>Oh no 😢</h1>
</template>
列表渲染
我们可以使用 v-for 指令来渲染一个基于源数组的列表:
<ul>
<li v-for="todo in todos" :key="todo.id">
{{ todo.text }}
</li>
</ul>
todo:局部变量,表示当前正在迭代的数组元素,只能在v-for绑定的元素或其内部访问,就像函数的作用域 id:给每个todo对象设置的唯一值,将它作为特殊的key Attribute绑定到每个
更新列表的两种方法:
- 在源数组上调用变更方法
todos.value.push(newTodo)
- 使用新的数组替代原数组:
todos.value = todos.value.filter(/* ... */)
示例:
<script setup>
import { ref } from 'vue'
// 给每个 todo 对象一个唯一的 id
let id = 0
const newTodo = ref('')
const todos = ref([
{ id: id++, text: 'Learn HTML' },
{ id: id++, text: 'Learn JavaScript' },
{ id: id++, text: 'Learn Vue' }
])
function addTodo() {
// ...
todos.value.push({id: id++, text:newTodo.value})
newTodo.value = ''
}
function removeTodo(todo) {
// ...
todos.value = todos.value.filter((t) => t !== todo)
}
</script>
<template>
<form @submit.prevent="addTodo">
<input v-model="newTodo" required placeholder="new todo">
<button>Add Todo</button>
</form>
<ul>
<li v-for="todo in todos" :key="todo.id">
{{ todo.text }}
<button @click="removeTodo(todo)">X</button>
</li>
</ul>
</template>