数据显示
文本插值 {{ }}
- 插值符
{{ }}
里面可以写 JS 表达式
Vue2
-
插值符
{{ }}
可以直接获取 data 中的数据实际上,
{{ }}
中能直接获取 Vue 实例的所有属性
<body>
<div id="app">
<p>msg: {{`${msg}!!!`}}</p>
</div>
</body>
<!-- vue2 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.10/dist/vue.js"></script>
<script>
let vm = new Vue({
el: "#app",
data: { msg: "superman" }
});
</script>
Vue3
<template>
<h1>{{ message }}</h1>
</template>
<script setup lang="ts">
import { ref } from "vue";
const message = ref<string>("Hello World!");
</script>
v-cloak
& 闪动问题
- 闪动问题:网速较慢时,
{{ }}
渲染的数据可能还没加载出来,就会先显示源码。待加载好了,再显示数据 v-cloak
:用于解决{{ }}
闪动问题;
原理:先将标签元素隐藏,待 Vue 实例创建完成,再显示内容- 本质是一个特殊属性,Vue 实例创建完毕并接管容器后 会自动删掉该属性
<!-- 在标签元素中设置 v-cloak 属性 -->
<p v-clock>msg: {{`${msg}!!!`}}</p>
/* 配合 CSS 使用,使用属性选择器 */
[v-cloak] {
display: none;
}
- 如果把引入 Vue 的 script 标签放到 head 标签内:先加载 script 标签、再渲染页面,也不会出现闪动问题
- 使用脚手架的话,也不会出现闪动问题
v-text
& v-html
v-text
:v-text
指令值会替换掉标签元素里面的内容,且不会出现闪动问题;不会解析内容中的 HTML 代码v-html
:v-html
指令值会替换掉标签元素里面的内容,且不会出现闪动问题;会解析内容中的 HTML 代码
<p v-text="msg"></p>
<p v-html="msg"></p>
|
<p v-text="html"></p>
<p v-html="html"></p>
new Vue({
el: '#app',
data: {
msg: "hello world1",
html: '<a href="https://www.baidu.com/">点击跳转百度</a>'
}
});
v-html
、v-text
的属性值可以是表达式
<!-- 使用表达式作为 v-html 的属性值 -->
<div v-html="num >= 18 ? ele1 : ele2">
<h1>大哥</h1>
</div>
new Vue({
el: "#app",
data: {
num: 19,
ele1: "<h2>已成年</h2>",
ele2: "<h2>尚未成年</h2>",
}
});
- 在网站上动态渲染 HTML 是非常危险的,因为容易导致 XSS 攻击;
v-html
只用在可信内容上,永远不要用在用户提交的内容上
v-once
v-once
:设置该属性的标签,为静态标签,初次渲染完毕后,内容不再改变
<p v-once>{{num}}</p>
<button @click.once="change">点击</button>
let vm = new Vue({
el: "#app",
data: { num: 100 },
methods: {
change() {
console.log("事件已触发!");
console.log(++this.num);;
}
}
});
可以发现,点击按钮后,执行事件函数、更新数据,但页面不会再重新渲染
v-pre
v-pre
:跳过当前元素及其子元素的编译过程- 给没有使用 Vue 语法的标签元素设置,可以稍微加快编译速度 ~
<!-- 里面写什么就显示什么,不会进行编译操作 -->
<p v-pre> {{ msg }} </p>
属性绑定 v-bind
v-bind:属性="值"
,可简写为:属性="值"
- 使用属性绑定后,
"值"
不再是字符串,""
里面可以写任何 JS 表达式 - 使用属性绑定后,
""
里面可以直接获取 data 中的数据(Vue 的属性都可直接获取)
普通属性
.redBg {
background: rgb(253, 167, 167);
}
.blueBg {
background: rgb(153, 180, 255);
}
div {
width: 200px;
height: 100px;
margin: 2px;
}
<div id="app">
<!-- ① v-bind:属性="值" -->
<div v-bind:class='value'>v-bind:class='value'</div>
<!-- ② :属性="值" -->
<div :class='value'>:class='value'</div>
<!-- ③ 属性值可以是字符串 -->
<div :class='"redBg"'>:class='"bgR"'</div>
<!-- ④ 属性值也可以写表达式 -->
<div :class='isOk ? "redBg" : "blueBg"'></div>
</div>
let vm = new Vue({
el: "#app",
data: {
value: "redBg", // ① ②
isOk: false, // ④
},
});
- 除了系统属性,我们也可以设置自定义属性:
<div id="app">
<!-- 设置 name 属性,属性值为 superman -->
<div :[key]='"superman"'>:[key]='"superman"'</div>
<div :name='value'>:my-name='value'</div>
</div>
let vm = new Vue({
el: "#app",
data: {
key: "name",
value: "superman",
},
});
class
因为 class 属性可以设置多个属性值,所以属性值可以为对象 / 数组
.red {
color: red;
}
.green {
color: green;
}
.yellow {
background-color: yellow;
}
<!-- 通过原生 JS 设置 class -->
<p class="red">原生 JS</p>
<!-- 通过 `v-bind` 绑定 class 属性,属性值为字符串 -->
<p :class="vGreen">string</p>
<!-- 原生 JS 设置的 class 与 `v-bind` 绑定的 class 会合并 -->
<p class="red" :class="vYellow">string</p>
let vm = new Vue({
el: "#app",
data: {
vGreen: "green",
vYellow: "yellow"
}
});
<!-- 原生 JS:设置多个 class -->
<p class="red yellow">多个类名</p>
<!-- 通过 `v-bind` 绑定 class 属性,属性值为数组 -->
<p :class="[vRed]">array</p>
<p :class="[vRed, vYellow]">array</p>
<p :class="arr">array</p>
let vm = new Vue({
el: "#app",
data() {
return {
vYellow: "yellow",
vRed: "red",
arr: ["red", "yellow"]
};
}
});
<!-- 单个 class -->
<p :class="{red: vRed}">object</p>
<!-- 多个 class -->
<p :class="{red: vRed, yellow: vYellow}">object</p>
<p :class="obj">object</p>
let vm = new Vue({
el: "#app",
data: {
vRed: true,
vYellow: true,
obj: {
red: true,
yellow: true,
}
}
});
style
因为 style 属性可以设置多个属性值,所以属性值可以为对象 / 数组
<p style="color: red">原始 JS</p>
<p :style="vRed">string</p>
let vm = new Vue({
el: "#app",
data: {
vRed: "color: red"
}
});
<p :style="{fontSize: vFontSize, color: vRed}">object</p>
<p :style="styleObj">object</p>
let vm = new Vue({
el: "#app",
data: {
vRed: "red",
vFontSize: '50px',
styleObj: {
fontSize: "50px",
color: "red"
}
}
});
<div id="app">
<p :style="[styleObj1, styleObj2]">object</p>
</div>
let vm = new Vue({
el: "#app",
data: {
styleObj1: {
fontSize: "50px",
color: "red"
},
styleObj2: {
backgroundColor: "yellow",
}
}
});
- 那你是不是可以直接在 data 里面写
styleArr: [{...}, {...}]
? 自己试~
双向绑定 v-model
v-model:value="值"
可简写为v-model="值"
,用于双向绑定 [表单] 的数据- 双向绑定:更新表单的 value,data 中的数据也会更新;更新 data 中的数据,表单的 value 也会更新
- 本质上,v-model 是由 v-bind 配合 input 事件实现的
① v-bind 绑定 value 属性、② 在 input 事件的回调函数中,修改 value 的值
文本 input [text]
<div id="app">
<p>Message is: {{ msg }}</p>
<!-- 给 input 标签元素设置 v-model 属性 -->
<input v-model="msg" type="text">
</div>
let vm = new Vue({
el: "#app",
data: { msg: "superman" }
});
上例中,input 的默认值为 data 中的 msg,更新 input 的 value 值 → msg 也会被更新 → p 显示的内容也会被更新
多行文本 textarea
- 对于文本域标签
<textarea>
,用法与 type=“text” 的 input 标签一样 - 虽然
<textarea>
是双标签,但<textarea> {{msg}} </textarea>
并不会生效,要设置v-model
属性来替代
<textarea v-model="msg"></textarea>
单选框 input [radio]
-
因为 v-model 绑定的是 value 值
所以,我们需要设置
value
属性;如果没有设置value
属性,则获取到的值为null
<input type="radio" id="male" value="male" v-model="sex">
<label for="male">male</label>
<br>
<input type="radio" id="female" value="female" v-model="sex">
<label for="female">female</label>
<br>
<span>sex: {{ sex }}</span>
let vm = new Vue({
el: "#app",
data: {
sex: ""
// sex: "male" // 设置默认值 'male',默认选中 male 选项
}
});
复选框 input [checkbox]
- 没有配置
value
属性,收集的是 checkbox 的checked
状态,所以会收集到布尔值
<input type="checkbox" id="checkbox" v-model="checked">
<label for="checkbox">{{checked}}</label>
let vm = new Vue({
el: "#app",
data: { checked: true } // 绑定 [布尔值]
});
- 配置了
value
属性,绑定 [非数组],收集的也还是 checkbox 的checked
状态
所以也还是会收集到布尔值 →ture
-全选、false
-全不选
篮球<input type="checkbox" value="篮球" v-model="checked">
足球<input type="checkbox" value="足球" v-model="checked">
网球<input type="checkbox" value="网球" v-model="checked">
<p>{{checked}}</p>
- 配置了
value
属性,绑定 [数组],才能收集到多选框的value
值
篮球<input type="checkbox" value="篮球" v-model="checked">
足球<input type="checkbox" value="足球" v-model="checked">
网球<input type="checkbox" value="网球" v-model="checked">
<p>{{checked}}</p>
let vm = new Vue({
el: "#app",
data: {
checked: [] // 绑定到数组
}
});
- 能获取到多个值的表单元素,都应该绑定 [数组],以存储多个数据
选择框 select > option
- 对于下拉菜单,推荐提供一个值为空的禁用选项,作为默认显示选项
<select v-model="selected">
<option disabled value="">国家</option>
<option value="China">中国</option>
<option value="America">美国</option>
<option value="Japan">日本</option>
</select>
<span>Selected: {{ selected }}</span>
let vm = new Vue({
el: "#app",
data: {
selected: ""
// selected: "China" // 设置默认值
}
});
- 如果
option
标签不设置value
属性,则获取到的是option
标签的内容
<select v-model="selected">
<option disabled value="">国家</option>
<option>中国</option>
<option>美国</option>
<option>日本</option>
</select>
<span>Selected: {{ selected }}</span>
- 多选时,绑定到一个数组
<select multiple v-model="selected">
<option disabled value="">国家</option>
<option>中国</option>
<option>美国</option>
<option>日本</option>
</select>
<span>Selected: {{ selected }}</span>
let vm = new Vue({
el: "#app",
data: {
selected: [] // 绑定到数组
}
});
标签修饰符
.lazy
:在change
事件之后同步,即失焦再同步(默认input
事件之后同步,即一边写一边同步).trim
:过滤首尾空白字符.number
:将获取到的数据转为 number 类型,如果这个值无法被parseFloat()
解析,则会返回数字前缀
<input type="text" v-model.lazy="username" />
<span>{{username}}</span><br>
<input type="text" v-model.trim="password" />
<span>{{password}}</span><br>
<!-- type="number" 控制 input 只能输入数字,但传给 Vue 的数据还是字符串格式的 -->
<!-- v-model.number="age" 将数据转为 Number 类型 -->
<input type="number" v-model.number="age" />
<span>{{age}}</span><br>
let vm = new Vue({
el: "#app",
data: {
username: "",
password: "",
age: ""
}
});
表单提交事件
submit
提交表单时触发.prevent
阻止默认行为
<form @submit.prevent="console.log('submit successfully')"></form>
说白了,使用 Vue 后,我们不用直接操作 DOM~ 我们操作 Vue,Vue 帮我们操作 DOM~