Vue组件化开发

本文详细介绍了Vue.js的组件化开发思想,包括组件注册、数据交换、自定义事件和插槽的使用。通过组件注册,可以实现代码的复用和独立性,避免冲突。组件间数据交换遵循单向数据流原则,通过props和自定义事件实现父子组件的通信。此外,还讲解了具名插槽和作用域插槽的应用,允许父组件向子组件传递复杂内容并进行定制处理。
摘要由CSDN通过智能技术生成

组件化开发思想

组件化规范:Web Components

问题:

  • 尽可能多的重用代码
  • 自定义组件的方式不太容易(html、css和js)
  • 多次使用组件可能导致冲突

Web Components通过创建封装好功能的定制元素(自定义标签)解决上述问题

Vue 实现了部分上述规范

组件注册

Vue.component(组件名称,{
    data:组件数据,
    template:组件模板内容
})

例子:计算按钮点击次数

Vue.component('button-counter',{
    data:function(){
        return{
            count:0
        }
    },
    template:'<button @click="count++">点击了{{count}}次</button>'
});

//另一种写法:定义方法使用
Vue.component('button-counter',{
    data:function(){
        return{
            count:0
        }
    },
    template:'<button @click="handle">点击了{{count}}次</button>',
    methods:{
        handle:function(){
            this.count+=1;
        }
    }
});

使用:

<div id="app">
    <!-- 可多次使用,组件数据相互独立 -->
        <button-counter></button-counter>
        <button-counter></button-counter>
        <button-counter></button-counter>
</div>

组件注册注意事项

  1. data必须是一个函数
    分析函数与普通对象的对比
  2. 组件模板内容必须是单个根元素
    // 报错
template:'<button @click="handle">点击了{{count}}次</button><button>测试</button>'
   //这样可以
template:'<div><button @click="handle">点击了{{count}}次</button><button>测试</button></div>'
  1. 组件模板内容可以是模板字符串
    模板字符串需要浏览器提供支持(ES6语法)
     Vue.component('hello-world',{
            template:`
            <div class="hello-world-box">
                <span>hello</span>
            </div>
            `
        });
  1. 组件命名方式
    短横线方法:
    Vue.component(‘my-component’,…)
    驼峰方式:
    Vue.component(‘MyComponent’,…)

驼峰命名不能直接在html中使用,只能加入到组件命名的template中使用

局部组件注册

不能在全局组件中使用,只能在注册它的父组件中使用

var ComponentA={
    data:function(){
        return(
            msg:'helloworld'
        )
    },
    template:'<div>{{msg}}</div>'
};
var ComponentB={/*...*/};
var ComponentC={/*...*/};
var vm = new Vue({
    el:'#app',
    data:{

    },
    components:{
        'component-a':ComponentA,
        'component-b':ComponentB,
        'component-c':ComponentC
    }
});

组件间数据交换

父组件向子组件传值

  1. 组件内部通过props接收传递过来的参数
//定义子组件 
Vue.component('menu-item',{
    props:['title'],
    template:'<div>{{title}}</div>'
});
//vm本身是一个组件,是根组件
var vm = new Vue({
    el:'#app',
    data:{
        title:'动态绑定属性'
    }
});
  1. 父组件通过属性将值传递给子组件
<menu-item title="来自父组件的数据"></menu-item>  
<menu-item :title="title"></menu-item>  
  1. props属性名规则
    • 在props中使用驼峰形式,dom模板中需要使用短横线的形式(原因:dom属性不存在大小写)
    • 字符串形式的模板中没有限制
//定义子组件 
Vue.component('menu-item',{
    //驼峰形式
    props:['menuTile'],
    //字符串形式模板
    template:'<div>{{menuTile}}</div>'
});
<!-- dom中使用时需要短横线形式 -->
<menu-item menu-title="来自父组件的数据"></menu-item>  
  1. props属性值类型
  • 字符串String
  • 数值 Number
<!-- typeof num:string -->
<menu-item num='12'></menu-item>  
<!-- typeof num:number -->
<menu-item :num='12'></menu-item>  
  • 布尔值 Boolean(同上,不加冒号为string类型,加冒号为boolean类型)
  • 数组 Array
  • 对象 Object
  1. props传递数据原则:单向数据流(只允许父组件传递数据给子组件)

子组件向父组件传值

  1. 子组件通过自定义事件向父组件传递信息
<!-- $emit是固定的 -->
<button v-on:click='$emit("自定义事件名")'>测试</button>
  1. 父组件监听子组件的事件
<menu-item v-on:自定义事件名='触发事件'>测试</menu-item>

  1. 子组件通过自定义事件向父组件传递
<button v-on:click='$emit("enlarge",0.1)'>测试</button>
  1. 父组件监听子组件的事件
<!-- 固定$event接收0.1 -->
<menu-item v-on:enlarge='fontSize+= $event'>测试</menu-item>

非父子(兄弟)组件间传值

  1. 单独的事件中心管理组件间的通信

组件A<–监听/触发–>事件中心<–触发/监听–>组件B

var eventHub = new Vue();
  1. 监听事件与销毁事件
eventHub.$on('自定义函数名称',自定义函数);
eventHub.$off('自定义函数名称');
  1. 触发事件
eventHub.$emit('自定义函数名称',参数);

组件插槽

作用

  • 父组件向子组件传递内容(模板内容)

组件插槽基本用法

  1. 插槽位置
 Vue.component('alert-box',{
    template:`
    <div class="demo-alert-box">
        <strong>Error!</strong>
        // 插槽
        <slot></slot>
    </div>
    `
});
  1. 插槽内容
<alert-box>Something bad happend.</alert-box>

运行结果(页面显示为):Error! Something bad happend.

注意:插槽内容为空,则默认显示slot的内容,否则slot内容不显示

具名插槽用法(有名字的插槽)

  1. 插槽定义
 Vue.component('alert-box',{
    template:`
    <div class="container">
        <header>
            <slot name='header'></slot>
        </header>
        <main>
            <slot></slot>
        </main>
        <footer>
            <solt name='footer'></solt>
        </footer>
    </div>
    `
}); 
  1. 插槽内容
<!-- 填充到名字匹配的插槽中,没有名字则匹配到默认的无名插槽中 -->
<base-layout>
    <h1 slot="header">标题内容</h1>
    <p>主要内容1</p>
    <p>主要内容2</p>
    <p slot="footer">底部内容</p>
</base-layout>

可以使用标签 填充多条内容
标签:临时性包裹内容,不会渲染到页面

<base-layout>
    <template slot="header">
        <p>标题信息1</p>
        <p>标题信息2</p>
    </template>
    <p>主要内容1</p>
    <p>主要内容2</p>
    <p slot="footer">底部内容</p>
</base-layout>

作用域插槽

  • 应用场景:父组件对子组件内容进行加工处理
  1. 插槽定义
Vue.component('alert-box',{
    props:['list'],
    template:`
    <ul>
        <li v-for="item in list" v-bind:key=item.id>
            <slot v-bind:绑定数据自定义名="item">
                {{itm.name}}
            </slot>
        </li>
    </ul>
    `
}); 
  1. 插槽内容
<fruit-list v-bind:list="list">
    <!-- slot-scope获取数据  值是在子属性slot中绑定的-->
    <template slot-scope="自定义名">
        <!-- 条件判断进行加工 -->
        <strong v-if='自定义名.绑定数据自定义名.id==2' class='current'>
            {{slotProps.info.name}}
        </strong>
    </template>
</fruit-list>
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值