Vue笔记(二):Components

组件注册


<!-- 组件使用 -->
<div id="exp">
    <my-component></my-component>
</div>
// 1. 全局注册 任何地方都可使用
Vue.component('my-component', {
    props: ['msg'],
    template: '<span>this is my component!</span>',
    data: function(){
        return {
            ...
        }
    }
});

// 2. 创建根实例
new Vue({
    el: '#exp',
    data: {}
});
注意:
    组件中的 data 必须是一个函数,否则 Vue 会停止工作。这样做是为了避免多个组件实例引用同一个 data 对象,导致彼此相互影响。换句话说,是为了保证组件实例间的相互独立,而这是通过每次调用 data 函数返回一个新对象来实现的。

Props


1. 字面量语法

组件实例的作用域是孤立的,不能在子组件的模板内直接引用父组件的数据。如果子组件要引用父组件的数据,需要使用 props 属性。

Vue.component('child', {
  props: ['myName'], // 声明 props
  template: '<span>{{ myName }}</span>'
});

这里的 props 就如同实例中的 data 对象,也可以在实例中以 this.myName 形式使用。

<child my-name="hello!"></child>
注意:
    HTML 特性不区分大小写。使用驼峰式命名的 prop 需要转换为相对应的短横线隔开式命名。
    myName --> my-name

2. 动态语法:v-bind

类似于用 v-bind 绑定 HTML 特性,我们也可用 v-bind 将动态 props 绑定到父组件中的数据。实现父组件与子组件数据变化的传递。

<div id="exp-1">
    <input v-model="parentMsg">
    <child :msg="parentMsg"></child>
</div>
new Vue({
    el: '#exp-1',
    data: {
        parentMsg: 'parent message'
    },
    components: {
        child: {
            props: ['msg'],
            template: '<button>{{msg}}</button>'
        }
    }
});
注意:
    这种数据绑定是单向的,父组件数据会影响子组件数据,但子组件数据不会影响父组件。

3. Prop验证

我们可以为组件的 props 指定验证规格。如果传入的数据不符合规格,Vue 会发出警告。

Vue.component('my-component', {
    props: {
        prop1: 'null', // 任何类型皆可
        prop2: [String, Number], // 指定多种类型
        prop3: {
            type: Number,
            reuqired: true, // 属性必需且为数值型
            default: 20, // 指定默认值
            twoway: true, // 指定此prop为双向绑定 2.0移除
            validator: function(v){ // 自定义验证器
                return v > 10
            }
        }
    }
});

props 验证失败时, Vuejs 将拒绝在子组件上设置此值。

组件通信 / 2.0+


1. v-on 绑定自定义事件

$on 监听事件:vm.$on('eventName', handler)

$emit 触发事件:vm.$emit('eventName', args)

<div id="exp-2">
    <h4>Total:{{total}}</h4>
    <my-btn @customEvt="reduceNum">{{counter}}</my-btn>
    <my-btn @customEvt="reduceNum">{{counter}}</my-btn>
</div>

在使用子组件的地方直接用 v-on:customEvt 来监听子组件事件的触发,来实现父子组件的通信。

Vue.component('my-btn', {
    template: '<button @click="addNum">{{counter}}</button>',
    data: function(){
        return {
            counter: 0
        }
    },
    methods: {
        addNum: function(){
            this.counter++;
            this.$emit('customEvt');
        }
    }
});

new Vue({
    el: '#exp-2',
    data: {
        total: 0
    },
    methods: {
        reduceNum: function(){
            this.total++;
        }
    }
});

2. 双向绑定的两种简单实现

# v-model + watch
  1. 由于子组件内部 props 不可写,因此我们需要在 data 对象中创建一个副本并将其初始为 props 属性的值。
  2. 组件外修改 props 并不会同步到副本中,因此我们设置一个侦听器 watchprops 与其副本数据同步。
  3. 监听副本状态变化,触发事件回调 this.$emit('input', val)
  4. 最后结合 v-model 将子组件的数据传递到外部,父组件数据响应式改变。
<template id="temp">
    <div>
        <input v-model="myname">
        <button>{{myname}}</button>
    </div>
</template>
<div id="exp-3">
    <h3>父组件</h3>
    <input v-model="name">
    <button>{{name}}</button>
    
    <h3>子组件</h3>
    <child :sname="name" v-model="name"></child>
</div>

new Vue({
    el: '#exp',
    data: {
        name: 'zz'
    },
    components: {
        'child': {
            template: '#temp',
            props: ['sname'],
            data: function(){
                return {
                    myname: this.sname  // 1
                }
            },
            watch: {
                sname: function(val){
                    this.myname = val;  // 2
                },
                myname: function(val){
                    this.$emit('input', val);  // 3
                }
            }
        }
    }
});

JS Bin - watch 双向绑定

# props + obj

将一个引用类型传递给 props 属性,由于对象的地址引用特性,子组件修改对象属性父组件数据也相应改变。借此实现组件数据的双向绑定。

<template id="temp">
    <div>
        <input v-model="obj.name">
        <button>{{obj.name}}</button>
    </div>
</template>

<div id="exp">
    <h3>父组件</h3>
    <input v-model="obj.name">
    <button>{{obj.name}}</button>
        
    <h3>子组件</h3>
    <child :obj="obj"></child>
</div>
new Vue({
    el: '#exp',
    data: {
        obj:{
            name: 'oo'
        }
    },
    components:{
        'child':{
            template: '#temp',
            props: ['obj']
        }
    }
});

JS Bin - 对象props双向绑定

转载于:https://www.cnblogs.com/qimeng/p/7683948.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue组件的插槽是一种抽象的概念,用于分发组件的内容。Vue提供了三种类型的插槽:默认插槽、具名插槽和作用域插槽。 默认插槽是没有名字的插槽,可以在组件模板中使用<slot>标签来定义。当组件没有具名插槽时,所有没有被包裹在具名插槽中的内容都会被传递到默认插槽中。 具名插槽是有名字的插槽,可以在组件模板中使用<slot name="xxx">标签来定义。当组件中有多个插槽时,可以使用具名插槽来指定要分发的内容。 作用域插槽是一种特殊的插槽,可以让父组件向子组件传递数据。作用域插槽可以在组件模板中使用<slot>标签来定义,并且可以使用一个带有参数的函数来向插槽中传递数据。 例如,下面是一个使用作用域插槽的例子: ```html <template> <div> <slot v-bind:user="user"> {{ user.lastName }} </slot> </div> </template> <script> export default { data() { return { user: { firstName: 'John', lastName: 'Doe' } } } } </script> ``` 在父组件中,可以这样使用这个组件: ```html <template> <div> <user-profile> <template v-slot:default="slotProps"> {{ slotProps.user.firstName }} </template> </user-profile> </div> </template> <script> import UserProfile from './UserProfile.vue' export default { components: { UserProfile } } </script> ``` 这个例子中,父组件向子组件传递了一个名为user的数据对象,并且在插槽中使用了一个带有参数的函数来向插槽中传递数据。在插槽中,可以使用slotProps来访问传递进来的数据。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值