Vue初学3 组件的学习

1.组件注册

<!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>
        <button-counter></button-counter>

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

            }
        })
    </script>
</body>

</html>

2.组件注册的注意事项

1. data必须是一个函数⚫分析函数与普通对象的对比
2. 组件模板内容必须是单个根元素⚫分析演示实际的效果
3. 组件模板内容可以是模板字符串⚫模板字符串需要浏览器提供支持(ES6语法)

<!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-template></button-template>
        <button-template></button-template>
        <button-template></button-template>

    </div>
    <script src="../vue.js"></script>
    <script>
        //
        /* 1.    data必须是一个函数⚫分析函数与普通对象的对比
        2.    组件模板内容必须是单个根元素⚫分析演示实际的效果
        3.    组件模板内容可以是模板字符串⚫模板字符串需要浏览器提供支持(ES6语法)
         */
        /* Vue.component("button-template", {
            data: function() {
                return {
                    count: 0,
                }
            },
            template: "<button @click.prevent='handle'>点击了{{count}}次</button>",
            methods: {
                handle() {
                    this.count++
                }
            },
        }) */
        // ---------------------------------------
        Vue.component("button-template", {
            data: function() {
                return {
                    count: 0,
                }
            },
            template: `<div>
                    <button @click.prevent='handle'>点击了{{count}}次</button>
                    <button>测试</button>
            </div>`,
            methods: {
                handle() {
                    this.count++
                }
            },
        })


        var vm = new Vue({
            el: '#app',
            data: {}
        })
    </script>
</body>

</html>

3.组件注册命名方式

<!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-template></button-template>
        <button-template></button-template>
        <button-template></button-template>
        <hello-World></hello-World>
    </div>
    <script src="../vue.js"></script>
    <script>
        //
        /* 
            组件注册注意事项
            如果使用驼峰式命名 那么在使用组件的时候  只能在字符串模板中用驼峰的方式使用组件
            但是  在普通的标签模板中  必须是使用短横线方式使用组件
         */
        Vue.component('HelloWorld', {
            data: function() {
                return {
                    msg: 'helloWorld'
                }
            },
            template: '<div>{{msg}}</div>'
        })
        Vue.component("button-template", {
            data: function() {
                return {
                    count: 0,
                }
            },
            template: `<div>
                    <button @click.prevent='handle'>点击了{{count}}次</button>
                    <button>测试</button>
                    <HelloWorld></HelloWorld>
            </div>`,
            methods: {
                handle() {
                    this.count++
                }
            },
        })

        var vm = new Vue({
            el: '#app',
            data: {}
        })
    </script>
</body>

</html>

4.局部组件注册

<!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">
        <hello-world></hello-world>
        <Hello-jay></Hello-jay>
        <!-- <test-com></test-com> -->
    </div>
    <script src="../vue.js"></script>
    <script>
        // Vue.component("test-com", {
        //     template: "<div>Test<hello-world></hello-world></div>"
        // });
        /* 
        局部组件注册
        局部组件只能在注册他的父组件中使用
         */
        var HelloWorld = {
            data: function() {
                return {
                    msg: "hello World"
                }
            },
            template: "<div>{{msg}}</div>"
        };
        var HelloJay = {
            data: function() {
                return {
                    msg: 'hello Jay'
                }
            },
            template: "<div>{{msg}}</div>"
        }
        var vm = new Vue({
            el: '#app',
            data: {},
            components: {
                'hello-world': HelloWorld,
                'hello-jay': HelloJay
            }
        })
    </script>
</body>

</html>

5.数据的传递

<!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">
        {{pmsg}}
        <menu-item title="来自父组件的值"></menu-item>
        <menu-item :title="ptitle" content="hello"></menu-item>

    </div>
    <script src="../vue.js"></script>
    <script>
        // 父组件向子组件传值
        Vue.component("menu-item", {
            props: ['title', 'content'],
            data: function() {
                return {
                    msg: "子组件本身的数据"
                }
            },
            template: '<div>{{msg+"--"+title+"--"+content}}</div>'
        })
        var vm = new Vue({
            el: '#app',
            data: {
                pmsg: "父组件中的内容",
                ptitle: '动态绑定属性'
            }
        })
    </script>
</body>

</html>

6.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">
        {{pmsg}}
        <menu-item :menu-title="ptitle"></menu-item>

    </div>
    <script src="../vue.js"></script>
    <script>
        // 父组件向子组件传值
        Vue.component("menu-item", {
            props: ['menuTitle'],
            data: function() {
                return {
                    msg: "子组件本身的数据"
                }
            },
            template: '<div>{{msg}}<third-item testTitle="hello"></third-item></div>'
        })

        Vue.component("third-item", {
            props: ['testTitle'],
            data: function() {
                return {
                    msg: "子组件本身的数据"
                }
            },
            template: '<div>{{testTitle}}</div>'
        })
        var vm = new Vue({
            el: '#app',
            data: {
                pmsg: "父组件中的内容",
                ptitle: '动态绑定属性'
            }
        })
    </script>
</body>

</html>

7.父传子的属性值类型

<!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 :pstr="pstr" :pnum="12" :pboo=true :parr="parr" :pobj='pobj'></menu-item>
    </div>
    <script src="../vue.js"></script>
    <script>
        Vue.component('menu-item', {
            props: ['pstr', 'pnum', 'pboo', 'parr', 'pobj'],
            template: `<div>
                <div>{{pstr+'---'+(12+pnum)+'--'+pboo}}</div>
                <ul><li v-for="(item,index) in parr" :key="index">{{item}}</li><ul>
                <div>
                    <span>{{pobj.name}}</span>
                    <span>{{pobj.age}}</span>
                </div>
            </div>`
        })
        var vm = new Vue({
            el: '#app',
            data: {
                pmsg: '父组件中的内容',
                pstr: 'hello',
                parr: ['apple', 'orange', 'banana'],
                pobj: {
                    name: 'lisi',
                    age: 12
                }
            }
        })
    </script>
</body>

</html>

8.子组件向父组件传值

<!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">
        <div :style='{fontSize:fontSize+"px"}'>{{pmsg}}</div>
        <menu-item :parr="parr" @enlarge-text="handle()"></menu-item>
    </div>
    <script src="../vue.js"></script>
    <script>
        // 子组件向父组件传值  基本用法
        // props传递数据原则  单向数据流
        Vue.component('menu-item', {
            props: ['parr'],
            template: `<div>
                <ul>
                    <li :key='index' v-for="(item,index) in parr">{{item}}</li>
                </ul>
                <button @click="parr.push('lemon')">点击</button>
                <button @click="$emit('enlarge-text')">扩大组件中字体大小</button>
            </div>`
        })
        var vm = new Vue({
            el: '#app',
            data: {
                pmsg: '父组件中的内容',
                parr: ['apple', 'orange', 'banana'],
                fontSize: 10
            },
            methods: {
                handle() {
                    this.fontSize += 5
                }
            }
        })
    </script>
</body>

</html>

9.兄弟组件之间的传值

<!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">
        <text-tom></text-tom>
        <div>
            <button @click="handle">销毁</button>
        </div>
        <text-jerry></text-jerry>
    </div>
    <script src="../vue.js"></script>
    <script>
        // 兄弟组件之间的数据传递

        //提供事件中心
        var hub = new Vue();
        Vue.component('text-tom', {
            data: function() {
                return {
                    num: 0
                }
            },
            template: `
                <div>
                    <div>TOM:{{num}}</div>
                    <div>
                        <button @click="handle">点击</button>
                    </div>
                </div>
            `,
            methods: {
                handle: function() {
                    hub.$emit('jerry-event', 1)
                }
            },
            mounted() {
                //监听事件
                hub.$on('tom-event', (val) => {
                    this.num += val
                })
            }
        })
        Vue.component('text-jerry', {
            data: function() {
                return {
                    num: 0
                }
            },
            template: `
                <div>
                    <div>Jerry:{{num}}</div>
                    <div>
                        <button @click="handle">点击</button>
                    </div>
                </div>
            `,
            methods: {
                handle: function() {
                    //触发兄弟组件的事件
                    hub.$emit('tom-event', 2)
                }
            },
            mounted() {
                //监听事件
                hub.$on('jerry-event', (val) => {
                    this.num += val
                });
            }
        })
        var vm = new Vue({
            el: "#app",
            data: {},
            methods: {
                handle() {
                    hub.$off('tom-event');
                    hub.$off('jerry-event');

                }
            },
        })
    </script>
</body>

</html>

10.组件插槽

<!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>有bug发生</alert-box>
        <alert-box>有一个警告</alert-box>
        <alert-box></alert-box>


    </div>
    <script src="../vue.js"></script>
    <script>
        Vue.component('alert-box', {
            template: `
                <div>
                    <strong>ERROR:</strong>
                    <slot>默认内容<slot>
                </div>
            `
        })
        var vm = new Vue({
            el: '#app',
            data: {}
        })
    </script>
</body>

</html>

11.具名插槽

<!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">
        <base-layout>
            <p slot="header">标题信息</p>
            <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>
            <template slot="footer">
                <p>底部信息1</p>
                <p>底部信息2</p>
            </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',
            data: {

            }
        })
    </script>
</body>

</html>

12.作用域插槽

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .current {
            color: orange;
        }
    </style>
</head>

<body>
    <div id="app">
        <fruit-list :list="list">
            <template slot-scope="slotProps">
                <strong v-if='slotProps.info.id==2' class="current">{{slotProps.info.name}}</strong>
                <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>
                <li v-for="item in list">
                    <slot :info="item">{{item.name}}</slot>
                </li>
            </div>
            `
        })
        var vm = new Vue({
            el: '#app',
            data: {
                list: [{
                    id: 1,
                    name: 'apple'
                }, {
                    id: 2,
                    name: 'orange'
                }, {
                    id: 3,
                    name: 'banana'
                }]
            }
        })
    </script>
</body>

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值