vue每次注册一个vue 获取子组件元素都会在html元素标签里生成这种属性吗

Vue.js学习 Item11 – 组件与组件间的通信 - vue-component-vuejs - ITkeyowrd
Vue.js学习 Item11 – 组件与组件间的通信
什么是组件?
组件(Component)是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素,封装可重用的代码。在较高层面上,组件是自定义元素,Vue.js 的编译器为它添加特殊功能。在有些情况下,组件也可以是原生 HTML 元素的形式,以 is 特性扩展。
之前说过,我们可以用 Vue.extend() 创建一个组件构造器:
var MyComponent = Vue.extend({
// 选项...
}) 要把这个构造器用作组件,需要用 `ponent(tag, constructor)` **注册** :
// 全局注册组件,tag 为 my-ponent('my-component', MyComponent)
&p class=&tip&&对于自定义标签名字,Vue.js 不强制要求遵循 (小写,并且包含一个短杠),尽管遵循这个规则比较好。
组件在注册之后,便可以在父实例的模块中以自定义元素 &my-component& 的形式使用。要确保在初始化根实例之前注册了组件:
&div id=&example&&
&my-component&&/my-component&
var MyComponent = Vue.extend({
template: '&div&A custom component!&/div&'
ponent('my-component', MyComponent)
// 创建根实例
el: '#example'
}) 渲染为:
&div id=&example&&
&div&A custom component!&/div&
注意组件的模板替换了自定义元素,自定义元素的作用只是作为一个挂载点。可以用实例选项 replace 决定是否替换。
不需要全局注册每个组件。可以让组件只能用在其它组件内,用实例选项 components 注册:
var Child = Vue.extend({ /* ... */ })
var Parent = Vue.extend({
template: '...',
components: {
// &my-component& 只能用在父组件模板内
'my-component': Child
}) 这种封装也适用于其它资源,如指令、过滤器和过渡。
注册语法糖
为了让事件更简单,可以直接传入选项对象而不是构造器给 <ponent() 和 component 选项。Vue.js 在背后自动调用 Vue.extend():
// 在一个步骤中扩展与注册
ponent('my-component', {
template: '&div&A custom component!&/div&'
// 局部注册也可以这么做
var Parent = Vue.extend({
components: {
'my-component': {
template: '&div&A custom component!&/div&'
组件选项问题
传入 Vue 构造器的多数选项也可以用在 Vue.extend() 中,不过有两个特例: data 和 el。试想如果我们简单地把一个对象作为 data 选项传给 Vue.extend():
var data = { a: 1 }
var MyComponent = Vue.extend({
data: data
}) 这么做的问题是 `MyComponent` 所有的实例将共享同一个 `data` 对象!这基本不是我们想要的,因此我们应当使用一个函数作为 `data` 选项,让这个函数返回一个新对象:
var MyComponent = Vue.extend({
data: function () {
return { a: 1 }
}) 同理,`el` 选项用在 `Vue.extend()` 中时也须是一个函数。
Vue 的模板是 DOM 模板,使用浏览器原生的解析器而不是自己实现一个。相比字符串模板,DOM 模板有一些好处,但是也有问题,它必须是有效的 HTML 片段。一些 HTML 元素对什么元素可以放在它里面有限制。常见的限制:
a 不能包含其它的交互元素(如按钮,链接)
ul 和 ol 只能直接包含 li
select 只能包含 option 和 optgroup
table 只能直接包含 thead, tbody, tfoot, tr, caption, col, colgroup
tr 只能直接包含 th 和 td
在实际中,这些限制会导致意外的结果。尽管在简单的情况下它可能可以工作,但是你不能依赖自定义组件在浏览器验证之前的展开结果。例如 &my-select&&option&...&/option&&/my-select& 不是有效的模板,即使 my-select 组件最终展开为 &select&...&/select&。
另一个结果是,自定义标签(包括自定义元素和特殊标签,如 &component&、&template&、 &partial& )不能用在 ul, select, table 等对内部元素有限制的标签内。放在这些元素内部的自定义标签将被提到元素的外面,因而渲染不正确。
对于自定义元素,应当使用 is 特性:
&tr is=&my-component&&&/tr&
&/table& `` 不能用在 `` 内,这时应使用 ``,` ` 可以有多个 ``:
&tbody v-for=&item in items&&
&tr&Even row&/tr&
&tr&Odd row&/tr&
使用 Props 传递数据
组件实例的作用域是孤立的。这意味着不能并且不应该在子组件的模板内直接引用父组件的数据。可以使用 props 把数据传给子组件。
“prop” 是组件数据的一个字段,期望从父组件传下来。子组件需要显式地用
声明 props:
<ponent('child', {
// 声明 props
props: ['msg'],
// prop 可以用在模板内
// 可以用 `this.msg` 设置
template: '&span&{{ msg }}&/span&'
}) 然后向它传入一个普通字符串:
&child msg=&hello!&&&/child&
驼峰式vs.横杠式
HTML 特性不区分大小写。名字形式为 camelCase 的 prop 用作特性时,需要转为 kebab-case(短横线隔开):
<ponent('child', {
// camelCase in JavaScript
props: ['myMessage'],
template: '&span&{{ myMessage }}&/span&'
&!-- kebab-case in HTML --&
&child my-message=&hello!&&&/child&
动态 Props
类似于用 v-bind 绑定 HTML 特性到一个表达式,也可以用 v-bind 绑定动态 Props 到父组件的数据。每当父组件的数据变化时,也会传导给子组件:
&input v-model=&parentMsg&&
&child v-bind:my-message=&parentMsg&&&/child&
&/div& 使用 `v-bind` 的缩写语法通常更简单:
&child :my-message=&parentMsg&&&/child&
字面量语法 vs. 动态语法
初学者常犯的一个错误是使用字面量语法传递数值:
&!-- 传递了一个字符串 &1& --&
&comp some-prop=&1&&&/comp& 因为它是一个字面 prop,它的值以字符串 `”1”` 而不是以实际的数字传下去。如果想传递一个实际的 JavaScript 数字,需要使用动态语法,从而让它的值被当作 JavaScript 表达式计算:
&!-- 传递实际的数字 --&
&comp :some-prop=&1&&&/comp&
Prop 绑定类型
prop 默认是单向绑定:当父组件的属性变化时,将传导给子组件,但是反过来不会。这是为了防止子组件无意修改了父组件的状态——这会让应用的数据流难以理解。不过,也可以使用 .sync 或 .once 绑定修饰符显式地强制双向或单次绑定:
比较语法:
&!-- 默认为单向绑定 --&
&child :msg=&parentMsg&&&/child&
&!-- 双向绑定 --&
&child :msg.sync=&parentMsg&&&/child&
&!-- 单次绑定 --&
&child :msg.once=&parentMsg&&&/child&
双向绑定会把子组件的 msg 属性同步回父组件的 parentMsg 属性。单次绑定在建立之后不会同步之后的变化。
注意如果 prop 是一个对象或数组,是按引用传递。在子组件内修改它会影响父组件的状态,不管是使用哪种绑定类型。
组件可以为 props 指定验证要求。当组件给其他人使用时这很有用,因为这些验证要求构成了组件的 API,确保其他人正确地使用组件。此时 props 的值是一个对象,包含验证要求:
<ponent('example', {
// 基础类型检测 (`null` 意思是任何类型都可以)
propA: Number,
// 多种类型 (1.0.21+)
propM: [String, Number],
// 必需且是字符串
type: String,
required: true
// 数字,有默认值
type: Number,
default: 100
// 对象/数组的默认值应当由一个函数返回
type: Object,
default: function () {
return { msg: 'hello' }
// 指定这个 prop 为双向绑定
// 如果绑定类型不对将抛出一条警告
twoWay: true
// 自定义验证函数
validator: function (value) {
return value & 10
// 转换函数(1.0.12 新增)
// 在设置值之前转换值
coerce: function (val) {
return val + '' // 将值转换为字符串
coerce: function (val) {
return JSON.parse(val) // 将 JSON 字符串转换为对象
type 可以是下面原生构造器:
type 也可以是一个自定义构造器,使用 instanceof 检测。
当 prop 验证失败了,Vue 将拒绝在子组件上设置此值,如果使用的是开发版本会抛出一条警告。
父子组件通信
子组件可以用 this.$parent 访问它的父组件。根实例的后代可以用 this.$root 访问它。父组件有一个数组 this.$children,包含它所有的子元素。
尽管可以访问父链上任意的实例,不过子组件应当避免直接依赖父组件的数据,尽量显式地使用 props 传递数据。另外,在子组件中修改父组件的状态是非常糟糕的做法,因为:
这让父组件与子组件紧密地耦合;
只看父组件,很难理解父组件的状态。因为它可能被任意子组件修改!理想情况下,只有组件自己能修改它的状态。
自定义事件
Vue 实例实现了一个自定义事件接口,用于在组件树中通信。这个事件系统独立于原生 DOM 事件,用法也不同。
每个 Vue 实例都是一个事件触发器:
使用 $on() 监听事件;
使用 $emit() 在它上面触发事件;
使用 $dispatch() 派发事件,事件沿着父链冒泡;
使用 $broadcast() 广播事件,事件向下传导给所有的后代。
不同于 DOM 事件,Vue 事件在冒泡过程中第一次触发回调之后自动停止冒泡,除非回调明确返回 true。
简单例子:
&!-- 子组件模板 --&
&template id=&child-template&&
&input v-model=&msg&&
&button v-on:click=&notify&&Dispatch Event&/button&
&/template&
&!-- 父组件模板 --&
&div id=&events-example&&
&p&Messages: {{ messages | json }}&/p&
&child&&/child&
// 注册子组件
// 将当前消息派发出去
ponent('child', {
template: '#child-template',
data: function () {
return { msg: 'hello' }
methods: {
notify: function () {
if (this.msg.trim()) {
this.$dispatch('child-msg', this.msg)
this.msg = ''
// 初始化父组件
// 将收到消息时将事件推入一个数组
var parent = new Vue({
el: '#events-example',
messages: []
// 在创建实例时 `events` 选项简单地调用 `$on`
'child-msg': function (msg) {
// 事件回调内的 `this` 自动绑定到注册它的实例上
this.messages.push(msg)
使用 v-on 绑定自定义事件
上例非常好,不过从父组件的代码中不能直观的看到 &child-msg& 事件来自哪里。如果我们在模板中子组件用到的地方声明事件处理器会更好。为此子组件可以用 v-on 监听自定义事件:
&child v-on:child-msg=&handleIt&&&/child& 这样就很清楚了:当子组件触发了 `”child-msg”` 事件,父组件的 `handleIt` 方法将被调用。所有影响父组件状态的代码放到父组件的 `handleIt` 方法中;子组件只关注触发事件。
子组件索引
尽管有 props 和 events,但是有时仍然需要在 JavaScript 中直接访问子组件。为此可以使用 v-ref 为子组件指定一个索引 ID。例如:
&div id=&parent&&
&user-profile v-ref:profile&&/user-profile&
var parent = new Vue({ el: '#parent' })
// 访问子组件
var child = parent.$refs.profile
v-ref 和 v-for 一起用时,ref 是一个数组或对象,包含相应的子组件。
使用 Slot 分发内容
在使用组件时,常常要像这样组合它们:
&app-header&&/app-header&
&app-footer&&/app-footer&
注意两点:
&app& 组件不知道它的挂载点会有什么内容,挂载点的内容是由 &app& 的父组件决定的。
&app& 组件很可能有它自己的模板。
为了让组件可以组合,我们需要一种方式来混合父组件的内容与子组件自己的模板。这个处理称为内容分发(或 “transclusion”,如果你熟悉 Angular)。Vue.js 实现了一个内容分发 API,参照了当前 ,使用特殊的 &slot& 元素作为原始内容的插槽。
编译作用域
在深入内容分发 API 之前,我们先明确内容的编译作用域。假定模板为:
&child-component&
&/child-component&
msg 应该绑定到父组件的数据,还是绑定到子组件的数据?答案是父组件。组件作用域简单地说是:
父组件模板的内容在父组件作用域内编译;子组件模板的内容在子组件作用域内编译
一个常见错误是试图在父组件模板内将一个指令绑定到子组件的属性/方法:
&!-- 无效 --&
&child-component v-show=&someChildProperty&&&/child-component&
假定 someChildProperty 是子组件的属性,上例不会如预期那样工作。父组件模板不应该知道子组件的状态。
如果要绑定子组件内的指令到一个组件的根节点,应当在它的模板内这么做:
<ponent('child-component', {
// 有效,因为是在正确的作用域内
template: '&div v-show=&someChildProperty&&Child&/div&',
data: function () {
someChildProperty: true
}) 类似地,分发内容是在父组件作用域内编译。
父组件的内容将被抛弃,除非子组件模板包含 &slot&。如果子组件模板只有一个没有特性的 slot,父组件的整个内容将插到 slot 所在的地方并替换它。
&slot& 标签的内容视为回退内容。回退内容在子组件的作用域内编译,当宿主元素为空并且没有内容供插入时显示这个回退内容。
假定 my-component 组件有下面模板:
&h1&This is my component!&/h1&
如果没有分发内容则显示我。
&/div& 父组件模板:
&my-component&
&p&This is some original content&/p&
&p&This is some more original content&/p&
&/my-component& 渲染结果:
&h1&This is my component!&/h1&
&p&This is some original content&/p&
&p&This is some more original content&/p&
&slot& 元素可以用一个特殊特性 name 配置如何分发内容。多个 slot 可以有不同的名字。具名 slot 将匹配内容片段中有对应 slot 特性的元素。
仍然可以有一个匿名 slot,它是默认 slot,作为找不到匹配的内容片段的回退插槽。如果没有默认的 slot,这些找不到匹配的内容片段将被抛弃。
例如,假定我们有一个 multi-insertion 组件,它的模板为:
&slot name=&one&&&/slot&
&slot&&/slot&
&slot name=&two&&&/slot&
&/div& 父组件模板:
&multi-insertion&
&p slot=&one&&One&/p&
&p slot=&two&&Two&/p&
&p&Default A&/p&
&/multi-insertion& 渲染结果为:
&p slot=&one&&One&/p&
&p&Default A&/p&
&p slot=&two&&Two&/p&
&/div& 在组合组件时,内容分发 API 是非常有用的机制。
多个组件可以使用同一个挂载点,然后动态地在它们之间切换。使用保留的 &component& 元素,动态地绑定到它的 is 特性:
el: 'body',
currentView: 'home'
components: {
home: { /* ... */ },
posts: { /* ... */ },
archive: { /* ... */ }
&component :is=&currentView&&
&!-- 组件在 vm.currentview 变化时改变 --&
&/component&
keep-alive
如果把切换出去的组件保留在内存中,可以保留它的状态或避免重新渲染。为此可以添加一个 keep-alive 指令参数:
&component :is=&currentView& keep-alive&
&!-- 非活动组件将被缓存 --&
&/component&
activate 钩子
在切换组件时,切入组件在切入前可能需要进行一些异步操作。为了控制组件切换时长,给切入组件添加 activate 钩子:
<ponent('activate-example', {
activate: function (done) {
var self = this
loadDataAsync(function (data) {
self.someData = data
}) 注意 `activate` 钩子只作用于动态组件切换或静态组件初始化渲染的过程中,不作用于使用实例方法手工插入的过程中。
transition-mode
transition-mode 特性用于指定两个动态组件之间如何过渡。
在默认情况下,进入与离开平滑地过渡。这个特性可以指定另外两种模式:
in-out:新组件先过渡进入,等它的过渡完成之后当前组件过渡出去。
out-in:当前组件先过渡出去,等它的过渡完成之后新组件过渡进入。
&!-- 先淡出再淡入 --&
&component
:is=&view& transition=&fade& transition-mode=&out-in&&
&/component&
.fade-transition { transition: opacity .3 }
.fade-enter, .fade-leave { opacity: 0; }
组件和 v-for
自定义组件可以像普通元素一样直接使用 v-for:
&my-component v-for=&item in items&&&/my-component&
但是,不能传递数据给组件,因为组件的作用域是孤立的。为了传递数据给组件,应当使用 props:
&my-component
v-for=&item in items& :item=&item& :index=&$index&&
&/my-component&
不自动把 item 注入组件的原因是这会导致组件跟当前 v-for 紧密耦合。显式声明数据来自哪里可以让组件复用在其它地方。
编写可复用组件
在编写组件时,记住是否要复用组件有好处。一次性组件跟其它组件紧密耦合没关系,但是可复用组件应当定义一个清晰的公开接口。
Vue.js 组件 API 来自三部分——prop,事件和 slot:
prop 允许外部环境传递数据给组件;
事件 允许组件触发外部环境的 action;
slot 允许外部环境插入内容到组件的视图结构内。
使用 v-bind 和 v-on 的简写语法,模板的缩进清楚且简洁:
&my-component
:foo=&baz& :bar=&qux& @event-a=&doThis& @event-b=&doThat&&
&!-- content --&
&img slot=&icon& src=&...&&
&p slot=&main-text&&Hello!&/p&
&/my-component&
在大型应用中,我们可能需要将应用拆分为小块,只在需要时才从服务器下载。为了让事情更简单,Vue.js 允许将组件定义为一个工厂函数,动态地解析组件的定义。Vue.js 只在组件需要渲染时触发工厂函数,并且把结果缓存起来,用于后面的再次渲染。例如:
<ponent('async-example', function (resolve, reject) {
setTimeout(function () {
template: '&div&I am async!&/div&'
工厂函数接收一个 resolve 回调,在收到从服务器下载的组件定义时调用。也可以调用 reject(reason) 指示加载失败。这里 setTimeout 只是为了演示。怎么获取组件完全由你决定。推荐配合使用 :
<ponent('async-webpack-example', function (resolve) {
// 这个特殊的 require 语法告诉 webpack
// 自动将编译后的代码分割成不同的块,
// 这些块将通过 ajax 请求自动下载。
require(['./my-async-component'], resolve)
资源命名约定
一些资源,如组件和指令,是以 HTML 特性或 HTML 自定义元素的形式出现在模板中。因为 HTML 特性的名字和标签的名字不区分大小写,所以资源的名字通常需使用 kebab-case 而不是 camelCase 的形式,这不大方便。
Vue.js 支持资源的名字使用 camelCase 或 PascalCase 的形式,并且在模板中自动将它们转为 kebab-case(类似于 prop 的命名约定):
// 在组件定义中
components: {
// 使用 camelCase 形式注册
myComponent: { /*... */ }
&!-- 在模板中使用 kebab-case 形式 --&
&my-component&&/my-component&
也没问题:
// PascalCase
import TextBox from './components/text-box';
import DropdownMenu from './components/dropdown-menu';
export default {
components: {
// 在模板中写作 &text-box& 和 &dropdown-menu&
DropdownMenu
组件在它的模板内可以递归地调用自己,不过,只有当它有 name 选项时才可以:
var StackOverflow = Vue.extend({
name: 'stack-overflow',
// 递归地调用它自己
'&stack-overflow&&/stack-overflow&' +
上面组件会导致一个错误 “max stack size exceeded”,所以要确保递归调用有终止条件。当使用 <ponent() 全局注册一个组件时,组件 ID 自动设置为组件的 name 选项。
在使用 template 选项时,模板的内容将替换实例的挂载元素。因而推荐模板的顶级元素始终是单个元素。
不这么写模板:
&div&root node 1&/div&
&div&root node 2&/div&
推荐这么写:
I have a single root node!
&div&node 1&/div&
&div&node 2&/div&
下面几种情况会让实例变成一个片断实例:
模板包含多个顶级元素。
模板只包含普通文本。
模板只包含其它组件(其它组件可能是一个片段实例)。
模板只包含一个元素指令,如 &partial& 或 vue-router 的 &router-view&。
模板根节点有一个流程控制指令,如 v-if 或 v-for。
这些情况让实例有未知数量的顶级元素,它将把它的 DOM 内容当作片断。片断实例仍然会正确地渲染内容。不过,它没有一个根节点,它的 $el 指向一个锚节点,即一个空的文本节点(在开发模式下是一个注释节点)。
但是更重要的是,组件元素上的非流程控制指令,非 prop 特性和过渡将被忽略,因为没有根元素供绑定:
&!-- 不可以,因为没有根元素 --&
&example v-show=&ok& transition=&fade&&&/example&
&!-- props 可以 --&
&example :prop=&someData&&&/example&
&!-- 流程控制可以,但是不能有过渡 --&
&example v-if=&ok&&&/example&
当然片断实例有它的用处,不过通常给组件一个根节点比较好。它会保证组件元素上的指令和特性能正确地转换,同时性能也稍微好些。
如果子组件有 inline-template 特性,组件将把它的内容当作它的模板,而不是把它当作分发内容。这让模板更灵活。
&my-component inline-template&
&p&These are compiled as the component's own template&/p&
&p&Not parent's transclusion content.&/p&
&/my-component&
但是 inline-template 让模板的作用域难以理解,并且不能缓存模板编译结果。最佳实践是使用 template 选项在组件内定义模板。
什么是组件? 组件(Component)是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素,封装可重用的代码。在较高层面上,组件是自定义元素,Vue.js 的编译器为它添加特殊功能。在有些情况下,
相关阅读排行
相关内容推荐
请激活账号
为了能正常使用评论、编辑功能及以后陆续为用户提供的其他产品,请激活账号。
您的注册邮箱:
如果您没有收到激活邮件,请注意检查垃圾箱。君,已阅读到文档的结尾了呢~~
扫扫二维码,随身浏览文档
手机或平板扫扫即可继续访问
Vue&#46;js组件化开发
举报该文档为侵权文档。
举报该文档含有违规或不良信息。
反馈该文档无法正常浏览。
举报该文档为重复文档。
推荐理由:
将文档分享至:
分享完整地址
文档地址:
粘贴到BBS或博客
flash地址:
支持嵌入FLASH地址的网站使用
html代码:
&embed src='/DocinViewer--144.swf' width='100%' height='600' type=application/x-shockwave-flash ALLOWFULLSCREEN='true' ALLOWSCRIPTACCESS='always'&&/embed&
450px*300px480px*400px650px*490px
支持嵌入HTML代码的网站使用
您的内容已经提交成功
您所提交的内容需要审核后才能发布,请您等待!
3秒自动关闭窗口Vue.js说说组件
来源:博客园
什么是组件:组件是Vue.js最强大的功能之一。组件可以扩展HTML元素,封装可重用的代码。在较高层面上,组件是自定义的元素,Vue.js的编译器为它添加特殊功能。在有些情况下,组件也可以是原生HTML元素的形式,以is特性扩展。&#13;
如何注册组件?&#13;
需要使用Vue.extend方法创建一个组件,然后使用ponent方法注册组件。Vue.extend方法格式如下:&#13;&#13;var MyComponent = Vue.extend({&#13;
// 选项...后面再介绍&#13;})&#13;&#13;
如果想要其他地方使用这个创建的组件,还得个组件命个名:&#13;&#13;<ponent('my-component', MyComponent)&#13;&#13;
命名之后即可在HTML标签中使用这个组件名称,像使用DOM元素一样。下面来看看一个完整的组件注册和使用例子。&#13;
html代码:&#13;&#13;&div id="example"&&#13;
&my-component&&/my-component&&#13;&/div&&#13;&#13;
js代码:&#13;&#13;// 定义&#13;var MyComponent = Vue.extend({&#13;
template: '&div&A custom component!&/div&'&#13;})&#13;&#13;// 注册&#ponent('my-component', MyComponent)&#13;&#13;// 创建根实例&#13;new Vue({&#13;
el: '#example'&#13;})&#13;&#13;
输出结果:&#13;&#13;&div id="example"&&#13;
&div&A custom component!&/div&&#13;&/div&#13;&#13;
嵌套组件&#13;
组件本身也可以包含组件,下面的parent组件就包含了一个命名为child-component组件,但这个组件只能被parent组件使用:&#13;&#13;var child = Vue.extend({&#13;
template: '&div&A custom component!&/div&'&#13;});&#13;var parent = Vue.extend({&#13;
template: '&div&Parent Component: &child-component&&/child-component&&/div&',&#13;
components: {&#13;
'child-component': child&#13;
}&#13;});&#ponent("parent-component", parent);&#13;&#13;
上面的定义过程比较繁琐,也可以不用每次都调用ponent和Vue.extend方法:&#13;&#13;// 在一个步骤中扩展与注册&#ponent('my-component', {&#13;template: '&div&A custom component!&/div&'&#13;})&#13;&#13;// 局部注册也可以这么做&#13;var Parent = Vue.extend({&#13;
components: {&#13;
'my-component': {&#13;
template: '&div&A custom component!&/div&'&#13;
}&#13;})&#13;&#13;
动态组件&#13;
多个组件可以使用同一个挂载点,然后动态的在他们之间切换。使用保留的&component&元素,动态地绑定到它的is特性。下面的列子在同一个vue实例下挂了home、posts、archive三个组件,通过特性currentView动态切换组件显示。&#13;
html代码:&#13;&#13;&div id="dynamic"&&#13;
&button id="home"&Home&/button&&#13;
&button id="posts"&Posts&/button&&#13;
&button id="archive"&Archive&/button&&#13;
&component :is="currentView"&&/component&&#13;&/div&&#13;&#13;
js代码:&#13;&#13;var vue = new Vue({&#13;
el:"#dynamic",&#13;
data: {&#13;
currentView: "home"&#13;
components: {&#13;
home:{&#13;
template: "Home"&#13;
posts: {&#13;
template: "Posts"&#13;
archive: {&#13;
template: "Archive"&#13;
}&#13;});&#13;document.getElementById("home").onclick = function(){&#13;vue.currentView = "home";&#13;};&#13;document.getElementById("posts").onclick = function(){&#13;vue.currentView = "posts";&#13;};&#13;document.getElementById("archive").onclick = function(){&#13;vue.currentView = "archive";&#13;};&#13;&#13;
组件和v-for&#13;&#13;&my-component v-for="item in items"&&/my-component&&#13;&#13;
不能传递数据给组件,因为组件的作用域是独立的。为了传递数据给组件,应当使用props:&#13;&#13;&my-component&#13;v-for="item in items"&#13;:item="item"&#13;:index="$index"&&#13;&/my-component&&#13;&#13;
不自动把 item 注入组件的原因是这会导致组件跟当前 v-for 紧密耦合。显式声明数据来自哪里可以让组件复用在其它地方。&#13;
深入响应式原理&#13;
在组件绑定数据时,如何绑定才能够有效,并且可动态修改、添加属性?看看下面的原理介绍。&#13;
如何追踪变化:把一个不同对象传给vue实例作为data的选项,vue.js将遍历它的属性,用Object.defineProperty将它转换为getter/setter。这是ES5特性,所有vue.js不支持IE8或更低版本。
模板中每个指令/数据绑定都有一个对应的watcher对象,在计算过程中它把属性记录为依赖。之后当依赖的setter被调用时 ,会触发watcher重新计算。流程如下所示:&#13;&#13;
变化检测问题:vue.js不能检测到对象属性的添加或删除,属性必须在data上才能让vue.js转换它为getter/setter模式,才能有响应。例如:&#13;&#13;var data = { a: 1 };&#13;var vm = new Vue({&#13;data: data&#13;});&#13;// `vm.a` 和 `data.a` 现在是响应的&#13;vm.b = 2&#13;// `vm.b` 不是响应的&#13;data.b = 2&#13;// `data.b` 不是响应的&#13;&#13;
不过,也有办法在实例创建后添加属性并且让它是相应的。可以使用set(key,value)实例方法:&#13;&#13;vm. set('b', 2)&#13;// `vm.b` 和 `data.b` 现在是响应的&#13;&#13;
对于普通对象可以使用全局方法:Vue.set(object, key, value):&#13;&#13;Vue.set(data, 'c', 3)&#13;// `vm.c` 和 `data.c` 现在是响应的&#13;&#13;
初始化数据:尽管Vue.js提供动态的添加相应属性,还是推荐在data对象上声明所有的相应属性。&#13;
不这么做:&#13;&#13;var vm = new Vue({&#13;
template: '&div&{{msg}}&/div&'&#13;})&#13;// 然后添加 `msg`&#13;vm.$set('msg', 'Hello!')&#13;&#13;
应该这么做:&#13;&#13;var vm = new Vue({&#13;
data: {&#13;
// 以一个空值声明 `msg`&#13;
msg: ''&#13;
template: '&div&{{msg}}&/div&'&#13;})&#13;// 然后设置 `msg`&#13;vm.msg = 'Hello!'&#13;&#13;
组件完整案例&#13;
下面介绍的例子实现了模态窗口功能,代码也比较简单。&#13;
html代码:&#13;&#13;&!-- 实现script定义一个模板 --&&#13;&script type="x/template" id="modal-template"&&#13;
&!--模板是否显示通过v-show="show"来设置, transition设置动画效果--&&#13;
&div class="modal-mask" v-show="show" transition="modal"&&#13;
&div class="modal-wrapper"&&#13;
&div class="modal-container"&&#13;
&div class="modal-header"&&#13;
&!--slot 相当于header占位符--&&#13;
&slot name="header"&&#13;
default header&#13;
&/slot&&#13;
&/div&&#13;
&div class="modal-body"&&#13;
&!--slot 相当于body占位符--&&#13;
&slot name="body"&&#13;
default body&#13;
&/slot&&#13;
&/div&&#13;
&div class="modal-footer"&&#13;
&!--slot 相当于footer占位符--&&#13;
&slot name="footer"&&#13;
default footer&#13;
&/slot&&#13;
&button class="modal-default-button" @click="show = false"&OK&/button&&#13;
&/div&&#13;
&/div&&#13;
&/div&&#13;
&/div&&#13;&/script&&#13;&div id="app"&&#13;
&!--点击按钮时设置vue实例特性showModal的值为true--&&#13;
&button id="show-modal" @click="showModal = true"&show modal&/button&&#13;
&!--modal是自定义的一个插件,插件的特性show绑定vue实例的showModal特性--&&#13;
&modal :show.sync="showModal"&&#13;
&!--替换modal插件中slot那么为header的内容--&&#13;
&h3 slot="header"&Custom Header&/h3&&#13;
&/modal&&#13;&/div&&#13;&#13;
js代码:&#13;&#13;//定义一个插件,名称为modal&#ponent("modal", {&#13;
//插件的模板绑定id为modal-template的DOM元素内容&#13;
template: "#modal-template",&#13;
props: {&#13;
//特性,类型为布尔&#13;
show:{&#13;
type: Boolean,&#13;
required: true,&#13;
twoWay: true&#13;
}&#13;});&#13;//实例化vue,作用域在id为app元素下,&#13;new Vue({&#13;
el: "#app",&#13;
data: {&#13;
//特性,默认值为false&#13;
showModal: false&#13;
}&#13;});&#13;&#13;
css代码:&#13;&#13;.modal-mask {&#13;
position: fixed;&#13;
z-index: 9998;&#13;
top: 0;&#13;
left: 0;&#13;
width: 100%;&#13;
height: 100%;&#13;
background-color: rgba(0, 0, 0, .5);&#13;
display: table;&#13;
transition: opacity .3s ease;&#13;}&#13;&#13;.modal-wrapper {&#13;
display: table-cell;&#13;
vertical-align: middle;&#13;}&#13;&#13;.modal-container {&#13;
width: 300px;&#13;
margin: 0px auto;&#13;
padding: 20px 30px;&#13;
background-color: #fff;&#13;
border-radius: 2px;&#13;
box-shadow: 0 2px 8px rgba(0, 0, 0, .33);&#13;
transition: all .3s ease;&#13;
font-family: Helvetica, Arial, sans-serif;&#13;}&#13;&#13;.modal-header h3 {&#13;
margin-top: 0;&#13;
color: #42b983;&#13;}&#13;&#13;.modal-body {&#13;
margin: 20px 0;&#13;}&#13;&#13;.modal-default-button {&#13;
float: right;&#13;}&#13;&#13;/*&#13;* the following styles are auto-applied to elements with&#13;* v-transition="modal" when their visiblity is toggled&#13;* by Vue.js.&#13;*&#13;* You can easily play with the modal transition by editing&#13;* these styles.&#13;*/&#13;&#13;.modal-enter, .modal-leave {&#13;
opacity: 0;&#13;}&#13;&#13;.modal-enter .modal-container,&#13;.modal-leave .modal-container {&#13;
-webkit-transform: scale(1.1);&#13;
transform: scale(1.1);&#13;}&#13;&#13;
由于自己在项目中还没怎么深入使用组件的功能,所以自己对组件的理解也不深入,介绍的比较肤浅,忽喷。&#13; &#13;
如果本篇内容对大家有帮助,请点击页面右下角的关注。如果觉得不好,也欢迎拍砖。你们的评价就是博主的动力!下篇内容,敬请期待!
免责声明:本站部分内容、图片、文字、视频等来自于互联网,仅供大家学习与交流。相关内容如涉嫌侵犯您的知识产权或其他合法权益,请向本站发送有效通知,我们会及时处理。反馈邮箱&&&&。
学生服务号
在线咨询,奖学金返现,名师点评,等你来互动}

我要回帖

更多关于 vue组件引入html 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信