一、Vue组件
一个Vue项目是由很多个组件构成的。
Vue组件分为全局组件和局部组件。
组件是可以复用的Vue实例,且带有一个名字,它与new Vue({})接收相同的选项,比如data,computed,watch,methods以及生命周期钩子等,除了el。
组件可以复用,每个相同的组件相互独立,各自独立维护自己的数据,你每用一次组件,就会有一个它的新实例被创建。
一个组件的data选项必须是一个函数,每个实例可以维护一份被返回对象的独立的拷贝。
通常一个应用会以一棵嵌套的组件树的形式来组织。
为了能在模板中使用,这些组件必须先注册以便Vue能够识别。
在注册一个组件的时候,必须给组件一个名字;
在Vue里 ,每一个Vue组件,都是一个Vue实例 【实例=组件】;
Vue实例有的功能,Vue组件都拥有。
每个组件都是vue的实例;
每个实例的组成部分:
props、template、data、methods...
每一个组件都有一个template模板,如果没有写template,默认为挂载点下面的所有DOM标签作为模板。
组件的三个特点:独立性,可复用性,完整性
组件化问题:
1、组件状态管理(vuex)
2、多组件的混合使用、多页面复杂业务(vue-router)
3、组件之间的传参、消息、事件管理(props,emit/on,bus)
为什么要组件化:
1. 实现功能模块的复用
2. 高效执行
3. 开发单页面复杂应用
二、全局组件:
通过Vue.component定义的组件是全局组件, 可以在任何地方使用
Vue.component('todo-item', {
props: ['content'], //这个组件接收从外部传进来的叫 content的属性
template: '全局组件的组件名,就是Vue.component的第一个参数。
定义全局组件名的方式有两种:
第一种:Vue.component('my-component-name', { }) 组件名使用短横线-进行连接;
第二种:Vue.component('MyComponentName', { }) 组件名首字母大写;
子组件通过props选项来接收父组件传递的参数,比如:
Vue.component('blog-post', {
props: ['title'],
template: '{{ title }}'
})记住:全局注册的行为必须在根 Vue 实例 (通过 new Vue) 创建之前发生。
全局组件在注册之后可以用在任何新创建的 Vue 根实例 (new Vue) 的模板中。
实例代码1:
Vue组件
实例代码2:
Vue组件
实例代码3:
vue - 全局组件
实例代码4:
Vue-TodoList
三、局部组件
局部组件必须在new Vue()内通过components注册声明
var TodoItem = { template: '对于 components 对象中的每个属性来说,其属性名就是自定义元素的名字,其属性值就是这个组件的选项对象。
注意:局部注册的组件不能在子组件中使用;
如果你希望局部组件ComponentA在子组件ComponentB中可以用,你可以这样写:
var ComponentA = { }
var ComponentB = {
components: {
'component-a': ComponentA
},
// ...
}实例代码:
Vue-TodoList
四、组件属性——props
在这里以下面的组件为例:
Vue.component('blog-post', {
props: ['postTitle'],
template: '{{ postTitle }}'
})使用组件:
一个组件默认可以拥有任意数量的 prop,任何值都可以传递给任何 prop。
通常情况下,prop是以字符串数组的形式列出的,如下:
props: ['title', 'likes', 'isPublished', 'commentIds', 'author']
我们也可以以对象形式列出prop,如下:
props: {
title: String,
likes: Number,
isPublished: Boolean,
commentIds: Array,
author: Object,
callback: Function,
contactsPromise: Promise // or any other constructor
}给prop赋值:
(1)给prop传入一个静态值:
(2)给prop传入一个变量的值
(3)给prop传入一个复杂的表达式
(4)给prop传入一个数字
(5)给prop传入一个布尔值
(6)给prop传入一个数组
(7)给prop传入一个对象
(8)给prop传入一个对象的所有属性
我们可以通过不带参数的v-bind指令将一个对象的所有属性传给prop
比如:对象user包含如下信息:
user: {
id: 1,
name: "刘豆豆",
sex: "男",
age: 18,
content: "天国虽美,没有了你,万杯觥筹只不过是提醒寂寞罢了"
}直接传入:
所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定,也就是父组件的 prop的更新会向下流动到子组件中,但是反过来则不行。
换句话说:父组件与子组件之间的数组传输是单向的,只能是父组件传递给子组件,当父组件的prop更新时,子组件中所有的prop都会被刷新为最新的值。
注意在 Javascript 中对象和数组是通过引用传入的,所以对于一个数组或对象类型的 prop 来说,在子组件中改变这个对象或数组本身将会影响到父组件的状态。
在实际的开发过程中,我们需要对props中的键值对进行验证,为了定制prop的验证方式,我们可以为props中的值提供一个带有验证需求的对象,而不是一个字符串数组,比如:
Vue.component('my-component', {
props: {
// 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)
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 ['success', 'warning', 'danger'].indexOf(value) !== -1
}
}
}
})如果验证失败,会在控制台给出警告信息。
prop中的type对应的类型有:String, Number, Boolean, Array, Object, Date, Function, Symbol, 也可以是一个自定义的构造函数,我们可以使用instanceof类进行检查确认。
比如:
//自定义构造函数
function User(id, name){
this.id = id;
this.name = name;
}
//在组件中使用
Vue.component('blog-post',{
props: {
author: User
}
})通常情况下,组件可以接受任意的特性,这些接受到的特性会被添加到这个组件的根元素上。为什么会这样呢?因为开发组件库的作者并不知道你会把这个组件用在什么场景下。一个非 prop 特性是指传向一个组件,但是该组件并没有相应 prop 定义的特性。
比如说:
在Bootstrap插件中使用
这个 data-date-picker="activated" 特性就会自动添加到
在这里,如果你不希望组件的根元素继承特性,你可以在组件中设置inheritAttrs: false,来禁用特性继承。
Vue.component('my-component', {
inheritAttrs: false,
// ...
})注意 inheritAttrs: false 选项不会影响 style 和 class 的绑定。
五、动态组件:
在一个Vue项目中,会有很多个组件,我们可以使用v-bind:is特性来切换不同的组件,如下:
每次切换组件的时候,Vue都会创建一个新的组件实例。
通常情况下,我们更希望在组件实例第一次创建的时候,被及时缓存下来。为了解决这个问题,我们可以使用
全局组件和局部组件都可以使用
六、异步组件:
在大型应用中,我们可能需要将应用分割成小一些的代码块,并且只在需要的时候才从服务器加载一个模块。为了简化,Vue 允许你以一个工厂函数的方式定义你的组件,这个工厂函数会异步解析你的组件定义。Vue 只有在这个组件需要被渲染的时候才会触发该工厂函数,且会把结果缓存起来供未来重渲染。
比如:
Vue.component('async-example', function (resolve, reject) {
setTimeout(function () {
// 向 `resolve` 回调传递组件定义
resolve({
template: 'I am async!'
})
}, 1000)
})这个工厂函数会收到一个 resolve 回调,这个回调函数会在你从服务器得到组件定义的时候被调用。
一个推荐的做法是将异步组件和 webpack 的 code-splitting 功能一起配合使用:
Vue.component('async-webpack-example', function (resolve) {
// 这个特殊的 `require` 语法将会告诉 webpack
// 自动将你的构建代码切割成多个包,这些包
// 会通过 Ajax 请求加载
require(['./my-async-component'], resolve)
})你也可以在工厂函数中返回一个 Promise,所以把 webpack 2 和 ES2015 语法加在一起,我们可以写成这样:
Vue.component(
'async-webpack-example',
// 这个 `import` 函数会返回一个 `Promise` 对象。
() => import('./my-async-component')
)当使用局部注册的时候,你也可以直接提供一个返回 Promise 的函数:
new Vue({
// ...
components: {
'my-component': () => import('./my-async-component')
}
})在Vue的2.3.0+ 的版本中,这里的异步组件工厂函数也可以返回一个如下格式的对象:
const AsyncComponent = () => ({
// 需要加载的组件 (应该是一个 `Promise` 对象)
component: import('./MyComponent.vue'),
// 异步组件加载时使用的组件
loading: LoadingComponent,
// 加载失败时使用的组件
error: ErrorComponent,
// 展示加载时组件的延时时间。默认值是 200 (毫秒)
delay: 200,
// 如果提供了超时时间且组件加载也超时了,
// 则使用加载失败时使用的组件。默认值是:`Infinity`
timeout: 3000
})七、自定义组件的v-model
一个组件上的 v-model 默认会利用名为 value 的 prop 和名为 input 的事件,但是像单选框、复选框等类型的输入控件可能会将 value 特性用于不同的目的。model 选项可以用来避免这样的冲突。如下:
Vue.component('base-checkbox', {
model: {
prop: 'checked',
event: 'change'
},
props: {
checked: Boolean
},
template: `
`
})
这里的 lovingVue 的值将会传入这个名为 checked 的 prop。同时当
以上就是Vue.js组件相关的知识点了,关于Vue.js的更多相关知识,本人还在继续学习中!



