组件基础

1、基本示例

<div id="id1">
    <button-counter></button-counter>
</div>
//定义一个名为button-counter的新组件
    Vue.component('button-counter',{
        data:function () {
            return {
                count:0
            }
        },
        template:'<button v-on:click="count++">you clicked me {{count}} times.</button>'
    })


    //调用
    new Vue({el:"#id1"})

       因为组件是可复用的 Vue 实例,所以它们与 new Vue 接收相同的选项,例如 data、computed、watch、methods 以及生命周期钩子等。仅有的例外是像 el 这样根实例特有的选项。

注:一个组件的data选项必须是一个函数。因此每个实例可以维护一份被返回对象的独立的拷贝。

2、组件的复用

可以将组件进行任意次数的复用:

<div id="id1">
    <button-counter></button-counter>
    <button-counter></button-counter>
    <button-counter></button-counter>
    <button-counter></button-counter>
</div>

注:当点击按钮时,每个组件都会各自独立维护它的count。因为每用一次组件,就会有一个它的新实例被创建。

3、通过Prop向子组件传递数据

Prop——是可以在组件上注册的一些自定义特性。当一个值传递给一个prop特性的时候,它就变成了那个组件实例的一个属性。

<!--通过 Prop 向子组件传递数据-->
<div id="id2">
    <blog-post v-for="post in posts" v-bind:key="post.id" v-bind:title="post.title"></blog-post>
</div>
//通过 Prop 向子组件传递数据,为组件传递一个标题
    Vue.component('blog-post',{
        props:['title'],
        template:'<h3>{{title}}</h3>'
    })
    new Vue({
        el:"#id2",
        data:{
            posts:[
                {id:1,title:'h1'},
                {id:2,title:'h2'},
                {id:3,title:'h3'}
            ]
        }
    })

4、单个根元素

       每个组件必须只有一个根元素——可以将模板的内容包裹在一个父元素内

       当组件变得越来越复杂的时候,不只需要标题和内容,还需要发布日期、评论等等。为每个相关的信息定义一个 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>
  `
})

5、通过事件向父级组件发送消息

       示例:引入一个可访问性的功能放大文字字号,同时让页面的其他部分保持默认的字号。在父组件中,添加一个postFontSize 数据属性来支持这个功能:

<!--通过事件向父级组件发送消息-->
<div id="id3">
    <div :style="{ fontSize: postFontSize + 'em' }">
        <wjy-post
                v-for="post in posts"
                v-bind:key="post.id"
                v-bind:post="post"
                v-on:enlarge-text="postFontSize += 0.1"
        ></wjy-post>
    </div>
</div>
//通过事件向父级组件发送消息
    //调用内建的 $emit 方法并传入事件的名字,来向父级组件触发一个事件
    Vue.component('wjy-post', {
        props: ['post'],
        template: `
            <div class="wjy-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:"#id3",
        data:{
            posts:[
                {id:1,title:'aaaaaaaaaaaa',content:'ddddd'},
                {id:2,title:'bbbbbbbbbbbb',content:'ddddd'},
                {id:3,title:'cccccccccccc',content:'ddddd'}
            ],
            postFontSize:1
        }
})

6、在组件上使用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>

为了让它正常工作,这个组件内的 <input> 必须:

  • 将其 value 特性绑定到一个名叫 value 的 prop 上
  • 在其 input 事件被触发时,将新的值通过自定义的 input 事件抛出

如:

<custom-input v-model="searchText"></custom-input>

Vue.component('custom-input', {
  props: ['value'],
  template: `
    <input
      v-bind:value="value"
    v-on:input="$emit('input', $event.target.value)"
   >
  `
 })

7、通过插槽分发内容——向一个组件传递内容<slot>

<alert-box>
  Something bad happened.
</alert-box>
//定义组件
Vue.component('alert-box', {
  template: `
    <div class="demo-alert-box">
      <strong>Error!</strong>
      <slot></slot>
    </div>
  `
})

8、解析DOM模板时的注意事项

       自定义的组件可能会被作为无效的内容提升到元素外部,导致渲染结果出错——is

       有些 HTML 元素,诸如 <ul><ol><table> 和 <select>,对于哪些元素可以出现在其内部是有严格限制的。而有些元素,诸如 <li><tr> 和 <option>,只能出现在其它某些特定的元素内部。

这会导致我们使用这些有约束条件的元素时遇到一些问题。例如:

<table>
  <blog-post-row></blog-post-row>
</table>

这个自定义组件 <blog-post-row> 会被作为无效的内容提升到外部,并导致最终渲染结果出错。幸好这个特殊的 is 特性给了我们一个变通的办法:

<table>
  <tr is="blog-post-row"></tr>
</table>

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值