Vue组件化开发

组件化开发思想

标准、分治、重用、组合
Web Components通过创建封装好功能的定制元素来实现

组件注册

1.全局组件注册
语法:
Vue.component(组件名称,{
data:组件数据,
template:组件模板内容
})
实例:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <button-counter></button-counter>
        <button-counter></button-counter>

    </div>
    <script src="./vue.js"></script>
    <script>
        Vue.component('button-counter', {
            data: function() {
                return {
                    count: 0
                }
            },
            template: '<button v-on:click="handle">点击了{{count}}次</button>',
            methods: {
                handle: function() {
                    this.count += 2;
                }
            }
        })
        var vm = new Vue({
            el: '#app',
            data: {

            }
        });
    </script>
</body>

</html>
  1. 组件的数据是独立的,相互之间不受影响
  2. data必须是一个函数
  3. 组件模板内容必须是单个根元素,可嵌套
  4. 组件模板内容可以是模板字符串
  5. 使用驼峰式命名组件只能使用在字符串模板中

2.局部组件注册
语法:

var ComponentA={}
var ComponentB={}
var ComponentC={}
new Vue({
el:'#app'
components:{
'component-a':ComponentA,
'component-b':ComponentB
'component-c':ComponentC,
}
})

实例:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <component-a></component-a>
        <component-b></component-b>
        <component-c></component-c>
    </div>

    <script src="./vue.js"></script>
    <script>
        var ComponentA = {
            data: function() {
                return {
                    msg: 'A'
                }
            },
            template: '<h1>{{msg}}</h1>'
        };
        var ComponentB = {
            data: function() {
                return {
                    msg: 'B'
                }
            },
            template: '<h1>{{msg}}</h1>'
        };
        var ComponentC = {
            data: function() {
                return {
                    msg: 'C'
                }
            },
            template: '<h1>{{msg}}</h1>'
        };
        var vm = new Vue({
            el: '#app',
            data: {

            },
            components: {
                'component-a': ComponentA,
                'component-b': ComponentB,
                'component-c': ComponentC
            }
        });
    </script>
</body>

</html>

局部组件只能在注册它的父组件中使用

Vue调试工具

1.下载(Chrome)
下载地址:
https://chrome.zzzmh.cn/info?token=nhdogjmejiglipccpnnnanhbledajbpd

2.使用
先解压,然后在chrome浏览器地址栏中输入chrome://extensions/
然后将解压后的CRX文件拖进来,添加插件
成功界面如下:
在这里插入图片描述
如果vue使用不了,则打开详细信息,打开“允许访问文件网址”按钮:
在这里插入图片描述
然后就能在调试栏中看到vue:
在这里插入图片描述
这样就可以开始使用了

组件间数据交互

父组件向子组件传值

1.组件内部通过props接收传递过来的值
语法:

 Vue.component('menu-item',{
            props:['title'],
            template:'<div>{{title}}</div>'
        })

实例:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <menu-item :title="title" :content="content"></menu-item>

    </div>
    <script src="./vue.js"></script>
    <script>
        Vue.component('menu-item', {
            props: ['title', 'content'],
            template: '<div>{{title}},{{content}}</div>'
        });
        var vm = new Vue({
            el: "#app",
            data: {
                title: '我是父组件传递的title',
                content: '我是父组件传递的content'
            }
        })
    </script>
</body>

</html>

当props数值类型为对象数组时:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <menu-item :arr_obj='arr_obj'></menu-item>

    </div>
    <script src="./vue.js"></script>
    <script>
        Vue.component('menu-item', {
            props: ['arr_obj'],
            template: `
            <div>
            <p :key='index' v-for='(item,index) in arr_obj'>
            <span>{{item.name}}</span>
            <span>{{item.age}}</span>
            </p>
            </div>
         
            `
        });
        var vm = new Vue({
            el: "#app",
            data: {
                arr_obj: [{
                    name: '大花',
                    age: 18
                }, {
                    name: '小花',
                    age: 17
                }]
            }
        });
    </script>
</body>
</html>

一些注意:
props中使用驼峰形式,模板中需要使用短横线的形式
props传递数据是单向数据流

子组件向父组件传值

1.子组件通过自定义事件向父组件传递信息

<button @click='$emit("enlarge-text",5)'>扩大字体</button>

2.父组件监听子组件的事件

<menu-item @enlarge-text='fontsize+=$event'></menu-item>

实例:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <p :style='{fontSize:fontSize+"px"}'>我是父组件</p>
        <menu-item @enlarge-text='handle($event)'></menu-item>
    </div>
    <script src="./vue.js"></script>
    <script>
        Vue.component('menu-item', {
            template: `
            <div>
                <button @click='$emit("enlarge-text",5)'>增大字号</button>
            </div>
            `
        });
        var vm = new Vue({
            el: '#app',
            data: {
                fontSize: 10
            },
            methods: {
                handle: function(value) {
                    this.fontSize += value;
                }
            }
        });
    </script>
</body>

</html>
非父子组件传值

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

var eventHub=new Vue();

2.监听事件与销毁事件

//监听事件
eventHub.$on('add-todo',addtodo)
//销毁事件
eventHub.$off('add-todo')

3.触发事件

//触发事件
eventHub.$emit('add-todo',id)

实例:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <button @click='handle'>销毁事件</button>
        <test-first></test-first>
        <test-second></test-second>

    </div>

    <script src="./vue.js"></script>
    <script>
        //事件中心
        var eventHub = new Vue();
        Vue.component('test-first', {
            data: function() {
                return {
                    num: 0
                }
            },
            template: `
            <div>
                <div>first:{{num}}</div>
                <div>
                    <button @click='handle'>first</button>
                 </div>
            </div>
            `,
            methods: {
                handle: function() {
                    //触发兄弟组件的事件
                    eventHub.$emit('second-event', 1)
                }
            },
            mounted: function() {
                //监听事件
                eventHub.$on('first-event', (value) => {
                    this.num += value;
                })
            }
        });
        Vue.component('test-second', {
            data: function() {
                return {
                    num: 0
                }
            },
            template: `
            <div>
                <div>second:{{num}}</div>
                <div>
                    <button @click='handle'>second</button>
                 </div>
            </div>
            `,
            methods: {
                handle: function() {
                    eventHub.$emit('first-event', 1)
                }
            },
            mounted: function() {
                //监听事件
                eventHub.$on('second-event', (value) => {
                    this.num += value;
                })
            }
        });
        var vm = new Vue({
            el: '#app',
            data: {

            },
            methods: {
                handle: function() {
                    eventHub.$off('first-event');
                    eventHub.$off('second-event');
                }
            }
        });
    </script>
</body>

</html>

组件插槽

父组件向子组件传递模板内容

1.位置

Vue.component('alert-box', {
            template: `
            <div class="demo-alert-box">
                <strong>Something I want to say:</strong>
                <slot></slot>
            </div>
            `
        });

2.内容

 <alert-box>Hello World!!!</alert-box>

实例:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <alert-box>Hello World!!!</alert-box>
    </div>

    <script src="./vue.js"></script>
    <script>
        Vue.component('alert-box', {
            template: `
            <div class="demo-alert-box">
                <strong>Something I want to say:</strong>
                <slot></slot>
            </div>
            `
        });
        var vm = new Vue({
            el: '#app'
        })
    </script>
</body>

</html>

效果:
在这里插入图片描述

具名插槽

实例:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <!-- ------------用法1-------------- -->
        <base-layout>
            <h1 slot="header">我是Header</h1>
            <h2>我是main</h2>
            <h1 slot="footer">我是footer</h1>
            <h2>我是main</h2>
        </base-layout>
        <!-- -------------用法2------------- -->
        <base-layout>
            <template slot="header">
                <h1>我是header</h1>
                <h1>我是header</h1>
            </template>
        </base-layout>
    </div>
    <script src="./vue.js"></script>
    <script>
        Vue.component('base-layout', {
            template: `
            <div>
                <header>
                    <slot name="header"></slot>
                </header>
                <main>
                    <slot></slot>
                </main>
                <footer>
                    <slot name="footer"></slot>
                </footer>
            </div>
            `
        });
        var vm = new Vue({
            el: '#app'
        })
    </script>
</body>

</html>

效果:
在这里插入图片描述

作用域插槽

父组件对子组件的内容进行加工

实例:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <fruit-list :list='list'>
            <template slot-scope="slotProps">
                <span v-if="slotProps.info.id==2" class="current">
                    {{slotProps.info.name}}
                </span>
                <span v-else>{{slotProps.info.name}}</span>
            </template>
        </fruit-list>
    </div>
    <script src="./vue.js"></script>
    <script>
        Vue.component('fruit-list', {
            props: ['list'],
            template: `
            <div>
                <ul>
                    <li :key='index' v-for='(item, index) in list'>
                        <slot :info="item">{{item.name}}</slot>
                    </li>
                </ul>
            </div>
            `
        });
        var vm = new Vue({
            el: '#app',
            data: {
                list: [{
                    id: 1,
                    name: 'apple'
                }, {
                    id: 2,
                    name: 'orange'
                }, {
                    id: 3,
                    name: 'banana'
                }]
            }
        });
    </script>
    <style scoped>
        .current {
            color: brown;
            font-size: 20px;
            font-weight: 700;
        }
    </style>
</body>

</html>

效果:
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值