Vue 选项式API
功能选项
name
显式声明组件展示时的名称。
export default {
name: "MyComponent",
};
template
字符串模板
export default {
/* html */
template: `<div>count is {{ count }}</div>`,
};
ID 选择器模板
<template id="component_app">
<div>count is {{ count }}</div>
</template>
export default {
template: "#component_app",
};
template 标签模板
<template>
<span>{{ message + getMessage() + 1 }}</span>
<span>{{ message ? 'YES' : 'NO' }}</span>
<span>{{ message.split('').reverse().join('') }}</span>
</template>
<script>
export default {
// 不需要template字段
};
</script>
components
局部注册组件
<template>
<div class="app">
<MyDialog />
<MyDialog></MyDialog>
</div>
</template>
<script>
import MyDialog from './MyDialog.vue'
export default {
components: { MyDialog },
}
</script>
expose
指定当前组件暴露到其他组件的属性和方法,未指定时默认全部暴露。
<!-- 父组件 -->
<template>
<div class="parent">
<Child ref="child"></Child>
</div>
</template>
<script>
import Child from './Child.vue'
export default {
components: { Child },
expose: ['status', 'say'],
data() {
return {
status: 1,
message: "信息",
};
},
methods: {
say() {},
run() {},
},
mounted() {
// 获取子组件对象
const child = this.$refs.child;
// 访问子组件对象的属性方法
console.log(child.type);
console.log(child.name); // 子组件的 expose 未指定,返回 undefined
child.show();
child.hide(); // 子组件的 expose 未指定,报错提示:child.hide is not a function
},
}
</script>
<!-- 子组件 -->
<template>
<div class="child"></div>
</template>
<script>
export default {
expose: ['type', 'show'],
data() {
return {
type: 1,
name: "名称",
};
},
methods: {
show() {},
hide() {},
},
mounted() {
// 获取父组件对象
const parent = this.$parent;
// 访问父组件对象的属性方法
console.log(parent.status);
console.log(parent.message); // 父组件的 expose 未指定,返回 undefined
parent.say();
parent.run(); // 父组件的 expose 未指定,报错提示:parent.run is not a function
},
}
</script>
props
父组件给子组件传递数据
<!-- 父组件 -->
<template>
<div class="parent">
<!-- 动态 -->
<Child :message="message" v-bind="post"></Child>
<!-- 静态:需要使用 v-bind 使其作为 JavaScript 表达式,而不是字符串-->
<Child
:likes="42"
:is-published="false"
:comment-ids="[234, 266, 273]"
:author="{
name: 'Veronica',
company: 'Veridian Dynamics'
}"
>
</Child>
</div>
</template>
<script>
import Child from './Child.vue'
export default {
components: { Child },
data() {
return {
message: "信息",
post: {
id: 1,
title: 'My Journey with Vue'
}
};
},
}
</script>
<!-- 子组件 -->
<template>
<div class="child">{{ message }}</div>
</template>
<script>
export default {
// prop是只读的
props: ['message'],
data() {
return {
// 作为初始值定义为数据以便更改
msg: this.message,
}
},
computed: {
// 使用计算属性进行转换
trimMessage() {
return this.message.trim();
}
}
}
</script>
emits
<!-- 父组件 -->
<template>
<div class="parent">
<!-- 监听子组件的自定义事件 -->
<Child @enlarge="handle"></Child>
</div>
</template>
<script>
import Child from './Child.vue'
export default {
components: { Child },
methods: {
handle(param1, param2) {
// doSomething
},
},
}
</script>
<!-- 子组件 -->
<template>
<button @click="show()">按钮</button>
</template>
<script>
export default {
// 声明自定义事件(当与原生事件重名时可以避免被当成原生事件)
emits: ['enlarge'],
methods: {
show() {
// 触发事件
this.$emit('enlarge', "参数1", "参数2")
},
},
}
</script>
inheritAttrs
透传属性继承
透传属性
父组件中定义子组件的属性,没有在子组件中 props
声明,则会透传成子组件的属性。
父组件中定义子组件的事件监听器,没有在子组件中 emits
声明,则会透传成子组件的原生事件监听器属性。
<!-- 父组件 -->
<template>
<div class="parent">
<Child class="message" @click="show"></Child>
</div>
</template>
<script>
import Child from './Child.vue'
export default {
components: { Child },
methods: {
show() {}
}
}
</script>
<!-- 单根节点子组件 -->
<template>
<div class="child"></div>
<!-- 继承了透传属性 class 和 onClick -->
<!-- <div class="child message" onClick="ƒ"></div> -->
</template>
<script>
export default {
inheritAttrs: true, // 是否继承透传属性,默认 true
mounted() {
// 获取透传属性(不管是否继承)
console.log(this.$attrs);
// {class: 'message', onClick: ƒ}
}
}
</script>
<!-- 多根节点子组件 -->
<template>
<header></header>
<!-- 无法继承透传属性,需要显示指定 v-bind="$attrs" -->
<!-- 或者设置 inheritAttrs: false,否则会有警告 -->
<main v-bind="$attrs"></main>
<footer></footer>
</template>
<script>
export default {
inheritAttrs: false,
}
</script>
provide
为后代组件供给数据
// keys.js
export default {
message: Symbol(),
info: Symbol(),
}
import { computed } from 'vue'
import keys from './keys.js'
export default {
// 对象形式
provide: {
message: "hello",
// symbol注入名
[keys.message]: "value",
},
// 函数形式
provide() {
return {
// 可以访问到 `this`
message: this.message
// 使用计算属性保存响应性
message: computed(() => this.message)
}
},
data() {
return {
message: 'hello!'
}
},
}
inject
注入祖先组件供给的数据
import keys from './keys.js'
export default {
// 直接注入
inject: ['message'],
// 配置注入
inject: {
// 别名
localMessage: {
from: 'message', // 原名
default: 'default value', // 默认值
}
myMessage: {
from: keys.message, // symbol形式原名
default: () => ({ name: 'John' }) // 函数形式默认值
}
}
data() {
return {
// data 可以访问到注入的数据
info: this.message,
}
},
}
data
数据
export default {
data() {
return {
name: 'John',
};
},
};
computed
计算属性
export default {
data() {
return {
count: 0,
firstName: 'John',
lastName: 'Doe'
};
},
computed: {
// 只读计算属性
doubleCount() {
return this.count * 2;
},
// 读写计算属性
fullName: {
get() {
return this.firstName + ' ' + this.lastName
},
set(value) {
[this.firstName, this.lastName] = value.split(' ')
}
}
},
};
watch
侦听器
export default {
data() {
return {
message: '',
user: {
name: "",
},
}
},
watch: {
// 基本侦听
message(newValue, oldValue) {
// doSomething
},
"user.name"(newValue, oldValue) {
// doSomething
}
// 侦听配置
user: {
// 侦听回调
handler(newValue, oldValue) {
// doSomething
},
// 深层侦听对象以及对象里的属性变化
deep: true,
// 创建侦听器时,立即执行一遍回调
immediate: true,
// 刷新时机:pre 组件更新之前(默认),post 组件更新之后,sync 异步
flush: 'post',
}
},
}
filters
过滤器
<template>
{{ score | omit(999999) }}
</template>
<script>
export default {
data: function () {
return {
score: 123,
};
},
filters: {
omit: function (value, max) {
return value > max ? max + "+" : value;
},
},
}
</script>
methods
方法
methods: {
increment() {
this.count++;
}
},
mixins
一个选项对象的数组,这些对象都将被混入到当前组件的实例中。
const mixin = {
created() {
console.log(1)
}
}
createApp({
created() {
console.log(2)
},
mixins: [mixin]
})
// => 1
// => 2
extends
要继承的“基类”组件。
const CompA = { ... }
const CompB = {
extends: CompA,
...
}
directives
自定义指令
<template>
<!-- 使用 v-focus 指令 -->
<input v-focus/>
</template>
<script>
export default {
directives: {
// 定义 v-focus 指令
focus: {
// 在绑定元素的 attribute 前或事件监听器应用前调用
created(el, binding, vnode, prevVnode) {},
// 在元素被插入到 DOM 前调用
beforeMount() {},
// 在绑定元素的父组件及他自己的所有子节点都挂载完成后调用
mounted(el) {
el.focus();
},
// 绑定元素的父组件更新前调用
beforeUpdate() {},
// 在绑定元素的父组件及他自己的所有子节点都更新后调用
updated() {},
// 绑定元素的父组件卸载前调用
beforeUnmount() {},
// 绑定元素的父组件卸载后调用
unmounted() {}
}
}
}
</script>
钩子参数
el
:指令绑定到的元素。这可以用于直接操作 DOM。binding
:一个对象,包含以下 property。value
:传递给指令的值。例如在v-my-directive="1 + 1"
中,值是2
。oldValue
:之前的值,仅在beforeUpdate
和updated
中可用。无论值是否更改,它都可用。arg
:传递给指令的参数 (如果有的话)。例如在v-my-directive:foo
中,参数是"foo"
。modifiers
:一个包含修饰符的对象 (如果有的话)。例如在v-my-directive.foo.bar
中,修饰符对象是{ foo: true, bar: true }
。instance
:使用该指令的组件实例。dir
:指令的定义对象。
vnode
:代表绑定元素的底层 VNode。prevNode
:之前的渲染中代表指令所绑定元素的 VNode。仅在beforeUpdate
和updated
钩子中可用。
render
以编程式来创建组件虚拟 DOM 树的函数,比 template 拥有更高的优先级。
compilerOptions
配置组件模板的运行时编译器选项。
参考:应用实例 / config.compilerOptions
生命周期钩子
beforeCreate
在组件实例初始化完成之后立即调用(Options API 还未初始化)
export default {
beforeCreate() {},
};
created
在组件实例处理完所有与状态相关的选项后调用(Options API 已初始化)
export default {
created() {},
};
beforeMount
在组件被挂载之前调用(DOM 还未渲染)
export default {
beforeMount() {},
};
mounted
在组件被挂载之后调用(DOM 已渲染)
export default {
mounted() {},
};
beforeUpdate
在组件即将因为一个响应式状态变更而更新其 DOM 树之前调用
export default {
beforeUpdate() {},
};
updated
在组件即将因为一个响应式状态变更而更新其 DOM 树之前调用
export default {
updated() {},
};
beforeUnmount
在一个组件实例被卸载之前调用
export default {
beforeUnmount() {},
};
unmounted
在一个组件实例被卸载之后调用
export default {
unmounted() {},
};
errorCaptured
在捕获了后代组件传递的错误时调用
export default {
errorCaptured() {},
};
activated
若组件实例是若组件实例是 <KeepAlive>
缓存树的一部分,当组件被插入到 DOM 中时调用
export default {
activated() {},
};
deactivated
若组件实例是若组件实例是 <KeepAlive>
缓存树的一部分,当组件从 DOM 中被移除时调用
export default {
deactivated() {},
};
renderTracked
在一个响应式依赖被组件的渲染作用追踪后调用 Dev only
export default {
renderTracked() {},
};
renderTriggered
在一个响应式依赖被组件触发了重新渲染之后调用 Dev only
export default {
renderTriggered() {},
};
serverPrefetch
当组件实例在服务器上被渲染之前要完成的异步函数 SSR only
export default {
serverPrefetch() {},
};