NT_1_Vue
Compute计算属性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <!-- CustomInput.vue --> export default { props: ['modelValue'], emits: ['update:modelValue'], computed: { newvalue() {' return value + "1" } value: { get() { return this.modelValue }, set(value) { this.$emit('update:modelValue', value) } } } } </script>
|
对于newvalue,当value变化时,newvalue也会跟着变化。value实现了组件v-model的功能。
在Comp上使用v-model
1 2 3 4
| <CustomInput :modelValue="searchText" @update:modelValue="newValue => searchText = newValue" />
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <!-- CustomInput.vue --> <script> export default { props: ['modelValue'], emits: ['update:modelValue'] } </script>
<template> <input :value="modelValue" @input="$emit('update:modelValue', $event.target.value)" /> </template>
|
透传标签属性
class, id等在父组件上定义的都会被头传到子组件。@click也会。
click 监听器会被添加到 <MyButton>
的根元素,即那个原生的 <button>
元素之上。当原生的 <button>
被点击,会触发父组件的 onClick 方法。同样的,如果原生 button
元素自身也通过 v-on 绑定了一个事件监听器,则这个监听器和从父组件继承的监听器都会被触发。
禁用:在组件选项中设置 inheritAttrs: false
透传进来的 attribute 可以在模板的表达式中直接用 $attrs 访问到。
包含了除组件所声明的 props 和 emits 之外的所有其他 attribute,例如 class,style,v-on 监听器等等。
插槽Slot
1 2 3
| <FancyButton> Click me! <!-- 插槽内容 --> </FancyButton>
|
1 2 3 4 5
| <button class="fancy-btn"> <slot> 默认内容 </slot> <!-- 插槽出口 --> </button>
|
- 插槽可以是任何模板内容(元素、甚至是组件)
- 插槽内容只能访问到父作用域。
具名插槽
没有提供name属性的slot出口会隐式地命名为default。
父组件声明v-slot名称作为slot的name。
1 2 3 4 5
| 父组件 <div class="container"> <header v-slot="hi"> </header> </div>
|
1 2
| 子组件 <div name="hi"></div>
|
v-slot可以缩写为#
动态插槽
v-slot内的内容可以是js变量。v-slot:[dynamicSlotName]
作用域插槽

分为具名和不具名。
v-slot内可以使用解构。
依赖注入
提供方:
1 2 3 4 5 6
| provide() { // 使用函数的形式,可以访问到 `this` return { message: this.message } }
|
上面的是非响应式的。要换成响应式,用计算属性
1
| message: computed(() => this.message)
|
注入方:
1 2 3 4 5 6
| export default { inject: ['message'], created() { console.log(this.message) // injected value } }
|
注入方可以使用别名注入,在使用别名注入时,也可以设置默认值
1 2 3 4 5 6
| inject: { /* 本地属性名 */ localMessage: { from: /* 注入来源名 */ 'message', default : 'default value' } }
|
异步组件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| const AsyncComp = defineAsyncComponent({ // 加载函数 loader: () => import('./Foo.vue'),
// 加载异步组件时使用的组件 loadingComponent: LoadingComponent, // 展示加载组件前的延迟时间,默认为 200ms delay: 200,
// 加载失败后展示的组件 errorComponent: ErrorComponent, // 如果提供了一个 timeout 时间限制,并超时了 // 也会显示这里配置的报错组件,默认值是:Infinity timeout: 3000 })
|
Logical Reuse
组合式函数
1 2 3 4
| // 按照惯例,组合式函数名以“use”开头 export function usexxxx() { //xxxxxxx }
|
其他组件中
1
| import { usexxxx } from './xxx.js'
|
支持组合函数嵌套。
自定义指令
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| //method1 const focus = { mounted: (el) => el.focus() }
export default { directives: { // 在模板中启用 v-focus focus } }
<input v-focus />
//method2 全局 const app = createApp({}) // 使 v-focus 在所有组件中都可用 app.directive('focus', (el, binding) => { /* ... */ })
//指令钩子 el:指令绑定到的元素。这可以用于直接操作 DOM。
binding:一个对象,包含以下属性。 //<div v-demo="{ color: 'white', text: 'hello!' }"></div> //返回的binding就是其中定义的对象 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 钩子中可用。
|
不用钩子函数的话,直接在callback内写,将会mounted和updated时调用
插件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| // plugins/xxx.js export default { install: (app, options) => { // 注入一个全局可用的 $hello() 方法 app.config.globalProperties.$hello = (val) => { // codes } } }
//注册 import x'x'x from './plugins/xxx'
app.use(i18nPlugin, { //额外参数 options })
//使用 $hello('val')
|
插件也可使用provide()来在整个应用层面提供依赖:
内置组件
Transition
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <button @click="show = !show">Toggle</button> <Transition> <p v-if="show">hello</p> </Transition>
.v-enter-active, .v-leave-active { transition: opacity 0.5s ease; }
.v-enter-from, .v-leave-to { opacity: 0; }
|