博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

vue-学习笔记-组件(组件基础)

Posted on 2019-06-14 10:01  追风0315  阅读(323)  评论(0编辑  收藏  举报

本章节包括组件的:基本使用,组件的复用,组件组织,组件prop传参,切换,is特性,slot,事件绑定,v-model

基本使用:

组件是可复用的 Vue 实例,且带有一个名字

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

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

<div id="components-demo">
  <button-counter></button-counter>
</div>

new Vue({ el: '#components-demo' })

 

组件的复用


 

每个组件有独立的counter

data:必须是一个构造函数:如果写成对象,我这运行报错

data: function () {
  return {
    count: 0
  }
}

 

组件的组织


 

为了能在模板中使用,这些组件必须先注册以便 Vue 能够识别

两种组件的注册类型:全局注册(Vue.component)和局部注册

全局注册的组件

1:可以用在其被注册之后的任何 (通过 new Vue) 新创建的 Vue 根实例,

2:其组件树中的所有子组件的模板中

 

通过 Prop 向子组件传递数据


 

不给组件传递数据,组件是没意义的!

一个组件默认可以拥有任意数量的 prop,任何值都可以传递给任何 prop

Vue.component('blog-post', {
  props: ['title'],
  template: '<h3>{{ title }}</h3>'
})
<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>

 

 v-for例子

new Vue({
  el: '#blog-post-demo',
  data: {
    posts: [
      { id: 1, title: 'My journey with Vue' },
      { id: 2, title: 'Blogging with Vue' },
      { id: 3, title: 'Why Vue is so fun' }
    ]
  }
})
<blog-post
  v-for="post in posts"
  v-bind:key="post.id"
  v-bind:title="post.title"
></blog-post>

单个根元素(组件必须有一个根元素,类似angularjs指令)


可以传送一个post对象给props;v-for必须有key哈

下面的代码使用了ES6的模板字符串概念,如果不想Babel 或 TypeScript 之类的工具编译,请用换行转义字符

Vue.component('blog-post', {
  props: ['post'],
  template: `
    <div class="blog-post">
      <h3>{{ post.title }}</h3>
      <div v-html="post.content"></div>
    </div>
  `
})

监听子组件事件


 

 父组件:

<blog-post
  ...
  v-on:enlarge-text="postFontSize += 0.1"
></blog-post>

子组件:

<button v-on:click="$emit('enlarge-text')">
  Enlarge text
</button>

 

 使用事件抛出一个值:$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

<input v-model="searchText">

等价于

<input
  v-bind:value="searchText"
  v-on:input="searchText = $event.target.value"
>

用在组件上会是这个样子

<custom-input
  v-bind:value="searchText"
  v-on:input="searchText = $event"
></custom-input>
  • 将其 value 特性绑定到一个名叫 value 的 prop 上
  • 在其 input 事件被触发时,将新的值通过自定义的 input 事件抛出
写成代码是这样子
Vue.component('custom-input', { props: ['value'], template: ` <input v-bind:value="value" v-on:input="$emit('input', $event.target.value)" > ` })

 

 使用时候这个样子

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

通过插槽分发内容


 

Vue.component('alert-box', {
  template: `
    <div class="demo-alert-box">
      <strong>Error!</strong>
      <slot></slot>
    </div>
  `
})

html页面:

<alert-box>
  Something bad happened.
</alert-box>

 

效果:

动态组件(组件切换)


 

 

Vue 的 <component> 元素加一个特殊的 is 特性来实现:

其中currentTabComponent可以取值

  • 已注册组件的名字,或
  • 一个组件的选项对象
<!-- 组件会在 `currentTabComponent` 改变时改变 -->
<component v-bind:is="currentTabComponent"></component>

 

 

 

 

 

 

解析 DOM 模板时的注意事项(is问题)


 

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

 

错误的用法

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

正确的用法

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

 

需要注意的是如果我们从以下来源使用模板的话,这条限制是不存在的:

 

下面是单文件组件和template