组件(Component)是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素,封装可重用的代码。在较高层面上,组件是自定义元素, Vue.js 的编译器为它添加特殊功能。在有些情况下,组件也可以是原生 HTML 元素的形式,以 is 特性扩展。
对于自定义标签名,Vue.js 不强制要求遵循 W3C规则 (小写,并且包含一个短杠),尽管遵循这个规则比较好。
1.全局注册
2.局部注册
要注册一个全局组件,你可以使用
Vue.component(tagName, options)
全局注册方式
使用方法
局部注册方式
使用方法
eg
A.tagName(不能使用关键字,如input,area等),定义名字如为驼峰,使用是需要用a-b
B.options
1.template
2.props
3.data
4.computed
5.method
当使用 DOM 作为模版时(例如,将 el 选项挂载到一个已存在的元素上), 你会受到 HTML 的一些限制,因为 Vue 只有在浏览器解析和标准化 HTML 后才能获取模版内容。尤其像这些元素 <ul> , <ol>, <table> , <select> 限制了能被它包裹的元素, 如<option> 不能出现在其非select它元素内部。
模版数据
要使用以上限制模版,可以使用is功能
eg
使用组件时,大多数可以传入到 Vue 构造器中的选项可以在注册组件时使用,有一个例外: data 必须是函数。
由于组件都是注册在Vue上,所以当data如果不是已函数返回的话,会指向同一个存储地址,如果出现多个组件的话,会同时指向一个内存地址,这样就会造成操作一个组件结果所有相同组件都跟着变的结果。
eg
组件意味着协同工作,通常父子组件会是这样的关系:组件 A 在它的模版中使用了组件 B 。它们之间必然需要相互通信:父组件要给子组件传递数据,子组件需要将它内部发生的事情告知给父组件。然而,在一个良好定义的接口中尽可能将父子组件解耦是很重要的。这保证了每个组件可以在相对隔离的环境中书写和理解,也大幅提高了组件的可维护性和可重用性。
在 Vue.js 中,父子组件的关系可以总结为 props down, events up 。父组件通过 props 向下传递数据给子组件,子组件通过 events 给父组件发送消息。看看它们是怎么工作的。
组件实例的作用域是孤立的。这意味着不能并且不应该在子组件的模板内直接引用父组件的数据。可以使用 props 把数据传给子组件。
Text
注意
1.组件内部的props命名为camelCase,html中的prop会转为kebab-case
2.可以简写 :message = "out-message"
3.注意区分message与:message。
4.vue2废弃了.sync(双向绑定)
5.prop不应该在子组件内被改变(单向数据流)
eg
支持的类型
String
Number
Boolean
Function
Object
Array
自定义校验 validator
自定义执行函数 coerce(vue2 已经移除)
Text
eg
我们知道,父组件是使用 props 传递数据给子组件,但如果子组件要把数据传递回去,应该怎样做?那就是自定义事件
1. 监听事件
2.派发事件
$dispatch,$broadcast 已废弃
$emit,$on现在使用的
this.$emit(eventName)
eventName为触发事件的自定义名称
比较适合用在简单的项目上,复杂的稍后会讲
v-on:dispatchEventName='eventName"
需要使用v-on接收事件
注:v-on监听时,$emit派发的函数名必须为小写,$on监听时可以试任意写法
dispatchEventName为子组件触发的事件名
eventName为父组件监听派发事件的执行函数
eg
v-on:eventName
需要使用v-on接收事件
eg
注意:ref,1.0版本不支持
原始:
<input v-bind:value='something' v-on:input="something = $event.target.value">
原理:
组件借鉴此思想,组件如下写法
<jd-input v-bind:value='rmb' v-on:input="rmb = arguments[0]"></jd-input>
<input v-model="something"></input>
插件简写:
<jd-input v-model='rmb'></jd-input>
eg
1.可以通过一个空Vue来做中间件
3.可以通过状态管理来实现
2.简单的状态管理理念-共享一个数据源
eg
4.进阶方式(最后在讲)
<app>
<app-header></app-header>
<app-footer></app-footer>
</app>
注意两点:
<app> 组件不知道它的挂载点会有什么内容。挂载点的内容是由<app>的父组件决定的。
<app> 组件很可能有它自己的模版。
为了让组件可以组合,我们需要一种方式来混合父组件的内容与子组件自己的模板。这个过程被称为 内容分发 (或 “transclusion” 如果你熟悉 Angular)。Vue.js 实现了一个内容分发 API ,参照了当前 Web 组件规范草案,使用特殊的 <slot> 元素作为原始内容的插槽。
分发内容是在父作用域内编译
<child-component v-show="someChildProperty"></child-component>
Vue.component('child-component', {
// 有效,因为是在正确的作用域内
template: '<div v-show="someChildProperty">Child</div>',
data: function () {
return {
someChildProperty: true
}
}
})
组件作用域在组件内部
达到效果的写法
eg
单个slot用法
<slot> 标签中的任何内容都被视为备用内容
具名Slot
eg
2.1.0后新增
eg
keep-live
include - 字符串或正则表达式。只有匹配的组件会被缓存。
exclude - 字符串或正则表达式。任何匹配的组件都不会被缓存。
eg
在编写组件时,记住是否要复用组件有好处。一次性组件跟其它组件紧密耦合没关系,但是可复用组件应当定义一个清晰的公开接口。
Vue 组件的 API 来自三部分 - props, events 和 slots :
Props 允许外部环境传递数据给组件
Events 允许组件触发外部环境的副作用
Slots 允许外部环境将额外的内容组合在组件中。
<my-component
:foo="baz"
:bar="qux"
@event-a="doThis"
@event-b="doThat"
>
<img slot="icon" src="...">
<p slot="main-text">Hello!</p>
</my-component>
尽管有 props 和 events ,但是有时仍然需要在 JavaScript 中直接访问子组件。为此可以使用 ref 为子组件指定一个索引 ID
eg
resolve加载成功回调
reject加载失败回调
eg
当注册组件(或者 props)时,可以使用 kebab-case ,camelCase ,或 TitleCase 。Vue 不关心这个。
在 HTML 模版中,请使用 kebab-case 形式:
如果组件未经 slot 元素传递内容,你甚至可以在组件名后使用 / 使其自闭合:
组件在它的模板内可以递归地调用自己,不过,只有当它有 name 选项时才可以:
Vue.component('unique-name-of-my-component', {
// ...
})
new Vue({
el:"#app",
components: {
component: {
name:" unique-name-of-my-component",
template: "<div></div>"
}
})
内联模版
X-Templates
对低开销的静态组件使用-v-once
eg
git地址:https://github.com/vuejs/vuex
简单的功能时候使用props与events
复杂的大型项目使用vuex会比较容易管理
.Vue文件使用
且听下回分解