iOS开发之笔记摘录跨平台

vue.js入门之第四篇(自定义组件)

2018-08-17  本文已影响0人  平安喜乐698
目录

除了可以使用普通html元素外,Vue还允许自定义组件(可以使用指令)

组件是可复用的 Vue 实例,每用一次组件就会有一个它的新实例被创建。
只能有一个跟元素
复用则data必须是个函数
  data: function () {
    return {
      count: 0
    }
  }

1、自定义全局组件

<div id="app">
        <!--2、使用全局组件-->
    <hello-world></hello-world>
</div>

<script>
// 1、注册全局组件,可在本页中使用
// 第一参数:组件名
// 第一种命名方式:全小写 加 连字符-(建议),使用<hello-world>
// 第二种命名方式:HelloWorld,使用<hello-world>或<HelloWorld>
Vue.component('hello-world', {
  template: '<h1>自定义组件!</h1>'
})

// 创建根实例
new Vue({
  el: '#app'
})
</script>

2、自定义局部组件

<div id="app">
        <!--2、使用局部组件-->
    <hello></hello >
</div>

<script>
var Child = {
  template: '<h1>自定义组件!</h1>'
}
// 创建根实例
new Vue({
  el: '#app',
  // 1、注册局部组件(仅在id为app中使用)
  components: {
    'hello': Child
  }
})
</script>
  1. 传递数据 [属性]
<div id="app">
    <child message="hello!"></child>
</div>
 
<script>
// 注册
Vue.component('child', {
  // 声明 props
  props: ['message'],
  // 同样也可以在 vm 实例中像 "this.message" 这样使用
  template: '<span>{{ message }}</span>'
})
// 创建根实例
new Vue({
  el: '#app'
})
</script>
  1. 传递数据(绑定属性)
<div id="app">
    <div>
      <input v-model="parentMsg">
      <br>
      <child v-bind:message="parentMsg"></child>
    </div>
</div>
 
<script>
// 注册
Vue.component('child', {
  // 声明 props
  props: ['message'],
  // 同样也可以在 vm 实例中像 "this.message" 这样使用
  template: '<span>{{ message }}</span>'
})
// 创建根实例
new Vue({
  el: '#app',
  data: {
    parentMsg: '父组件内容'
  }
})
</script>
  1. 传递数据(循环)
<div id="app">
    <ol>
      <todo-item v-for="item in sites" v-bind:todo="item"></todo-item>
    </ol>
</div>
 
<script>
Vue.component('todo-item', {
  props: ['todo'],
  template: '<li>{{ todo.text }}</li>'
})
new Vue({
  el: '#app',
  data: {
    sites: [
      { text: 'Runoob' },
      { text: 'Google' },
      { text: 'Taobao' }
    ]
  }
})
</script>
  1. is
有些 HTML 元素,诸如 <ul>、<ol>、<table> 和 <select>,对于哪些元素可以出现在其内部是有严格限制的。而有些元素,诸如 <li>、<tr> 和 <option>,只能出现在其它某些特定的元素内部。

这会导致我们使用这些有约束条件的元素时遇到一些问题。例如:
  <table>
    <customRow></customRow>
  </table>
这个自定义组件 <blog-post-row> 会被作为无效的内容提升到外部,并导致最终渲染结果出错。

注意:三种情况不存在这个限制:字符串、单文件组件.vue、<script type="text/x-template">
解决

<table>
  <tr is="customRow"></tr>
</table>
  1. v-model
<input v-model="searchText">
等价于:
<input
  v-bind:value="searchText"
  v-on:input="searchText = $event.target.value"
>
<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)"
    >
  '
})
  1. 插槽
<alert-box>
  Something bad happened.
</alert-box>

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

属性

1、html大小写不敏感,Vue中的驼峰属性名在html中要使用连字符-。{{}}不受限制

  <blog-post post-title="hello!"></blog-post>
  Vue.component('blog-post', {
    props: ['postTitle'],
    template: '<h3>{{ postTitle }}</h3>'
  })
2、属性类型type可以是:String、Number、Boolean、Function、Object、Array、Date、Symbol、一个自定义的构造函数
  当 prop 验证失败的时候,(开发环境构建版本的) Vue 将会产生一个控制台的警告
  prop 会在一个组件实例创建之前进行验证,所以实例的属性 (如 data、computed 等) 在 default 或 validator 函数中是不可用的

  Vue.component('example', {
    props: {
      // 基础类型检测 (`null` 意思是任何类型都可以)
      propA: Number,
      // 多种类型
      propB: [String, Number],
      // 必传且是字符串
      propC: {
        type: String,
        required: true
      },
      // 数字,有默认值
      propD: {
        type: Number,
        default: 100
      },
      // 数组/对象的默认值应当由一个工厂函数返回
      propE: {
        type: Object,
        default: function () {
          return { message: 'hello' }
        }
      },
      // 自定义验证函数
      propF: {
        validator: function (value) {
          return value > 10
        }
      }
    }
  })
3、传值(静态、动态)

<blog-post title="My journey with Vue"></blog-post>
<!-- 动态赋予一个变量的值 -->
<!-- 或者告诉Vue这不是个字符串而是表达式,如传递数值、Boolean、数组、对象-->
<blog-post v-bind:title="post"></blog-post>
<!-- 传入post对象的所有属性 -->
<blog-post v-bind="post"></blog-post>
4、组件可以接受任意特性
  因为组件并不总能预见组件会被用于怎样的场景。
  这些特性会被添加到这个组件的根元素上。

<blog-post title="My journey with Vue"></blog-post>
title会被加在根元素上
5、对于绝大多数特性来说,从外部提供给组件的值会替换掉组件内部设置好的值,即覆盖。class 和 style 则会合并。
6、禁用根元素的继承继承特性
  注意 inheritAttrs: false 选项不会影响 style 和 class 的绑定。

Vue.component('my-component', {
  inheritAttrs: false,
  props: ['label', 'value'],
  // ...
})
label、value不再从<my-component value=''>中获取


$attrs 属性包含了传递给一个组件的特性名和特性值
Vue.component('base-input', {
  inheritAttrs: false,
  props: ['label', 'value'],
  template: `
    <label>
      {{ label }}
      <input
        v-bind="$attrs"
        v-bind:value="value"
        v-on:input="$emit('input', $event.target.value)"
      >
    </label>
  `
})

方法(自定义事件)

  事件名不存在任何自动化的大小写转换,
  v-on 事件监听器在 DOM 模板中会被自动转换为全小写 (因为 HTML 是大小写不敏感的),所以 v-on:myEvent 将会变成 v-on:myevent——导致 myEvent 不可能被监听到。推荐使用全小写加连字符-

使用 $emit(eventName) 触发外部的事件


<div id="app">
    <div id="counter-event-example">
      <p>{{ total }}</p>
      <button-counter v-on:increment="incrementTotal"></button-counter>
      <button-counter v-on:increment="incrementTotal"></button-counter>
    </div>
</div>
 
<script>
Vue.component('button-counter', {
  template: '<button v-on:click="incrementHandler">{{ counter }}</button>',
  data: function () {    // data 必须是一个函数
    return {
      counter: 0
    }
  },
  methods: {
    incrementHandler: function () {
      this.counter += 1
      this.$emit('increment')    
      // this.$emit('increment',1) 带参数    ,在function (count)可获取 或 html 元素中 $event可获取
    }
  },
})
new Vue({
  el: '#counter-event-example',
  data: {
    total: 0
  },
  methods: {
    incrementTotal: function () {
      this.total += 1
    }
  }
})
</script>
上一篇下一篇

猜你喜欢

热点阅读