携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第4天,点击查看活动详情
data
data属性是传入一个函数,并且该函数需要返回一个对象
data中返回的对象会被Vue的响应式系统劫持,之后对该对象的修改或者访问都会在劫持中被处理
这也就是为什么可以在template中访问data中定义的数据,并且在data中对应数据发生改变的时候自动去修改界面
methods
methods属性是一个对象,通常我们会在这个对象中定义很多的方法
这些方法可以被绑定到模板中,并且可以使用this关键字来直接访问到data中返回的对象的属性
也就是说methods中的函数再被进行调用的时候
会通过bind方法将函数内部的this给绑定为data方法返回的那个对象的代理对象
所以methods中的方法不推荐定义为箭头函数,尤其是在函数内部需要使用this的时候
mustache语法
React使用的jsx来编写界面,所以对应的代码都是编写的类似于js的一种语法,
之后通过Babel将jsx编译成 React.createElement 函数调用
虽然vue也支持使用JSX来编写界面,但是在大多数情况下,使用基于HTML的模板语法
在模板中,允许开发者以声明式的方式将DOM和底层组件实例的数据绑定在一起
在底层的实现中,Vue将模板编译成虚拟DOM渲染函数
如果我们希望把数据显示到模板(template)中,使用最多的语法是 “Mustache”语法 (双大括号) 的文本插值
Mustache中不仅仅可以是data中的属性,也可以是一个JavaScript的表达式
<div id="app">
<!-- mustache中可以使用data和methods等中定义的属性和方法 -->
<h1>{{ count }}</h1>
<!-- mustache可以很好的和原生html结构进行结合 -->
<h2>count: {{ count }}</h2>
<!-- mustache中支持任何的合法的JS表达式 -->
<div>{{ count % 2 ? 'even' : 'odd' }}</div>
<div>{{ changeCount(10) }}</div>
</div>
<script>
Vue.createApp({
data() {
return {
count: 100
}
},
methods: {
changeCount(step) {
return this.count + step
}
},
}).mount('#app')
</script>
指令
名称 | 说明 |
---|---|
v-once | 1. v-once用于指定元素或者组件只渲染一次 2. 当数据发生变化时, 元素或者组件以及其所有的子元素 将视为静态内容 并且跳过3. 该指令可以用于性能优 |
v-memo | 1. 记住一个模板的子树。元素和组件上都可以使用 2. 该指令接收一个固定长度的数组作为依赖值进行记忆比对 3. 如果数组中的每个值都和上次渲染的时候相同,则整个该子树的更新会被跳过 4. 带有空依赖数组的 v-memo (v-memo="[]" ) 在功能上等效于 v-once |
v-text | 1. 用于更新元素的 textContent 2. v-text中的内容会覆盖掉元素原本的textContent 3. v-text没有mustache语法灵活,所以一般使用mustache语法来替换v-text |
v-html | 1. 默认情况下,如果我们展示的内容本身是 html 的,那么vue并不会对其进行特殊的解析 2. 如果我们希望这个内容被Vue可以解析出来,那么可以使用 v-html 来展示 3. 为了避免XSS攻击,请确保需要解析的html内容为安全有效的html内容 |
v-pre | 1. v-pre用于跳过元素和它的子元素的编译过程,显示原始的Mustache标签 2. 跳过不需要编译的节点,加快编译的速度 |
v-cloak | 1. 这个指令保持在元素上直到关联组件实例结束编译 2. 当元素还未被解析完成时,其对应元素会存在属性v-cloak 和 CSS 规则如 [v-cloak] { display: none } 一起用时 这个指令可以隐藏未编译的 Mustache 标签直到组件实例准备完毕 |
v-bind | v-bind用于绑定一个或多个属性值,或者向另一个组件传递props值 |
v-on | 方法的动态绑定 |
v-once
<!-- 指令可以看出是一种特殊的元素属性 -->
<div v-once>
<h1>{{ name }}</h1>
<div>{{ count }}</div>
</div>
v-memo
<div id="app">
<!-- 此时当变量name 和 age的值发生改变的时候,对应内容会更新 -->
<!-- 当height对应的值发生改变的时候,对应的内容并不会进行任何的更新 -->
<div v-memo="[name, age]">
<div>{{ name }}</div>
<div>{{ age }}</div>
<div>{{ height }}</div>
</div>
<button @click="changeName">changeName</button>
<button @click="changeHeight">changeHeight</button>
</div>
<script>
Vue.createApp({
data() {
return {
name: 'Klaus',
age: 23,
height: '1.88'
}
},
methods: {
changeName() {
this.name = 'Alex'
},
changeHeight() {
this.height = '2.00'
}
},
}).mount('#app')
</script>
v-text
<div>{{ name }}</div>
<!-- 等价于 -->
<div v-text="name"></div>
v-html
<!-- htmlContent: '<h1>this is h1 title</h1>' -->
<div v-html="htmlContent"></div>
v-pre
<div v-pre>
<h1>{{ name }}</h1>
<div>{{ count }}</div>
</div>
v-cloak
<style>
[v-cloak] {
display: none;
}
</style>
<div id="app">
<div v-cloak>{{ count }}</div>
</div>
<script>
setTimeout(() => {
Vue.createApp({
data() {
return {
count: 100
}
}
}).mount('#app')
}, 3000)
</script>
v-bind
基本使用
<img v-bind:src="imgUrl" />
<!-- v-bind 存在对应的语法糖 为 : -->
<img :src="imgUrl" />
绑定class
<!-- 普通方式进行绑定 -->
<!-- 在data选项中 -> classObj: 'active hover foo' -->
<div :class="classObj">foo</div>
<!-- class中也可以编写对应的表达式 -->
<div :class="isActive ? 'active' : ''">foo</div>
<!--
动态绑定class对应的值的结果如果为boolean类型值,那么对应的结果会自动忽略
所以这种方式的写法和三目运算符写法的作用是一致的,但是因为使用了vue的容错机制,所以并不推荐
-->
<div :class="isActive && 'active'">foo</div>
<!-- vue中的class编写支持对象写法 -->
<!--
对象的key --- class属性名
对象的value --- 必须是一个boolean类型值
--- 如果值为true的时候,显示对应的class
--- 如果值为false的时候,不显示对应的class
-->
<div :class="{ active: isActive, hover: isHover }">foo</div>
<!--
既然对象语法动态绑定class 对应的值 是 对象形式
所以我们可以将对应的值 抽离到data选项中,或者methods选项中
-->
<!-- data选项中 fooClass: { active: this.isActive } -->
<div :class="fooClass">foo</div>
<!-- methods选项中 getFooClass() { return { active: this.isActive } } -->
<div :class="getFooClass()">foo</div>
<!-- 动态绑定的class 可以和 普通的class 共存 -->
<div class="foo" :class="{ active: isActive }">foo</div>
<!-- 动态绑定class 除了对象语法外 也有数组语法 -->
<div :class="['active', 'foo']">foo</div>
<!-- 数组语法中可以传入变量 -->
<div :class="['active', foo]">foo</div>
<!-- 数组语法中,也可以编写合法的js表达式 -->
<div :class="[isActive ? 'active' : '', 'foo']">foo</div>
<!-- 数组语法中,可以嵌套使用对象语法 -->
<div :class="[{ active: isActive }, 'foo']">foo</div>
<!-- 数组语法可以和普通class 共存 -->
<div class="foo" :class="[{ active: isActive }]">foo</div>
绑定style
我们可以利用v-bind:style来绑定一些CSS内联样式,因为某些样式我们需要根据数据动态来决定,比如某段文字的颜色,大小等等
CSS property 名可以用驼峰式 (camelCase) 或短横线分隔 (kebab-case,使用引号括起来) 来命名
<!-- 使用style绑定对象 也是支持数组写法和对象写法的 -->
<!--
基本使用方式和动态绑定class的用法是一致的
在对象中可以使用变量,任意合法的js表达式
或者可以将整个对象单独抽离后,在进行引用
-->
<div :style="{ color: 'red', 'font-size': fontSize + 'px' }">foo</div>
<!--
动态绑定style 也是支持 数组写法的
数组写法可以将多个样式对象应用到同一个元素上
-->
<div :style="[{ color: 'red' }, { fontSize: '30px' }]">foo</div>
动态绑定属性
在某些情况下,我们属性的名称可能也不是固定的
如果属性名称不是固定的,我们可以使用 :[属性名]=“值”
的格式来定义
这种绑定的方式,我们称之为动态绑定属性
<div :[propName]="foo">foo</div>
绑定一个对象
如果我们希望将一个对象的所有属性依次绑定到元素(或组件)上时,我们可以直接使用 v-bind 绑定一个对象
vue在解析的时候,会自动遍历对应的对象中的属性名和属性值,并依次作为属性添加到对应的组件或元素上
<!-- 在data选项中 info: { name: 'Klaus', age: 24 } -->
<!-- 直接使用v-bind 即可 不需要加上对应属性名 因为这里是绑定多个属性 -->
<div v-bind="info">foo</div>
<!-- 简写形式 - 不推荐,可读性较差 -->
<div :="info">foo</div>
<!-- 上述的写法等价于 -->
<div :name="info.name" :age="info.age">foo</div>
v-on
在前端开发中,我们需要经常和用户进行各种各样的交互
此时我们可以使用v-on
指令来监听用户发生的事件,比如点击、拖拽、键盘事件等等
<div id="app">
<!-- 基本使用 -->
<div v-on:click="handleClick"></div>
<!-- 简写方式 -->
<div @mousemove="handleMove"></div>
<!-- 可以通过这个方式绑定多个事件 -->
<div @click="handleClick" @mousemove="handleMove"></div>
<!-- 也可以通过这个当时绑定多个事件 -->
<div v-on="{ click: handleClick, mousemove: handleMove }"></div>
<!-- 或使用简写方式(可读性较差,不推荐) -->
<div @="{ click: handleClick, mousemove: handleMove }"></div>
<!--
如果事件逻辑简单,可以将其以表达式的方式绑定到元素上(可读性差,不推荐)
在模板中,可以直接访问声明的数据状态,方法等
-->
<div @click="count++">{{ count }}</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.global.min.js"></script>
<script>
Vue.createApp({
data() {
return {
count: 0
}
},
methods: {
handleClick() {
console.log('handleClick')
},
handleMove() {
console.log('handleMove')
}
}
}).mount('#app')
参数传递
<div id="app">
<!-- 在没有参数需要传递的时候 直接输入对应的函数引用地址 -->
<div @click="handleClick"></div>
<!--
在需要传递参数的时候, 直接在函数名后通过小括号的形式进行调用
vue会在该函数外进行包裹,确保其在事件执行的时候才会被触发 (fun(p1, p1) -> () => { fun(p1, p2) })
如果我们自己传递了对应的参数,那么默认就不会在传递对应的事件对象
如果我们需要在传递参数的同时使用事件对象,可以使用内置对象$event
-->
<div @click="handleParamsClick('Klaus', 18, $event)"></div>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.global.min.js"></script>
<script>
Vue.createApp({
methods: {
// 在没有参数的情况下 默认情况下vue会将对应的事件对象作为参数传递进来
handleClick(e) {
console.log(e)
},
handleParamsClick(name, age, event) {
console.log(name, age, event)
}
}
}).mount('#app')
修饰符
v-on支持修饰符,修饰符相当于对事件进行了一些特殊的处理
修饰符 | 说明 |
---|---|
.stop | 调用 event.stopPropagation() |
.prevent | 调用 event.preventDefault() |
.capture | 添加事件侦听器时使用 capture 模式 |
.self | 只当事件是从侦听器绑定的元素本身触发时才触发回调 |
.{keyAlias} (例如: .enter) | 仅当事件是从特定键触发时才触发回调 |
.once | 只触发一次回调 |
.left | 只当点击鼠标左键时触发 |
.middle | 只当点击鼠标中键时触 |
.right | 只当点击鼠标右键时触发 |
.passive | { passive: true } 模式添加侦听器 |
条件渲染
在某些情况下,我们需要根据当前的条件决定某些元素或组件是否渲染,此时就可以使用条件渲染
<div id="app">
<div v-if="users.length > 1">有多个嘉宾</div>
<div v-else="users.length === 1">只有一个嘉宾</div>
<div v-else>没有嘉宾</div>
</div>
v-if 的渲染是惰性
的
- 当条件为false时,其判断的内容完全不会被渲染或者会被销毁掉
- 当条件为true时,才会真正渲染条件块中的内容
template
如果我们需要在多个元素上添加相同的指令,例如
<h1 v-if="showInfo">Klaus</h1>
<h1 v-if="showInfo">24</h1>
<!-- 渲染后的结果为 -->
<h1>Klaus</h1>
<h1>24</h1>
此时在每个元素上添加相同指令必然是十分繁琐的,所以我们会使用一个div元素进行包裹
目的是为了将其中的那些元素,作为div的子元素进行统一管理
<div v-if="showInfo">
<h1>Klaus</h1>
<h1>24</h1>
</div>
<!-- 渲染后的结果为 -->
<div>
<h1>Klaus</h1>
<h1>24</h1>
</div>
但是这么做,依旧存在一个很大的弊端,也就是我们额外引入了一个div元素
很多情况下,在渲染的时候,我们并不希望渲染这个额外的div元素
此时我们可以使用template
元素
template元素可以当做不可⻅的包裹元素,一般和指令结合使用,在最终的渲染结构中,template并不会被最终渲染出来
<template v-if="showInfo">
<h1>Klaus</h1>
<h1>24</h1>
</template>
<!-- 渲染后的结果为 -->
<h1>Klaus</h1>
<h1>24</h1>