第五节:Vue组件component

第五节:Vue组件component

目录

component 注册全局组件 Vue中方法

components 注册局部组件 钩子函数

props:[] 传值

$emit 传递参数

$parent 获取父组件中参数

1、component 注册全局组件

component 注册全局组件 Vue中的方法

注册组件的时候需要注意:

​ 如果为驼峰命名法的时候,需要使用 - 来隔开;

语法:

// 注册组件:【组件名,组件的方法】
Vue.component('aSideBar', {
    // 组件的模版
    template: `<div class='div1'>
          <h1>这个是即将被挂载的组件 {{info}} </h1>
      </div>`,
    data () {
        return {
            info: '这个是组件自己内容的值'
        }
    }
})
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <h1>{{about}}</h1>
        <p>{{author}}</p>
        <!-- <p>ID:{{user.id}} & name:{{user.name}}</p> -->
        <!-- 插入组件 -->
        <a-side-bar></a-side-bar>
    </div>
    <script src="https://cdn.bootcss.com/vue/2.6.10/vue.js"></script>
    <script>
        Vue.component('aSideBar', {
            // 组件的模版
            template: `<div class='div1'>
                <h1>这个是即将被挂载的组件 {{info}} </h1>
            </div>`,
            data () {
                return {
                    info: '这个是组件自己内容的值'
                }
            }
        })

        new Vue({
            el: '#app',
            data: {
                about: 'component 注册全局组件',
                author: 'xiaoge',
                user: {
                    id: 1,
                    name: "张三"
                }
            }
        })
    </script>
</body>

</html>

用render函数替代template ,就像使用原生js一样去拼接标签然后生成模板

语法:

render:function(createEl){// 第一参数为生成VNode的函数
  return createEl(
  	......
  );
},
 createEL函数:生成的就是一个提供给Vue组件生成DOM虚拟DOM;其实简单来说虚拟DOM就是把一个正真的DOM的一些必要的信息,比如标签名,标签属性等等单独存储起来,然后通过一些处理,更具这些信息来生成一个正真的DOM
 参数:createEl(string | object, [object ,] string | VNode | array)

第一参数 
 标签名<string>
 组件参数对象<object>
第二参数(可选)
 模板参数对象<object>
第三参数
 标签中的文本<string>
 子节点<VNode>
 多个内容组成的数组<array>
createEl(
	'div',
   {
       class:'box'
   },
   [
       'hello~',
       createEl({template:'<i></i>'})
   ]
);
第二参数模板设置对象的属性:
{
	class: ['a', {b: true}],      // 等同 v-bind:class
	style: {color: 'red'},        // 等同 v-bind:style
	attrs: {goudan: '大锤'},      // 设置普通的标签属性
	props: {p: 'data'},           // 等同 v-bind:p
	domProps: {innerHTML:'abc'},  // 设置DOM属性
	on: {testFn:()=>{}}, 		  // 等同 v-on:
	nativeOn: {click:() =>{}}, 	  // 监听原生事件
	key: 'myKey', 				  // 等同 v-bind:key
	ref: 'myRef' 				  // 等同 v-bind:ref
}
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <div id='app'>
        <base-head></base-head>
    </div>
    <script src="https://cdn.bootcss.com/vue/2.6.10/vue.js"></script>
    <script>
        /*
        语法:createEl(
            el,
            {
                class: ['a', {b: true}],      // 等同 v-bind:class
                style: {color: 'red'},        //  等同 v-bind:style
                attrs: {goudan: '大锤'},      // 设置普通的标签属性
                props: {p: 'data'},           // 等同 v-bind:p
                domProps: {innerHTML:'abc'},  // 设置DOM属性
                on: {testFn:()=>{}}, 		  // 等同 v-on:
                nativeOn: {click:() =>{}}, 	  // 监听原生事件
                key: 'myKey', 				  // 等同 v-bind:key
                ref: 'myRef' 				  // 等同 v-bind:ref
            },
            [
                '当前节点的内容 container ',
                createEl({template:'<i></i>'})
            ]
        );
        */
        Vue.component('base-head', {
            render: function (createEl) {// 第一参数为生成VNode的函数
                return createEl(
                    'div',
                    {
                        style: { color: 'red' },
                        props: { p: 'data' },
                    },
                    [
                        '这个是 createEL 的数据'
                    ]
                );
            },
            data () {
                return {
                    p: "123456"
                }
            },
            methods: {
                myKey: function () {
                    console.log("this is myKey function")
                }
            }
        });

        new Vue({
            el: '#app'
        });
        // 表单事件
    </script>
</body>

</html>

2、components 注册局部组件

components 注册局部组件 Vue中钩子函数

注册组件的时候需要注意:

如果为驼峰命名法的时候,需要使用 - 来隔开;

语法:

<a-side-bar></a-side-bar>
components: {
    aSideBar: {
        data () {
            return {
                info: '这个是组件自己内容的值'
            }
        },
        template: `<div class='div1'>
                <h1>这个是即将被挂载的组件 {{info}} </h1>
            </div>`,
    }
}
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <h1>{{about}}</h1>
        <p>{{author}}</p>
        <p>ID:{{user.id}} & name:{{user.name}}</p>
        <!-- 插入组件 -->
        <a-side-bar></a-side-bar>
    </div>

    <script src="https://cdn.bootcss.com/vue/2.6.10/vue.js"></script>
    <script>

        new Vue({
            el: '#app',
            data: {
                about: 'components 注册局部组件',
                author: 'xiaoge',
                user: {
                    id: 1,
                    name: "张三"
                }
            },
            components: {
                aSideBar: {
                    data () {
                        return {
                            info: '这个是组件自己内容的值'
                        }
                    },
                    template: `<div class='div1'>
                            <h1>这个是即将被挂载的组件 {{info}} </h1>
                        </div>`,
                }
            }
        })

    </script>
</body>

</html>

3、props:[]传值

props:[] 传递参数

componentcomponents 全局组件和局部组件中都带有 data 参数 那么就牵涉到子组件使用父组件中的参数或者父组件使用子组件中的参数,props 是父组件传递参数给子组件的关键词,props 负责接受父组件传递过来的参数。

如果为驼峰命名法的时候,需要使用 - 来隔开;

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <!--html给子组件传值-->
    <div id='app'>
        <!-- app有自己的data -->
        <h1>{{title}}</h1>
        <div>{{about}}</div>
        <hr>
        <!-- h-nav也有自己的data -->
        <h-nav :title='"这里是子组件"' :des-name='param'></h-nav>
    </div>
    <script src="https://cdn.bootcss.com/vue/2.6.10/vue.js"></script>
    <script>

        /* 父子组件通讯(传值):父组件向子组件传值,子组件接受值,实现组件与组件之间进行通讯(非父子组件通讯)
            组件的形成:html + css + js */
        let vm = new Vue({
            el: '#app',
            data: {
                about: '父组件向子组件传值,子组件接受值,实现组件与组件之间进行通讯',
                title: '这里是父组件的标题',
                param: '这里是传递的参数'
            },
            components: {
                hNav: {
                    data () {
                        return {
                            ablout: '这里是子组件的标题',
                        }
                    },
                    template: `<div>
                            <h2>{{ablout}}</h2>
                            <div>{{title}} </div>
                            <div>{{desName}} </div>
                        </div>`,
                    //接收父组件传达过来的值。
                    props: ['title', 'desName'],
                }
            }
        })
    </script>
</body>

</html>

4、父组件给子组件传值

props:[] 传递参数

​ 父组件传递参数给子组件

​ ***传递参数如果为驼峰命名法的时候,需要使用 - 来隔开;***如:

props: ["firstParam", "params"],
<xiaoge-parents 
:first-param='"来自原型的第一个参数"' 
:params="'来自原型的第二个参数'">
</xiaoge-parents>

第一种写法

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <!--html给子组件传值-->
    <div id='app'>
        <!-- app有自己的data -->
        <h1>{{title}}</h1>
        <div>{{about}}</div>
        <hr>
        <!-- h-nav也有自己的data -->
        <xiaoge-parents :first-title='"来自原型的第一个参数"' :doudou="'来自原型的第二个参数'"> </xiaoge-parents>
    </div>
    <script src="https://cdn.bootcss.com/vue/2.6.10/vue.js"></script>
    <script>

        /* 父子组件通讯(传值):父组件向子组件传值,子组件接受值,实现组件与组件之间进行通讯(非父子组件通讯)
                    组件的形成:html + css + js */
        let vm = new Vue({
            el: '#app',
            data: {
                about: '父组件向子组件传值,子组件接受值,实现组件与组件之间进行通讯',
                title: '这里是原始DOM',
                param: '来自原型的第二个参数'
            },
            components: {
                xiaogeParents: {
                    data () {
                        return {
                            parentTitle: "这里是 xiaogeParents 节点"
                        }
                    },
                    props: ["firstTitle", "doudou"],
                    template: `<div>
                            <h1>{{parentTitle}}</h1>
                            <p>{{firstTitle}}</p>
                            <p>{{doudou}}</p>
                            <hr>
                            <xiaoge-child :first-param='"这是第一个参数"' :params='"这是第二个参数"'></xiaoge-child>
                            </div>
                            `,
                    components: {
                        xiaogeChild: {
                            data () {
                                return {
                                    childTitle: '这里是 xiaogeChild 节点'
                                }
                            },
                            props: ["firstParam", "params"],
                            template: `<div>
                                <h1>{{childTitle}}</h1>
                                <p>{{firstParam}}</p>
                                <p>{{params}}</p>
                            </div>`,
                        }
                    }
                }
            }
        })

    </script>
</body>

</html>

第二种写法

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <!--html给子组件传值-->
    <div id='app'>
        <!-- app有自己的data -->
        <h1>{{title}}</h1>
        <div>{{about}}</div>
        <hr>
        <!-- h-nav也有自己的data -->
        <xiaoge-parents :first-title='"来自原型的第一个参数"' :doudou="'来自原型的第二个参数'"> </xiaoge-parents>
    </div>
    <script src="https://cdn.bootcss.com/vue/2.6.10/vue.js"></script>
    <script>

        /* 父子组件通讯(传值):父组件向子组件传值,子组件接受值,实现组件与组件之间进行通讯(非父子组件通讯)
                    组件的形成:html + css + js */
        // 定义局部组件
        // 子组件
        let child = {
            xiaogeChild: {
                data () {
                    return {
                        childTitle: '这里是 xiaogeChild 节点'
                    }
                },
                template: `<div>
                            <h1>{{childTitle}}</h1>
                            <p>{{firstParam}}</p>
                            <p>{{params}}</p>
                        </div>`,
                props: ["firstParam", "params"]
            }
        }

        // 父组件
        let parent = {
            xiaogeParents: {
                data () {
                    return {
                        parentTitle: "这里是 xiaogeParents 节点"
                    }
                },
                props: ["firstTitle", "doudou"],
                template: `<div>
                                <h1>{{parentTitle}}</h1>
                                <p>{{firstTitle}}</p>
                                <p>{{doudou}}</p>
                                <hr>
                                <xiaoge-child :first-param='"这是第一个参数"' :params='"这是第二个参数"'></xiaoge-child>
                                </div>
                                `,
                components: child
            }
        }

        /* 父子组件通讯(传值):父组件向子组件传值,子组件接受值,实现组件与组件之间进行通讯(非父子组件通讯)
            组件的形成:html + css + js */
        let vm1 = new Vue({
            el: '#app',
            data: {
                about: '父组件向子组件传值,子组件接受值,实现组件与组件之间进行通讯',
                title: '这里是原始DOM',
                param: '来自原型的第二个参数'
            },
            components: parent
        })
    </script>
</body>

</html>

5、多个组件写法

components :组件中针对组件的几种赋值方式 组件可以使用 components 钩子函数实现,也可以以变量的形式实现,当以变量形式出现时需要判断是否为组件 使用指令::is=”变量名“ 判读变量是否为组件 如果是组件则调用组件显示,反之不显示。

个人推荐使用components 钩子函数形式使用组件

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>

    <div id="app">
        <h1>{{about}}</h1>
        <component-a></component-a>
        <component-b></component-b>
        <component-c></component-C>

        <!-- is():判断是否有该对象 -->
        <component :is="ABC"></component>

    </div>

    <script src="https://cdn.bootcss.com/vue/2.6.10/vue.js"></script>
    <script>

        let componentA = {
            data () {
                return {
                    aboutA: "这个是A组件"
                }
            },
            template: `<div>
                    <h2> {{aboutA}} </h2>                            
                </div>`
        }
        let componentB = {
            data () {
                return {
                    aboutB: "这个是B组件"
                }
            },
            template: `<div>
                    <h2> {{aboutB}} </h2>                            
                </div>`
        }

        let componentD = {
            data () {
                return {
                    aboutD: "这个是D组件"
                }
            },
            template: `<div>
                    <h2> {{aboutD}} </h2>                            
                </div>`
        }

        let vm = new Vue({
            el: '#app',
            data: {
                about: "这是多个组件的写法",
                ABC: componentD
            },
            components: {
                //如果键值与键名相同的情况下,es6简写;
                componentA,
                componentB: componentB,
                componentC: {
                    template: `<div>
                            <h2>{{aboutC}}</h2>                            
                        </div>`,
                    data () {
                        return {
                            aboutC: "这个是C组件"
                        }
                    }
                },
            }
        })
    </script>

</body>

</html>

6、$emit $parent 传递参数

$emit 方法调用该事件并传参

​ 如果需要在父组件中绑定事件,需要使用$emit并传递参数

$parent 获取父组件中参数

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>

    <div id="app">
        <h2>{{about}}</h2>
        <p>SUM:{{ total }}</p>
        <p>return:{{res}}</p>
        <button-counter :total="total" v-on:increment="incrementTotal"></button-counter>
        <button-counter v-on:increment="incrementTotal"></button-counter>
    </div>

    <script src="https://cdn.bootcss.com/vue/2.6.10/vue.js"></script>
    <script>
        // 父组件中调用子组件时绑定事件,在子组件中使用$emit方法调用该事件并传参
        let vm = new Vue({
            el: '#app',
            data: {
                about: "$emit 子组件给父组件赋值",
                total: 0,
                res: 0
            },
            methods: {
                incrementTotal: function (value) {
                    this.res = value
                    this.total++
                }
            },
            components: {
                buttonCounter: {
                    data () {
                        return {
                            counts: 0
                        }
                    },
                    template: `<button v-on:click="incrementHandler">{{ counts }}</button>`,
                    methods: {
                        incrementHandler: function () {
                            this.counts++
                            console.log(this.$parent.total)
                            this.$emit('increment', this.counts)
                        }
                    }
                }
            }

        })
    </script>

</body>

</html>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小戈&328

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值