Vue 组件

全局组件和局部组件

Props

props验证

组件自定义事件

自定义组件的 v-model


全局组件和局部组件

        组件(Component)是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素,封装可重用的代码。

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

Vue.component(tagName, options)

        tagName 为组件名,options 为配置选项。注册后,我们可以使用以下方式来调用组件:

<tagName></tagName>

        所有实例都能用全局组件。当然我们也可以在实例选项中注册局部组件,这样组件只能在这个实例中使用:

<div id="app">
	<runoob></runoob>
    <child></child>
</div>

<script>
// 注册全局组件
Vue.component('runoob', {
  template: '<h1>自定义全局组件!</h1>'
})

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

Props

        prop 是子组件用来接受父组件传递过来的数据的一个自定义属性。父组件的数据需要通过 props 把数据传给子组件,子组件需要显式地用 props 选项声明 "prop":

<div id="app">
	<input v-model="parentMsg">
	<br>
	<child v-bind:message="parentMsg"></child>
</div>

<script>
// 注册
Vue.component('child', {
  // 声明 props
  props: ['message'],
  // 同样也可以在 vm 实例中像 “this.message” 这样使用
  template: '<span>{{ message }}</span>'
})
// 创建根实例
new Vue({
  el: '#app',
  data: {
	parentMsg: '父组件内容'
  }
})
</script>

        类似于用 v-bind 绑定 HTML 特性到一个表达式,也可以用 v-bind 动态绑定 props 的值到父组件的数据中。每当父组件的数据变化时,该变化也会传导给子组件。注意: prop 是单向绑定的:当父组件的属性变化时,将传导给子组件,但是不会反过来。

props验证

        组件可以为 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 传递数据给子组件,但如果子组件要把数据传递回去,就需要使用自定义事件!

  • 使用 $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 不是一个对象,而是一个函数
  // 这样的好处是每个实例可以维护一份被返回对象的独立的拷贝,不会影响到其他实例
  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>

自定义组件的 v-model

        组件上的 v-model 默认会利用名为 value 的 prop 和名为 input 的事件。

<input v-model="parentData">

// 上面等价于下面
<input 
    :value="parentData"
    @input="parentData = $event.target.value"
>

        使用实例如下:

<div id="app">
    <runoob-input v-model="num"></runoob-input>
    <p>输入的数字为:{{num}}</p>
</div>
<script>
Vue.component('runoob-input', {
    template: `
    <!-- 包含了名为 input 的事件 -->
    <input :value="value" @input="$emit('input', $event.target.value)">`,
    props: ['value'], // 名为 value 的 prop
})
   
new Vue({
    el: '#app',
    data: {
        num: 100,
    }
})
</script>

        由于 v-model 默认传的是 value,不是 checked,所以对于复选框或者单选框的组件时,我们需要使用 model 选项,model 选项可以指定当前的事件类型和传入的 props。

<div id="app">
    <base-checkbox v-model="lovingVue"></base-checkbox> 
	<div v-show="lovingVue">如果选择框打勾我就会显示。</div>
</div> 
<script>
// 注册
Vue.component('base-checkbox', {
  model: {
    prop: 'checked',
    event: 'change'  // onchange 事件
  },
  props: {
    checked: Boolean
  },
  template: `
    <input type="checkbox" v-bind:checked="checked"
      v-on:change="$emit('change', $event.target.checked)">`
})
// 创建根实例
new Vue({
  el: '#app',
  data: {
    lovingVue: true
  }
})

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值