标签:绑定 关于 jsf ide 严格 roo 完美 fonts 返回
<div id='components1'>
<button-conter></button-conter>
</div>
<script>
// 定义一个名为button-conter组件
Vue.component("button-conter",{
data:function () {
return {
count:0
}
},
template:`<button v-on:click="count++">You clicked me {{count}}</button>`
});
// 创建一个根实例
new Vue({el:"#components1"})
</script>
id=‘components1‘
的作用域中再定义<button-conter></button-conter>
也是可以的,并且它们彼此之间互不影响。new Vue
接收相同的选项,例如 data
、computed
、watch
、methods
以及生命周期钩子等。仅有的例外是像 el
这样根实例特有的选项。<div id="components-demo">
<button-counter></button-counter>
<button-counter></button-counter>
<button-counter></button-counter>
</div>
注意: 当点击按钮时,每个组件都会各自独立维护它的 count
。因为你每用一次组件,就会有一个它的新实例被创建。
组件时,你可能会发现它的
data` 并不是像这样直接提供一个对象:data: {
count: 0
}
取而代之的是,一个组件的 data
选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝:
data: function () {
return {
count: 0
}
}
通常一个应用会以一颗嵌套的组件树的形式来组织
例如,你可能会有页头、侧边栏、内容区等组件,每个组件又包含了其它的像导航链接、博文之类的组件。
为了能在模板中使用,这些组件必须先注册以便 Vue 能够识别。这里有两种组件的注册类型:全局注册和局部注册。至此,我们的组件都只是通过 Vue.component
全局注册的:
Vue.component('my-component-name', {
// ... options ...
})
全局注册的组件可以用在其被注册之后的任何 (通过 new Vue
) 新创建的 Vue 根实例,也包括其组件树中的所有子组件的模板中。
到目前为止,关于组件注册你需要了解的就这些了,如果你阅读完本页内容并掌握了它的内容,我们会推荐你再回来把组件注册读完。
props
选项将其包含在该组件可接受的 prop 列表中:Vue.component('blog-post', {
props: ['title'],
template: '<h3>{{ title }}</h3>'
})
一个组件默认可以拥有任意数量的 prop,任何值都可以传递给任何 prop。在上述模板中,你会发现我们能够在组件实例中访问这个值,就像访问 data
中的值一样。
一个 prop 被注册之后,你就可以像这样把数据作为一个自定义 attribute 传递进来:
<blog-post title="My journey with Vue"></blog-post>
<blog-post title="Blogging with Vue"></blog-post>
<blog-post title="Why Vue is so fun"></blog-post>
然而在一个典型应用中,你可能在data
里有一个博文数组:
<div id='components1'>
<button-conter></button-conter>
<blog-post v-for="post in posts"
v-bind:title="post.title"
v-bind:key="post.id"
></blog-post>
</div>
// 定义一个名为button-conter组件
Vue.component("button-conter",{
data:function () {
return {
count:0,
}
},
template:`<button v-on:click="count++">You clicked me {{count}}</button>`
});
Vue.component("blog-post",{
props:['title'],
template:`<h3>{{title}}</h3>`
})
// 创建一个根实例
new Vue({el:"#components1",
data:{
posts:[
{id:1,title:"My journey with Vue"},
{id:2,title:"Blogging with Vue"},
{id:3,title:"Why Vue is so fun"},
]
}
})
如上所示,你会发现我们可以使用 v-bind
来动态传递 prop。这在你一开始不清楚要渲染的具体内容,比如从一个 API 获取博文列表的时候,是非常有用的。
当构建一个 <blog-post>
组件时,你的模板最终会包含的东西远不止一个标题:
最最起码,你会包含这篇博文的正文:
<h3>{{ title }}</h3>
<div v-html="content"></div>
然而如果你在模板中尝试这样写,Vue 会显示一个错误,并解释道 every component must have a single root element (每个组件必须只有一个根元素)。你可以将模板的内容包裹在一个父元素内,来修复这个问题,例如:
<div class="blog-post">
<h3>{{ title }}</h3>
<div v-html="content"></div>
</div>
看起来当组件变得越来越复杂的时候,我们的博文不只需要标题和内容,还需要发布日期、评论等等。为每个相关的信息定义一个 prop 会变得很麻烦:
<blog-post
v-for="post in posts"
v-bind:key="post.id"
v-bind:title="post.title"
v-bind:content="post.content"
v-bind:publishedAt="post.publishedAt"
v-bind:comments="post.comments"
></blog-post>
所以是时候重构一下这个<blog-post>
组件了,让它变成接受一个单独的 post prop:
<blog-post
v-for="post in posts"
v-bind:key="post.id"
v-bind:post="post"
></blog-post>
Vue.component('blog-post', {
props: ['post'],
template: `
<div class="blog-post">
<h3>{{ post.title }}</h3>
<div v-html="post.content"></div>
</div>
`
})
上述的这个和一些接下来的示例使用了 JavaScript 的模板字符串来让多行的模板更易读。它们在 IE 下并没有被支持,所以如果你需要在不 (经过 Babel 或 TypeScript 之类的工具) 编译的情况下支持 IE,请使用折行转义字符取而代之。
现在,不论何时为 post
对象添加一个新的属性,它都会自动地在 <blog-post>
内可用。
在我们开发<blog-post>
组件时,它内部一些功能要求我们和父级组件进行沟通。比如在父组件定义字体大小,子组件中 引入一个辅助功能来放大博文的字号 ,同时页面其他字号保持默认
示例:
<div id='components1'>
<!--在父组件中,我们添加一个postFontSize数据属性来支持这个功能-->
<!--通过 v-on:enlarge-text="postFontSize += 0.1" 监听器,父级组件就会接收该事件并更新 postFontSize 的值-->
<div :style="{fontSize:postFontSize + 'em'}">
<blog-post v-for="post in posts"
v-bind:post="post"
v-bind:key="post.id"
v-on:enlarge-text="postFontSize += 0.1"
></blog-post>
</div>
</div>
Vue.component("blog-post",{
props:['post'],
// 每篇博文正文之前添加一个按钮来放大字号
// 同时子组件调用内建$emit方法传入事件名称
template:`<div class="blog-post">
<h3>{{post.title}}</h3>
<button v-on:click="$emit('enlarge-text')">Enlarge text</button>
<div v-html="post.content"></div>
</div>`
})
// 创建一个根实例
new Vue({el:"#components1",
data:{
posts:[
{id:1,title:"My journey with Vue",content:"<span>文章1</span>"},
{id:2,title:"Blogging with Vue",content:"<span>文章2</span>"},
{id:3,title:"Why Vue is so fun",content:"<span>文章3</span>"},
],
// 定义默认字体大小
postFontSize:1
}
})
例如我们想让<blog-post>
组件决定它的文本要放大多少,可以通过使用$emit
第二个参数提供这个值
<!--子组件定义传入放大的大小-->
<button v-on:click="$emit('enlarge-text', 0.1)">
Enlarge text
</button>
然后当父组件监听这个事件时候,我们通过$event
访问抛出这个值:
<blog-post
...
v-on:enlarge-text="postFontSize += $event"
></blog-post>
又或用函数去处理这个事件:
<blog-post
...
v-on:enlarge-text="onEnlargeText"
></blog-post>
// 那么这个值将会作为第一个参数传入这个方法
methods: {
onEnlargeText: function (enlargeAmount) {
this.postFontSize += enlargeAmount
}
}
v-model
自定义事件也可以用于创建支持 v-model
的自定义输入组件。
<input v-model="searchText">
等价于
<input
v-bind:value="searchText"
v-on:input="searchText = $event.target.value"
>
当用在组件上时,v-model
则会这样:
<custom-input
v-bind:value="searchText"
v-on:input="searchText = $event"
></custom-input>
为了让它正常工作,这个组件内的 `` 必须:
value
attribute 绑定到一个名叫 value
的 prop 上input
事件被触发时,将新的值通过自定义的 input
事件抛出写成代码之后是这样的:
Vue.component('custom-input', {
props: ['value'],
template: `
<input
v-bind:value="value"
v-on:input="$emit('input', $event.target.value)"
>
`
})
现在 v-model
就应该可以在这个组件上完美地工作起来了:
<custom-input v-model="searchText"></custom-input>
<div id="demo">
<alert-box>
Something bad happened
</alert-box>
</div>
Vue.component("alert-box",{
template:`
<div class="demo-alert-box">
你好啊!
</div>
`
});
new Vue({el:"#demo"})
我们定义<alert-box>
内的内容并没有打印出来,此时你只需要加入<slot></slot>
,这样内容都会打印出来。
Vue.component("alert-box",{
template:`
<div class="demo-alert-box">
你好啊!
<slot></slot>
</div>
`
});
new Vue({el:"#demo"})
<div id="app">
<button @click="change">切换</button>
<component :is="type"></component>
</div>
Vue.component("One",{
template:"<span>One</span>"
});
Vue.component("Two",{
template:"<span>Two</span>"
});
new Vue({
el:"#app",
data:{
type:"One"
},
methods:{
change:function () {
this.type = (this.type === "One"?"Two":"One")
}
}
})
有些 HTML 元素,诸如 、
、和
,对于哪些元素可以出现在其内部是有严格限制的。而有些元素,诸如 、 和
,只能出现在其它某些特定的元素内部。
这会导致我们使用这些有约束条件的元素时遇到一些问题。例如:
<table>
<blog-post-row></blog-post-row>
</table>
这个自定义组件 <blog-post-row>
会被作为无效的内容提升到外部,并导致最终渲染结果出错。幸好这个特殊的 is
attribute 给了我们一个变通的办法:
<table>
<tr is="blog-post-row"></tr>
</table>
参照文献:Vue.js组件基础
标签:绑定 关于 jsf ide 严格 roo 完美 fonts 返回
原文地址:https://www.cnblogs.com/xujunkai/p/12215961.html