1、文本插值(双大括号)
这是最基本的数据绑定形式,双大括号的msg即为脚本中的msg的值。
<template>
<div>
{{ msg }}
</div>
</template>
<script setup>
let msg = '我是提示信息';
</script>
如果绑定的响应式数据,那么脚本中的数据发生变化,dom的相关内容会重新渲染。
<template>
<div>
{{ msg }}
</div>
<button @click="changeMsg"> 改变msg</button>
</template>
<script setup>
import {ref} from 'vue';
const msg = ref('这是提示信息');
const changeMsg = ()=>{
msg.value = '这是修改之后的值';
}
</script>
2、文本插值(v-text)
v-text 的指令与双大括号的用法基本一致,仅仅是写法上不同。
<template>
<span v-text="msg"></span>
<button @click="changeMsg"> 改变msg</button>
</template>
<script setup>
import {ref} from 'vue';
const msg = ref('这是提示信息');
const changeMsg = ()=>{
msg.value = '这是修改之后的值';
}
</script>
3、html插值(v-html)
文本插值是不会解析html代码的,即便文本中有标签,渲染到了dom也会原样展示。要想插值内容解析html代码,就需要用到 v-html 指令
<template>
<span v-html="msg"></span>
<button @click="changeMsg"> 改变msg</button>
</template>
<script setup>
import {ref} from 'vue';
const msg = ref('<p style="color:red">我是红色字体</p>');
const changeMsg = ()=>{
msg.value = '<b>这是修改之后粗体</b>';
}
</script>
4、元素绑定(v-bind)
给元素绑定上一个响应式变量,可以使用脚本灵活修改dom的元素。如果绑定上一个null或者undifined,那么该元素会从元素上面移除。
4.1、写法
v-bing:attribute
attribute为你需要绑定的元素。
如,绑定id
<div v-bind:id="dynamicId"></div>
绑定class
<div v-bind:class="dynamicClass"></div>
绑定disabled
<div :disabled="true"></div>
v-bind可以简写:使用冒号
<template>
<!-- v-bind的写法 -->
<div v-bind:id="myId"></div>
<!-- 简写写法 -->
<div :id="myid2"></div>
</template>
<script setup>
import { ref } from 'vue';
const myId = ref('d1');
const myid2 = ref('d2');
</script>
在控制台中的表现如图,dom已经将 脚本中的变量值 渲染给了div的id属性。
4.2、用法
绑定动态class,可灵活改变样式
<template>
<div :class="myclass" style="width: 200px;height: 200px;">
</div>
<button @click="setY">圆角样式</button>
<button @click="setB">边框样式</button>
<button @click="setBj">背景颜色样式</button>
</template>
<script setup>
import { ref } from 'vue';
const myclass = ref('setBorder');
const setY = ()=>{
myclass.value = 'setRound'
}
const setB = ()=>{
myclass.value = 'setBorder'
}
const setBj = ()=>{
myclass.value = 'setBackgound'
}
</script>
<style>
.setBorder {
border: 1px solid;
}
.setBackgound{
background-color: aqua;
}
.setRound{
border: 1px solid;
border-radius: 50%;
}
</style>
给元素属性绑定布尔值,决定是否渲染该属性。
例:给输入框设置动态的disabled。
<template>
<input type="text" :disabled="isShow">
<button @click="setD">是否禁用</button>
</template>
<script setup>
import { ref } from 'vue';
const isShow = ref(true);
const setD = ()=>{
isShow.value = isShow.value?false:true;
}
</script>
4.3、绑定多个属性
前面的写法是绑定一个变量字符串。
v-bind也可以绑定一个对象,对象的属性和值即为元素的属性和属性值
<template>
<div v-bind="myAtt">
</div>
</template>
<script setup>
import { ref } from 'vue';
const myAtt = ref({
id: 'myId',
class: 'myClass',
})
</script>
通过控制台观察div的属性:
5、v-if
v-if 可以绑定一个布尔值,根据绑定的值来决定是否渲染该元素
<template>
<div v-if="ok">
这是一段文本
</div>
<button @click="ok = ok ? false : true">显示/隐藏</button>
</template>
<script setup>
import { ref } from 'vue';
const ok = ref(true);
</script>
使用了v-if的元素后面可以使用v-else,或者继续v-else-if来配合控制
<template>
<!-- 如果ok为真的话,显示下面的元素 -->
<div v-if="ok">
这是一段文本: ok为真
</div>
<!-- 如果ok为假的话,显示下面的元素 -->
<div v-else>
这是一段文本:ok为假
</div>
<button @click="ok = ok ? false : true">显示/隐藏</button>
</template>
<script setup>
import { ref } from 'vue';
const ok = ref(true);
</script>
6、v-show
v-show通过绑定一个布尔值来决定是否显示该内容
v-if 和 v-show 的区别
实现原理不同:
v-if 指令会动态地创建或移除 DOM 元素,从而控制元素在页面上的显示与隐藏;
v-show 指令会动态为元素添加或移除 style=“display: none;” 样式,从而控制元素的显示与隐藏;
性能消耗不同:
v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此:
如果需要非常频繁地切换,则使用 v-show 较好
如果在运行时条件很少改变,则使用 v-if 较好
7、v-for
v-for可以绑定可遍历的数据结构(对象、数组,字符串等),将其元素依次渲染到相同的标签当中。
语法:
- v-for = “(值 , 索引)in 目标元素”
- v-for = "值 in 目标结构"
使用v-for,一般需要补充:key="index",index为子元素的唯一值。有:key和没有:key的算法不一样,有:key的性能更好。
将数组渲染到列表:
<template>
<ul>
<li v-for="item,index in arr" :key="index">
{{ item }}
</li>
</ul>
</template>
<script setup>
import { ref } from 'vue';
const arr = ref(['三国演义', '水浒传', '红楼梦', '西游记']);
</script>
将对象渲染到列表:
<template>
<ul>
<li v-for="item,index in obj" :key="index">
{{ index+":"+item }}
</li>
</ul>
</template>
<script setup>
import { ref } from 'vue';
const obj = ref({
name:'张三',
age:18,
id: 10010
});
</script>
8、v-on
绑定事件的指令,可以简写为@
7.1、基础用法
- 绑定点击事件:v-on:click 或@click
- 绑定改变事件:v-on:change或 @change
- 绑定失焦事件:v-on:focus 或 @focus
- ……
元素绑定一个点击事件
<template>
<button @click="clickMe">点我</button>
</template>
<script setup>
const clickMe = ()=>{
console.log('点击事件触发了……');
}
</script>
7.2、事件修饰符
- .stop 停止事件冒泡
- .prevent 阻止事件默认行为
- .capture 在事件捕获阶段执行事件处理函数
- .self 只当在 event.target 是当前元素自身时触发处理函数
- .once 事件处理函数执行一次后解绑
- .passive 滚动事件的默认行为 (即滚动行为) 将会立即触发 ,一般与scroll连用,能够提升移动端的性能
示例:
有两个div,包含关系(父子关系)。都绑定上了点击事件。
<template>
<div @click="clickFu" style="width: 200px;height: 200px;background-color: red;">
<div @click="clickZi" style="width: 100px;height: 100px;background-color: burlywood;">
</div>
</div>
</template>
<script setup>
const clickFu = ()=>{
console.log('父元素事件触发了……');
}
const clickZi = ()=>{
console.log('子元素事件触发了……');
}
</script>
点击子元素的时候会触发两个div的点击事件:
添加.stop阻止冒泡后:
<template>
<div @click="clickFu" style="width: 200px;height: 200px;background-color: red;">
<!-- 添加.stop后 -->
<div @click.stop="clickZi" style="width: 100px;height: 100px;background-color: burlywood;">
</div>
</div>
</template>
<script setup>
const clickFu = ()=>{
console.log('父元素事件触发了……');
}
const clickZi = ()=>{
console.log('子元素事件触发了……');
}
</script>
9、v-model
在表单输入元素或组件上创建双向绑定。
适用于:<input> <select> <textarea>以及组件
-
修饰符
- .lazy- 监听
change
事件而不是input
- .number- 将输入的合法字符串转为数字
- .trim- 移除输入内容两端空格
双向绑定的意义:通过输入框修改input的值,会将数据同步更新到dom。
<template>
<input type="text" v-model="val">
<br>
{{ '我是输入框内的值:'+ val }}
</template>
<script setup>
import {ref} from 'vue';
const val = ref('');
</script>
使用修饰符.lazy。
不使用lazy时,数据的更新时input事件。使用了lazy,数据的更新时change事件。
<template>
<input type="text" v-model.lazy="val">
<br>
{{ '我是输入框内的值:'+ val }}
</template>
<script setup>
import {ref} from 'vue';
const val = ref('');
</script>
10、其他指令
10.1、v-pre
v-pre主要用来跳过这个元素和它的子元素编译过程。可以用来显示原始的Mustache标签。跳过大量没有指令的节点加快编译。
<div id="app">
<span v-pre>{{message}}</span> //这条语句不进行编译
<span>{{message}}</span>
</div>
10.2、v-cloak
使用其他指令进行渲染的时候,如果网速过慢,会导致原本的代码加载不出来。
可以通过v-cloak指令进行预编译。
10.3、v-once
仅渲染元素和组件一次,并跳过之后的更新。
在下面的代码中,<p>标签中添加了v-once,只会在最初渲染一次message,后面的更新中不会重新渲染。
<template>
<p v-once> {{ message }}</p>
<button @click="changeW">改变文本</button>
</template>
<script setup>
import { ref } from "vue";
const message = ref('这是一段文本二')
const changeW = () => {
message.value = message.value+'1';
}
</script>
10.4、v-memo
该指令用于实现缓存,一般用于渲染海量的v-for
在下方的代码中,v-memo绑定上了 item.id === selected 。如果该等式不发生变化,那么不会重新渲染,而是使用缓存,从而提高了v-for的渲染速度。
<div v-for="item in list" :key="item.id" v-memo="[item.id === selected]">
<p>ID: {{ item.id }} - selected: {{ item.id === selected }}</p>
<p>...more child nodes</p>
</div>
10.5、v-slot
使用组件的时候的插槽名,可以缩写为#。
具体案例,拥有了组件基础才能学习。
补充说明
1、javaScript表达式用法
vue可以绑定一个变量,但其实也支持一段完整的javaScript代码。
绑定的地方可以书写一段javaScript表达式。
如计算:
<template>
{{ number + 1 }}
<span v-text="number + 100"></span>
</template>
<script setup>
import { ref } from 'vue';
const number = ref(1);
</script>
如三元表达式:
<template>
{{ ok?'yes':'no' }}
<br>
<span v-text="ok?'ok的值为true':'ok的值为false'"></span>
</template>
<script setup>
import { ref } from 'vue';
const ok = ref(true);
</script>
绑定的地方,只允许拥有返回值的表达式:
<!-- 这是一个语句,而非表达式 -->
{{ var a = 1 }}
<!-- 条件控制也不支持,请使用三元表达式 -->
{{ if (ok) { return message } }}