组件

​ Vue之所以能火起来,一个是简单易用,还有就是他的模块思维,使用模块可以叫我们尽可能的减少重复的工作,这就是目前为什么模块化思维越来越火。Vue把封装起来的模块看做组件。

全局组件的创建注册与使用

​ Vue的组件注册有三个步骤:创建组件构造器,注册组件,使用组件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue注册使用组件</title>
    <style>
        .red{
            color: blueviolet;
        }
    </style>
</head>
<body>
    <div id="app">
        {{ message }}
        <input-me></input-me>
    </div>
</body>
<script src="../js/vue.js"></script>
<script>
    // 组件构造器
    var componentMe = Vue.extend({
        template: '<input type="text" value="我是组件">'
    })

    // 注册构造器并使用(注册组件名字不能使用驼峰命名)
    Vue.component('input-me', componentMe)

    app = new Vue({
        el:"#app",
        data:{
            message:'演示组件的注册与使用'
        }
    })
</script>
</html>
  1. Vue.extend()是Vue构造器的扩展,调用Vue.extend()创建的是一个组件构造器。
  2. ue.extend()构造器有一个选项对象,选项对象的template`属性用于定义组件要渲染的HTML。
  3. 使用Vue.component()注册组件时,需要提供2个参数,第1个参数时组件的标签,第2个参数是组件构造器。
  4. 组件应该挂载到某个Vue实例下,否则它不会生效。
  5. 组件使用必须在Vue监听节点下,否则不生效

###局部组件创建注册与使用

<!DOCTYPE html>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue注册使用组件</title>
    <style>
        .red{
            color: blueviolet;
        }
    </style>
</head>
<body>
    <div id="app">
        {{ message }}
        <input-me></input-me>
    </div>
    <div id="app2">
<!--        这样使用不会显示并在console下报错-->
        <input-me></input-me>
    </div>
</body>
<script src="../js/vue.js"></script>
<script>
    // 组件构造器
    var componentMe = Vue.extend({
        template: '<input type="text" value="我是组件">'
    })


    app = new Vue({
        el:"#app",
        data:{
            message:'演示组件的注册与使用'
        },
        component:{
            // 注册构造器并使用(注册组件名字不能使用驼峰命名)
            'input-me': componentMe
        }
    })
</script>
</html>

嵌套组件

​ 组件内使用组件的演示,最外层是最内层的长辈,最内层是最外层的晚辈

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue组件套组件演示</title>
    <style>
        .red{
            color: blueviolet;
        }
    </style>
</head>
<body>
    <div id="app">
        {{ message }}
        <input-me></input-me>
    </div>
</body>
<script src="../js/vue.js"></script>
<script>
    // 注册子组件
    var componentMeChild = Vue.extend({
        template:'<input type="text" value="我是子组件">'
    })

    // 组件构造器
    var componentMe = Vue.extend({
        template: '<div>组件套组件演示<component-me-child></component-me-child></div>',
        components: {
            'component-me-child':componentMeChild
        }
    })


    app = new Vue({
        el:"#app",
        data:{
            message:'Vue组件套组件演示'
        },
        components:{
            // 注册构造器并使用(注册组件名字不能使用驼峰命名)
            'input-me': componentMe,
        }
    })
</script>
</html>

###组件注册语法糖

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue注册使用组件</title>
    <style>
        .red{
            color: blueviolet;
        }
    </style>
</head>
<body>
<div id="app">
    {{ message }}
    <input-me></input-me>
</div>
</body>
<script src="../js/vue.js"></script>
<script>
    // 组件构造器与注册构造器并使用(注册组件名字不能使用驼峰命名)
    Vue.component('input-me',{
        template: '<input type="text" value="我是组件">'
    })
    app = new Vue({
        el:"#app",
        data:{
            message:'演示组件的注册与使用'
        }
    })
</script>
</html>

script或template标签

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue-script或template标签</title>
    <style>
        .red{
            color: blueviolet;
        }
    </style>
</head>
<body>
<div id="app">
    {{ message }}
    <input-me></input-me>
    <input-m-two></input-m-two>
</div>
</body>
<script type="text/x-template" id="inputMe">
    <input type="text" value="我是组件">
</script>
<template id="inputMeTwo">
    <input type="text" value="我是组件2">
</template>
<script src="../js/vue.js"></script>
<script>
    // 组件构造器与注册构造器并使用(注册组件名字不能使用驼峰命名)
    Vue.component('input-me',{
        template: '#inputMe'
    })
    Vue.component('input-m-two',{
        template: '#inputMeTwo'
    })
    app = new Vue({
        el:"#app",
        data:{
            message:'演示组件的注册与使用'
        }
    })
</script>
</html>

Vue 的组件作用域都是孤立的,不允许在子组件的模板内直接引用父组件的数据。必须使用特定的方法才能实现组件之间的数据传递。其中 App.vue 是父组件,components 文件夹下都是子组件。

官网看到这句话camelCase vs. kebab-caseHTML 特性是不区分大小写的。所以,当使用的不是字符串模版,camelCased (驼峰式) 命名的 prop 需要转换为相对应的kebab-case(短横线隔开式) 命名: 如果你使用字符串模版,则没有这些限制。

props父组件传给子组件

<child-component v-bind:子组件prop="父组件数据属性"></child-component>

####Vue组件父组件传递给子组件简单演示

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue组件父组件传递给子组件简单演示</title>
    <style>
        .red{
            color: blueviolet;
        }
    </style>
</head>
<body>
<div id="app">
    <my-component v-bind:pr-message="message"></my-component>
</div>

</body>
<script src="../js/vue.js"></script>
<template id="divMe">
    <div>我是子组件传达:{{prMessage}}</div>
</template>
<script>
    var vm = new Vue({
        el: '#app',
        data: {
            message: '父组件消息',
        },
        components: {
            'my-component': {
                template: '#divMe',
                props: ['pr-message']
            }
        }
    })
</script>
</html>

父组件传递子组件消息在传递给下级子组件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue组件父组件传递给子组件在传递给子组件简单演示</title>
    <style>
        .red{
            color: blueviolet;
        }
    </style>
</head>
<body>
<div id="app">
    <my-component v-bind:pr-message="message"></my-component>
</div>

</body>
<script src="../js/vue.js"></script>
<template id="divMe">
    <div>我是子组件传达:{{prMessage}}----<my-component-child v-bind:pr-pr-message="prMessage"></my-component-child></div>
</template>

<template id="divMeChild">
    <div>我是子组件的子组件:{{prPrMessage}}</div>
</template>

<script>
    // 说明: vue是顶级组件,他传递message传递给子组件my-component,并绑定prPrMessage,子组件内因为Html,这这时你在v-bind进行绑定,变量名就是prPrMessage,继续上边步骤就是同理的了!
    var vm = new Vue({
        el: '#app',
        data: {
            message: '父组件消息',
        },
        components: {
            'my-component': {
                template: '#divMe',
                props: ['pr-message'],
                components: {
                    'my-component-child':{
                        template: '#divMeChild',
                        props: ['prPrMessage']
                    }
                }
            }
        }
    })
</script>
</html>

子组件传递数据给父组件(如果工作中碰到复杂的就一层一层传播)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue子组件传递数据给父组件(简单)</title>
    <style>
        .red{
            color: blueviolet;
        }
    </style>
</head>
<body>
<div id="app">
    <my-component v-bind:pr-message="message"></my-component>
</div>

</body>
<script src="../js/vue.js"></script>
<template id="divMe">
    <div>我是子组件传达:{{prMessage}}----<my-component-child v-bind:pr-pr-message="prMessage"  @prsub_child="prsub"></my-component-child></div>
</template>

<template id="divMeChild">
    <div>我是子组件的子组件:{{prPrMessage}} <div><button type="button" @click="sub()" value="子组件消息" data-custvalue="我是自定义属性值" ref="sulwan">点我试试传递消息</button></div></div>
</template>

<script>
    var vm = new Vue({
        el: '#app',
        data: {
            message: '父组件消息',
        },
        components: {
            'my-component': {
                template: '#divMe',
                props: ['pr-message'],
                methods: {
                    prsub(m,u){
                        console.log('m值: '+m);
                        console.log('u值: '+u);
                    }
                },
                components: {
                    'my-component-child':{
                        template: '#divMeChild',
                        props: ['prPrMessage'],
                        methods:{
                            sub(){
                                // 打印自定义属性
                                console.log(this.$refs.sulwan.dataset.custvalue)
                                // 获取自带属性值
                                console.log(this.$refs.sulwan.value)
                                this.$emit('prsub_child',this.$refs.sulwan.value,"哈哈")
                            }
                        }
                    }
                }
            }
        }
    })
</script>
</html>

v-model

子组件修改不会修改父组件值,父组件修改影响子组件

建议不要这么绑定,因为会覆盖原值,建议使用单独方法或者计算属性记录修改

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue子组件传递数据给父组件(简单)</title>
    <style>
        .red{
            color: blueviolet;
        }
    </style>
</head>
<body>
<div id="app">
    <my-component v-bind:pr-message="message"></my-component>
</div>

</body>
<script src="../js/vue.js"></script>
<template id="divMe">
    <div>我是子组件传达:{{prMessage}}----<input type="text" v-model="prMessage" /><my-component-child v-bind:pr-pr-message="prMessage"  @prsub_child="prsub"></my-component-child></div>
</template>

<template id="divMeChild">
    <div>我是子组件的子组件:{{prPrMessage}} <div><button type="button" @click="sub()" value="子组件消息" data-custvalue="我是自定义属性值" ref="sulwan">点我试试传递消息</button>
        <!--修改位置-->
        <input type="text" v-model="prPrMessage" />
    </div></div>
</template>

<script>
    var vm = new Vue({
        el: '#app',
        data: {
            message: '父组件消息',
        },
        components: {
            'my-component': {
                template: '#divMe',
                props: ['pr-message'],
                methods: {
                    prsub(m,u){
                        console.log('m值: '+m);
                        console.log('u值: '+u);
                    }
                },
                components: {
                    'my-component-child':{
                        template: '#divMeChild',
                        props: ['prPrMessage'],
                        methods:{
                            sub(){
                                // 打印自定义属性
                                console.log(this.$refs.sulwan.dataset.custvalue)
                                // 获取自带属性值
                                console.log(this.$refs.sulwan.value)
                                this.$emit('prsub_child',this.$refs.sulwan.value,"哈哈")
                            }
                        }
                    }
                }
            }
        }
    })
</script>
</html>

.sync

子组件修改影响父组件

sync显式地指定双向绑定,这使得子组件的数据修改会回传给父组件

这个之所以不讲解了,因为VUE2.0取消了,只有在1.0版本才有,如果要实现这个功能,请使用计算函数