全局注册
const app = Vue.createApp({})
app.component('component-a', {
/* ... */
})
app.component('component-b', {
/* ... */
})
app.mount('#app')
局部注册
const app = Vue.createApp({
components: {
'component-a': ComponentA,
'component-b': ComponentB
}
})
常用写法
import ComponentA from './ComponentA.vue'
export default {
components: {
ComponentA
}
// ...
}
监听子组件事件 - $emit
<!--子组件-->
<button @click="$emit('enlargeText')"> Enlarge text</button>
<!--父组件-->
<blog-post ... @enlarge-text="postFontSize += 0.1"></blog-post>
子组件传递参数给父组件
<!--子组件-->
<button @click="$emit('enlargeText', 0.1)">Enlarge text</button>
方法1
<!--父组件-->
<blog-post ... @enlarge-text="postFontSize += $event"></blog-post>
方法2
<blog-post ... @enlarge-text="onEnlargeText"></blog-post>
methods: {
onEnlargeText(enlargeAmount) {
this.postFontSize += enlargeAmount
}
}
通过插槽分发内容 <slot>
template: `
<div class="demo-alert-box">
<strong>Error!</strong>
<slot></slot>
</div>
`
<alert-box>
Something bad happened.
</alert-box>
image.png
Prop 类型
props: {
title: String,
likes: Number,
isPublished: Boolean,
commentIds: Array,
author: Object,
callback: Function,
contactsPromise: Promise // 或任何其他构造函数
}
传入一个【静态】的值
<blog-post title="My journey with Vue"></blog-post>
传入一个【动态】的值
<blog-post :title="post.title"></blog-post>
传入一个对象的所有 property
post: {
id: 1,
title: 'My Journey with Vue'
}
<blog-post v-bind="post"></blog-post>
<!--等价上面-->
<blog-post v-bind:id="post.id" v-bind:title="post.title"></blog-post>
注意
不应该在一个子组件内部改变 prop。如果这样做,Vue会在浏览器的控制台中发出警告, 希望将其作为一个本地的 prop 来使用。最好定义一个本地的 data property 并将这个 prop 作为其初始值:
props: ['initialCounter'],
data() {
return {
counter: this.initialCounter
}
}
HTML 中的 attribute 名是大小写不敏感, 使用其等价的 kebab-case (短横线分隔命名) 命名:
const app = Vue.createApp({})
app.component('blog-post', {
// 在 JavaScript 中使用 camelCase
props: ['postTitle'],
template: '<h3>{{ postTitle }}</h3>'
})
<!-- 在 HTML 中使用 kebab-case -->
<blog-post post-title="hello!"></blog-post>
父组件引用子组件ref
const app = Vue.createApp({})
app.component('base-input', {
template: `
<input ref="input" />
`,
methods: {
focusInput() {
this.$refs.input.focus()
}
},
mounted() {
this.focusInput()
}
})
Provide / Inject
传递基础
const app = Vue.createApp({})
app.component('todo-list', {
data() {
return {
todos: ['Feed a cat', 'Buy tickets']
}
},
provide: {
user: 'John Doe'
},
template: `
<div>
{{ todos.length }}
<!-- 模板的其余部分 -->
</div>
`
})
app.component('todo-list-statistics', {
inject: ['user'],
created() {
console.log(`Injected property: ${this.user}`) // > 注入的 property: John Doe
}
})
传递实例,将 provide 转换为返回对象的函数:
app.component('todo-list', {
data() {
return {
todos: ['Feed a cat', 'Buy tickets']
}
},
provide() {
return {
todoLength: this.todos.length
}
},
template: `
...
`
})
处理响应性
app.component('todo-list', {
provide() {
return {
todoLength: Vue.computed(() => this.todos.length)
}
}
})
app.component('todo-list-statistics', {
inject: ['todoLength'],
created() {
console.log(`Injected property: ${this.todoLength.value}`) // > 注入的 property: 5
}
})
网友评论