目录
- 组件基础
- 概念
- 注册
- 实例
- 使用
- 渲染
模板语法
组件基础
概念
组件可以扩展 HTML 元素,封装可重用的代码。
在较高层面上,组件是自定义元素。
在有些情况下,组件也可以表现为用 is 特性进行了扩展的原生 HTML 元素。
注册
全局注册
//Vue.component(tagName, options)
Vue.component('my-component', {
template: 'A custom component!'
})
局部注册
//通过某个 Vue 实例/组件的实例选项 components
var Child = {
template: 'A custom component!'
}
new Vue({
// ...
components: {
'my-component': Child
}
})
写在哪里
//方式1
//方式2
//JavaScript 内联模板字符串
//方式3
//.vue 组件
数据对象
var data = { counter: 0 }
Vue.component('simple-counter', {
template: '',
//data 必须是函数
data: function () {
return data
}
})
new Vue({
el: '#example-2'
})
传递数据
Vue.component('child', {
// 声明 props
props: ['message'],
// 就像 data 一样,prop 也可以在模板中使用
// 同样也可以在 vm 实例中通过 this.message 来使用
template: '{{ message }}'
})
属性命名
使用时,camelCase (驼峰式命名) 的 prop 需要转换为相对应的 kebab-case (短横线分隔式命名)
动态绑定
new Vue({
el: '#prop-example-2',
data: {
parentMsg: 'Message from parent'
}
})
字面量语法 vs 动态语法
单向数据
数据验证
Vue.component('example', {
props: {
// 基础类型检测 (`null` 指允许任何类型)
propA: Number,
// 可能是多种类型
propB: [String, Number],
// 必传且是字符串
propC: {
type: String,
required: true
},
// 数值且有默认值
propD: {
type: Number,
default: 100
},
// 数组/对象的默认值应当由一个工厂函数返回
propE: {
type: Object,
default: function () {
return { message: 'hello' }
}
},
// 自定义验证函数
propF: {
validator: function (value) {
return value > 10
}
}
}
})
直接传入
属性合并
自定事件
绑定
监听
触发
给组件绑定原生事件
使用自定义事件的表单输入组件
自定义组件的 v-model
Vue.component('my-checkbox', {
model: {
prop: 'checked',
event: 'change'
},
props: {
checked: Boolean,
// 这样就允许拿 `value` 这个 prop 做其它事了
value: String
},
// ...
})
非父子组件的通信
在简单的场景下,可以使用一个空的 Vue 实例作为事件总线:
var bus = new Vue()
// 触发组件 A 中的事件
bus.$emit('id-selected', 1)
// 在组件 B 创建的钩子中监听事件
bus.$on('id-selected', function (id) {
// ...
})
在复杂的情况下,推荐使用专门的状态管理模式。
内容插槽
使用场景
作用范围
父组件模板的内容在父组件作用域内编译;子组件模板的内容在子组件作用域内编译。
单个插槽
我是父组件的标题
这是一些初始内容
这是更多的初始内容
我是子组件的标题
只有在没有要分发的内容时才会显示。
我是父组件的标题
我是子组件的标题
这是一些初始内容
这是更多的初始内容
有名插槽
这里可能是一个页面标题
主要内容的一个段落。
另一个主要段落。
这里有一些联系信息
这里可能是一个页面标题
主要内容的一个段落。
另一个主要段落。
内容丢失
除非子组件模板包含至少一个 插口,否则父组件的内容将会被丢弃。
作用域插槽
动态组件
//使用保留的 元素,并对其 is 特性进行动态绑定
//方式1
var vm = new Vue({
el: '#example',
data: {
currentView: 'home'
},
components: {
home: { /* ... */ },
posts: { /* ... */ },
archive: { /* ... */ }
}
})
//方式2
var Home = {
template: 'Welcome home!
'
}
var vm = new Vue({
el: '#example',
data: {
currentView: Home
}
})
组件缓存
编写可复用组件
子组件引用
var parent = new Vue({ el: '#parent' })
// 访问子组件实例
var child = parent.$refs.profile
异步组件
在大型应用时,推荐将应用拆分为多个小模块,按需从服务器下载。
//方式1
Vue.component('async-webpack-example', function (resolve) {
// 这个特殊的 require 语法告诉 webpack
// 自动将编译后的代码分割成不同的块,
// 这些块将通过 Ajax 请求自动下载。
require(['./my-async-component'], resolve)
})
//方式2-全局注册
Vue.component(
'async-webpack-example',
// 该 `import` 函数返回一个 `Promise` 对象。
() => import('./my-async-component')
)
//方式3-局部注册
new Vue({
// ...
components: {
'my-component': () => import('./my-async-component')
}
})
命名约定
对低开销的静态组件使用 v-once
实例
new Vue({
el: '#example'
})
使用
渲染
A custom component!