@TOC

1.组件化

Vue学习之组件化_html

Vue学习之组件化_vue.js_02

2.注册组件

Vue学习之组件化_Vue_03

<!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'>
    <!-- //3.使用组件 -->
    <my-cpn></my-cpn>
</div>
<script src='../js/vue.js'></script>
<script>
    //1.创建组件构造器对象(es6 ` 可以换行不用+)
    const cpnC = Vue.extend({
        template: ` 
        <div>
            <h2>我是标题</h2>
            <p>我是内容,哈哈哈</p>
            <p>我是内容,呵呵呵</p>
        </div>`
    })
    //2.注册组件
    Vue.component('my-cpn',cpnC)
    


    const app = new Vue({
        el:'#app', //用于挂载要管理的元素
        data:{ //定义数据
            message:    '你好啊,李银河!',
            name:   'codewhy'
        }
    })
</script>
</body>
</html>

3.注册组件步骤解析

Vue学习之组件化_html_04

Vue学习之组件化_Vue_05

注:必须在new Vue挂载的实例之下,才被渲染出来

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'>
    <cpn></cpn>
    <cpn></cpn>
</div>

<div id='app2'>
    <cpn></cpn>
</div>
<script src='../js/vue.js'></script>
<script>
    //1.创建组件构造器对象(es6 ` 可以换行不用+)
    const cpnC = Vue.extend({
        template: ` 
        <div>
            <h2>我是标题</h2>
            <p>我是内容,哈哈哈</p>
            <p>我是内容,呵呵呵</p>
        </div>`
    })
    //2.注册组件(全局组件),意味着可以在多个Vue的实例下面使用
    //Vue.component('my-cpn',cpnC)
    
    const app = new Vue({
        el:'#app', //用于挂载要管理的元素
        data:{ //定义数据
            message:    '你好啊,李银河!',
            name:   'codewhy'
        },components: {
            //局部组件:
            // cpn 使用组件时候的标签名
            cpn:cpnC
        }
    });
    const app2 = new Vue({
        el:'#app2', //用于挂载要管理的元素
        data:{ //定义数据
            message:    '你好啊,李银河!',
            name:   'codewhy'
        }
    })
</script>
</body>
</html>

Vue学习之组件化_Vue_06

Vue学习之组件化_vue.js_07

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'>
    <cpn2></cpn2>
</div>

<div id='app2'>
    <cpn></cpn>
</div>
<script src='../js/vue.js'></script>
<script>
    //1.创建第一个组件
    const cpnC1 = Vue.extend({
        template: ` 
            <div>
                <h2>我是标题1</h2>
                <p>我是内容,哈哈哈</p>
            </div>`
    });
    //2.创建第二个组件(父组件)
    const cpnC2 = Vue.extend({
        template: ` 
        <div>
            <h2>我是标题2</h2>
            <p>我是内容,呵呵呵</p>
            <cpn1></cpn1>
        </div>`,
        components:{
            cpn1:cpnC1
        }
    });

    //root组件
    const app = new Vue({
        el:'#app', //用于挂载要管理的元素
        data:{ //定义数据
            message:    '你好啊,李银河!',
            name:   'codewhy'
        },components: {
            //2.注册:局部组件:
            // cpn 使用组件时候的标签名
            cpn2:cpnC2
        }
    });

</script>
</body>
</html>

Vue学习之组件化_Vue_08

6.注册组件的语法糖

Vue学习之组件化_Vue_09

Vue学习之组件化_Vue_10

Vue学习之组件化_html_11

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'>
    <cpn></cpn>
</div>
<!-- 1.第一种 -->
<!-- <script type="text/x-template" id="cpn">
<div>
    <h2>我是标题</h2>
    <p>我是内容</p>
</div>
</script> -->

<!-- 2.第二种 -->
<template id="cpn">
    <div>
        <h2>我是标题</h2>
        <p>我是内容</p>
    </div>
</template>
<script src='../js/vue.js'></script>
<script>
    //1.注册一个全局组件
    Vue.component('cpn',{
        template:`#cpn`
    })
    const app = new Vue({
        el:'#app', //用于挂载要管理的元素
        data:{ //定义数据
            message:    '你好啊,李银河!',
            name:   'codewhy'
        }
    })
</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'>
    <cpn></cpn>
</div>
<!-- 1.第一种 -->
<!-- <script type="text/x-template" id="cpn">
<div>
    <h2>我是标题</h2>
    <p>我是内容</p>
</div>
</script> -->

<!-- 2.第二种 -->
<template id="cpn">
    <div>
        <h2>我是标题</h2>
        <p>我是内容</p>
    </div>
</template>
<script src='../js/vue.js'></script>
<script>
    const app = new Vue({
        el:'#app', //用于挂载要管理的元素
        data:{ //定义数据
            message:    '你好啊,李银河!',
            name:   'codewhy'
        },
        components: {
            'cpn':{
                template:'#cpn'
            }
        }
    })
</script>
</body>
</html>

8.组件数据

Vue学习之组件化_Vue_12

注:组件内不能访问data数据,所以Vue组件因该有自己保存数据的地方

Vue学习之组件化_Vue_13

  • 为什么必须是一个函数?

Vue学习之组件化_html_14

9.父子间通信

Vue学习之组件化_vue.js_15

10.父级向子级传递

Vue学习之组件化_Vue_16

<!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'>
    <cpn :cmovies='movies' :cmessage='message'></cpn>
</div>
<template id="cpn">
    <div>
        <ul>
            <li v-for="item in cmovies">{{item}}</li>
        </ul>
        <p> {{cmessage}}</p>
        <h2>{{cmovies}}</h2>
    </div>
</template>
<script src='../js/vue.js'></script>
<script>
    // 父传子:props
    //局部组件
    const cpn = {
        template:'#cpn',
        //props: ['cmovies','cmessage']
        props:{
            //1.类型限制
            //cmovies:Array,
            //cmessage:String

            //2.提供一些默认值
            cmessage:{
                type:String,
                default:"aaaaa",
                required:true ///必传
            },
            //类型是对象或数组的时候,默认值必须是一个函数
            cmovies:{
                type:Array,
                default(){
                    return []
                }
            }
        }
    }
    const app = new Vue({
        el:'#app', //用于挂载要管理的元素
        data:{ //定义数据
            message:    '你好啊,李银河!',
            name:   'codewhy',
            movies: ['海','王者','夏洛特']
        },
        components: {
            'cpn':cpn
        }
    })
</script>
</body>
</html>
  • 数据验证的写法(props对象)

11.props驼峰标识

注:vue不支持直接的驼峰标识,需要进一步的转换,如:childMyMessage,需要在绑定的时候使用:child-my-message

<!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'>
    <cpn :cinfo='info' :child-my-message ="message"></cpn>
    
</div>
<template id="cpn">
    <!-- 如果有多个标签,需要外部有个div包起来 -->
    <div>
        <h2>{{cinfo}}</h2>
        <h2>{{childMyMessage}}</h2>
    </div>
</template>
<script src='../js/vue.js'></script>
<script>

    const cpn = {
        template: '#cpn',
        props:{
            cinfo:{
                type : Object,
                default(){
                    return {}
                }
            },
            childMyMessage:{
                type : String,
                default : ''
            }
        }
    }
    const app = new Vue({
        el:'#app', //用于挂载要管理的元素
        data:{ //定义数据
            message:    '你好啊,李银河!',
            name:   'codewhy',
            info:{
                name:   'why',
                age:    18,
                height: 1.88
            }
        },
        components: {
            'cpn':cpn
        }
    })
</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>
</head>
<body>
<!-- 父组件模板 -->
<div id='app'>
   <cpn v-on:itemclick="cpnClick"></cpn>
</div>

<!-- 子组件模板 -->
<template id="cpn">
    <!-- 如果有多个标签,需要外部有个div包起来 -->
    <div>
        <button v-for='item in categories' @click="btnClick(item)">{{item.name}}</button>
    </div>
</template>
<script src='../js/vue.js'></script>
<script>
    ///1.子组件
     const cpn = {
        template: '#cpn',
        data(){
            return {
                categories:[
                    {id:    'aaa',name: '热门推荐'},
                    {id:    'bbb',name: '手机数码'},
                    {id:    'ccc',name: '家用家电'},
                    {id:    'ddd',name: '电脑办公'},
                ]
            }
        },methods:{
            btnClick(item){
                //console.log(item);
                // 发射事件,自定义事件,子传父
                this.$emit('itemclick',item)
            }
        }
     }
    //2.父组件
    const app = new Vue({
        el:'#app', //用于挂载要管理的元素
        data:{ //定义数据
            message:    '你好啊,李银河!',
            name:   'codewhy'
        },
        components: {
            cpn
        },methods:{
            cpnClick(item){
                console.log('cpnClick',item);
            }
        }
    })
</script>
</body>
</html>