• Vue.js(09):组件


    一、组件

    组件(Component)是 Vue.js 最强大的功能之一。

    组件可以扩展 HTML 元素,封装可重用的代码。

    组件系统让我们可以用独立可复用的小组件来构建大型应用,几乎任意类型的应用的界面都可以抽象为一个组件树:

    注册一个全局组件语法格式如下:

    Vue.component(tagName, options)

    tagName 为组件名,options 为配置选项。

    注册后,我们可以使用以下方式来调用组件:

    <tagName></tagName>

    1、全局组件

    所有实例都能用全局组件。

    注册一个简单的全局组件 runoob,并使用它:

    <div id="app">
        <runoob></runoob>
    </div>
     
    <script>
    // 注册
    Vue.component('runoob', {
      template: '<h1>自定义组件!</h1>'
    })
    // 创建根实例
    new Vue({
      el: '#app'
    })
    </script>

    尝试一下 »

    2、局部组件

    我们也可以在实例选项中注册局部组件,这样组件只能在这个实例中使用:

    注册一个简单的局部组件 runoob,并使用它:

    <div id="app">
        <runoob></runoob>
    </div>
    
    <script>
        // 创建根实例
        new Vue({
            el: '#app',
            components: {'runoob': {  // <runoob> 将只在父模板可用
               template: '<h1>自定义组件!</h1>'
            }}
        })
    </script>

    尝试一下 »

    二、Prop

    prop 是子组件用来接受父组件传递过来的数据的一个自定义属性。

    父组件的数据需要通过 props 把数据传给子组件,子组件需要显式地用 props 选项声明:

    <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、动态 Prop

    类似于用 v-bind 绑定 HTML 特性到一个表达式,也可以用 v-bind 动态绑定 props 的值到父组件的数据中。每当父组件的数据变化时,该变化也会传导给子组件:

    <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>

    尝试一下 »

    以下实例中使用 v-bind 指令将 todo 传到每一个重复的组件中:

    <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>

    尝试一下 »

    注意: prop 是单向绑定的:当父组件的属性变化时,将传导给子组件,但是不会反过来。

    2、Prop 验证

    组件可以为 props 指定验证要求。

    为了定制 prop 的验证方式,你可以为 props 中的值提供一个带有验证需求的对象,而不是一个字符串数组。例如:

    Vue.component('my-component', {
      props: {
        // 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)
        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 ['success', 'warning', 'danger'].indexOf(value) !== -1
          }
        }
      }
    })

    当 prop 验证失败的时候,(开发环境构建版本的) Vue 将会产生一个控制台的警告。

    type 可以是下面原生构造器:

    • String
    • Number
    • Boolean
    • Array
    • Object
    • Date
    • Function
    • Symbol

    type 也可以是一个自定义构造器,使用 instanceof 检测。

    三、自定义事件

    父组件是使用 props 传递数据给子组件,但如果子组件要把数据传递回去,就需要使用自定义事件!

    我们可以使用 v-on 绑定自定义事件, 每个 Vue 实例都实现了事件接口(Events interface),即:

    • 使用 $on(eventName) 监听事件
    • 使用 $emit(eventName) 触发事件

    另外,父组件可以在使用子组件的地方直接用 v-on 来监听子组件触发的事件。

    以下实例中子组件已经和它外部完全解耦了。它所做的只是触发一个父组件关心的内部事件。

    <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 () {
        return {
          counter: 0
        }
      },
      methods: {
        incrementHandler: function () {
          this.counter += 1
          this.$emit('increment')
        }
      },
    })
    
    new Vue({
      el: '#counter-event-example',
      data: {
        total: 0
      },
      methods: {
        incrementTotal: function () {
          this.total += 1
        }
      }
    })
    </script>

    尝试一下 »

    如果你想在某个组件的根元素上监听一个原生事件。可以使用 .native 修饰 v-on 。例如:

    <my-component v-on:click.native="doTheThing"></my-component>

    1、data 必须是一个函数

    上面例子中,可以看到 button-counter 组件中的 data 不是一个对象,而是一个函数:

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

    这样的好处就是每个实例可以维护一份被返回对象的独立的拷贝,如果 data 是一个对象则会影响到其他实例,如下所示:

    <div id="components-demo3" class="demo">
        <button-counter2></button-counter2>
        <button-counter2></button-counter2>
        <button-counter2></button-counter2>
    </div>
     
    <script>
    var buttonCounter2Data = {
      count: 0
    }
    
    Vue.component('button-counter2', {
        /*
        data: function () {
            // data 选项是一个函数,组件不相互影响
            return {
                count: 0
            }
        },
        */
        data: buttonCounter2Data// data 选项是一个对象,会影响到其他实例
        ,
        template: '<button v-on:click="count++">点击了 {{ count }} 次。</button>'
    })
    
    new Vue({ el: '#components-demo3' })
    </script>

    尝试一下 »

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

    为了让它正常工作,这个组件内的 <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)" >`
    })

    现在 v-model 就应该可以在这个组件上完美地工作起来了:

    <custom-input v-model="searchText"></custom-input>
  • 相关阅读:
    maven常用仓库
    AD域安装及必要设置
    oracle创建表空间
    javascript弹出模态窗体
    win8.1 AMD 屏幕亮度无法调整
    tomcat优化
    CentOS 6.2 中文
    tomcat之JNDI数据源配置
    eclipse中tomcat配置(待完善)
    Ant打jar包指定MainClass
  • 原文地址:https://www.cnblogs.com/springsnow/p/12923203.html
Copyright © 2020-2023  润新知