API开发风格
1. 选项式
2. 组合式
计算属性: computed
使用计算属性可以避免重复计算。计算属性和methods中方法的区别就是:计算属性中方法返回的值会基于其响应式依赖被缓存,而普通方法会每次重新执行不缓存。
javascript
export default {
data() {
return {
author: {
name: 'John Doe',
books: [
'Vue 2 - Advanced Guide',
'Vue 3 - Basic Guide',
'Vue 4 - The Mystery'
]
}
}
},
computed: {
// 一个计算属性的 getter
publishedBooksMessage() {
// `this` 指向当前组件实例
return this.author.books.length > 0 ? 'Yes' : 'No'
}
}
}
类与样式绑定: v-bind
绑定到模板
javascript
<div :class="{ active: isActive }"></div>
<!-- 绑定多个class,就需绑定数组 -->
<div :class="[activeClass, errorClass]"></div>
// 对应的data()
data() {
return {
activeClass: 'active',
errorClass: 'text-danger'
}
}
绑定到组件
html
<MyComponent :class="{ active: isActive }" />
条件渲染:v-if、v-show
v-if
- v-if 指令用于条件性地渲染一块内容。这块内容只会在指令的表达式返回真值时才被渲染。
html
<h1 v-if="awesome">Vue is awesome!</h1>
- 可结合v-else-if、v-else使用
html
<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>
- v-if可作用于<template>
html
<template v-if="ok">
<h1>Title</h1>
<p>Paragraph 1</p>
<p>Paragraph 2</p>
</template>
- 当 v-if 和 v-for 同时存在于一个元素上的时候,v-if 会首先被执行。
v-show
- v-show 会在 DOM 渲染中保留该元素;v-show 仅切换了该元素上名为 display 的 CSS 属性。
- v-show 不支持在 元素上使用,也不能和 v-else 搭配使用。
列表渲染:v-for
v-for
事件处理
行内形式:
html
<inuput @click="a++" />
表单输入绑定
行内形式:
html
<input v-model:udata="user.data" />
生命周期
Vue2与Vu3生命周期的变化
Vue2 | Vue3 |
---|---|
beforeCreate | Not needed* |
created | Not needed* |
beforeMount | onBeforeMount |
mounted | onMounted |
beforeUpdate | onBeforeUpdate |
updated | onUpdated |
beforeDestroy | onBeforeUnmount |
destroyed | onUnmounted |
- mounted / onMounted 钩子可以用来在组件完成初始渲染并创建 DOM 节点后运行代码
模板引用
Vue2中的引用
javascript
this.$refs.input
例如:
javascript
<script>
export default {
mounted() {
this.$refs.input.focus()
}
}
</script>
<template>
<input ref="input" />
</template>
Vue3中的引用
vue3中由于没有this所以不能用this.$refs.elem的形式获取,而是通过setup的形式来获取
可以用组合式API或选项式API
javascript
<template>
<div ref="box"></div>
</template>
<script setup>
import { ref, onMounted } from 'vue'
const box = ref(null)
// 须在mounted后才可输出引用的DOM元素
onMounted(() => {
console.log(box.value)
})
</script>
组件的引入、注册、使用
注册全局组件:
javascript
<script>
import MyComponent from './App.vue'
app.component('MyComponent', MyComponent)
</script>
注册局部组件:
javascript
<script>
import ButtonCounter from './ButtonCounter.vue'
export default {
components: {
ButtonCounter
}
}
</script>
<template>
<h1>Here is a child component!</h1>
<ButtonCounter />
<ButtonCounter />
</template>
</script>
每个被使用的组件会创建新实例,所以有各自独立的状态
Props
- 一个组件需要显式声明它所接受的 props,这样 Vue 才能知道外部传入的哪些是 props,哪些是透传 attribute (关于透传 attribute,我们会在专门的章节中讨论)。
- props 需要使用 props 选项来定义:
javascript
export default {
props: ['foo'],
created() {
// props 会暴露到 `this` 上
console.log(this.foo)
}
}
- 除了使用字符串数组来声明 prop 外,还可以使用对象的形式:
javascript
export default {
props: {
title: String,
likes: Number
}
}
Prop命名格式
- 如果一个 prop 的名字很长,应使用 camelCase 形式,因为它们是合法的 JavaScript 标识符,可以直接在模板的表达式中使用,也可以避免在作为属性 key 名时必须加上引号。
- 静态prop
html
<BlogPost title="My journey with Vue" />
- 动态prop(v-bind式)
html
<!-- 根据一个变量的值动态传入 -->
<BlogPost :title="post.title" />
<!-- 根据一个更复杂表达式的值动态传入 -->
<BlogPost :title="post.title + ' by ' + post.author.name" />
组件事件
触发与监听事件
- 在组件的模板表达式中,可以直接使用 $emit 方法触发自定义事件 (例如:在 v-on 的处理函数中):
html
<!-- MyComponent -->
<button @click="$emit('someEvent')">click me</button>
- e m i t ( ) 方法在组件实例上也同样以 t h i s . emit() 方法在组件实例上也同样以 this. emit()方法在组件实例上也同样以this.emit() 的形式可用:
javascript
export default {
methods: {
submit() {
this.$emit('someEvent')
}
}
}
组件 v-model
v-model 可以在组件上使用以实现双向绑定。
例如:
html
<input v-model="searchText" />
与下等价:
html
<input
:value="searchText"
@input="searchText = $event.target.value"
/>
而当使用在一个组件上时,v-model 会被展开为如下的形式:
html
<CustomInput
:modelValue="searchText"
@update:modelValue="newValue => searchText = newValue"
/>
插槽 Slots
Slots作用:
将组件使用处的内容,放于其模板中的占位,进而渲染
- 使用组件:
html
<FancyButton> Click me! </FancyButton>
- FancyButton模板:
html
<button class="fancy-btn">
<slot></slot>
</button>