美文网首页iOS开发之笔记摘录跨平台
vue.js入门之第四篇(自定义组件)

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

作者: 平安喜乐698 | 来源:发表于2018-08-17 15:15 被阅读0次
    目录
    
    
    除了可以使用普通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>
    

    相关文章

      网友评论

        本文标题:vue.js入门之第四篇(自定义组件)

        本文链接:https://www.haomeiwen.com/subject/aettiftx.html