Vue:组件

组件

 通常一个应用会以一棵嵌套的组件树的形式来组织:

 

例如,你可能会有页头、侧边栏、内容区等组件,每个组件又包含了其它的像导航链接、博文之类的组件。

为了能在模板中使用,这些组件必须先注册以便 Vue 能够识别。这里有两种组件的注册类型:全局注册和局部注册。

一、局部组件

1、什么是局部组件?

  局部组件,只能在局部使用,如果想要在其他组件中使用,需要挂载

let APP = {

}

 

2、局部组件的使用?

  声明,挂载,使用((局部组件需要挂载之后才能使用))

    打油诗: 声子 挂子 用子   (声子:创建组件,挂子:在父组件挂载创建的字组件,用子:在父组件template中使用子组件中的东西)

 

 

<body>
<div id="app">
    {{ msg }}
</div>

<script src="../vue.js"></script>
<script>

------------------------------------子组件------------------------------------------------------------
    //如果仅仅是实例化vue对象中 既有el 又有template,如果template中定义模板的内容
    //        那么template模板的优先级大于el


    // 1.声子(创建子组件,相当于自定义的标签)  Vue中 组件的名字 首字母要大写 跟标签区分 组件中的data必须是个函数 一定要有返回值  (注意子组件没有el,其它都有)
    let App = {
        data(){ //数据属性
        return{
          msg:'chen'
}
//一定要有return }, //template相当于表示自定义组件(标签)的具体功能 template:` <div id="a"> <h2>{{ msg }}</h2> </div> `, methods:{ // }, }; ------------------------------根VUE------------------------------------------------------ new Vue({ el:'#app', data(){ return{ msg:'alex' } }, //3 使用子组件。template渲染整个子组件(相当于自定义一个标签),template定义模板的内容 template:` <div class="app"> <App/> </div> `, //这里注意:template里面所有的内容在一个div内(闭合标签包裹起来);否则会报错:Component template should contain exactly one root element components:{ //components字面意思:组件们 //2.挂子组件 //如果key和value一样 可以只写一个 //App:App App } }) </script> </body>

 注意:

  1)第三步,用子,也可以在el中绑定的元素标签中,直接使用子组件。

   2)子组件中的template必须得使用,不然会有报错的,因为不用template就无法知道子组件的结构,根vue里的template可以不用,因为可以直接放在el绑定的标签里面

二、全局组件

1、什么是全局组件?

  全局组件可以再任意组件中使用

  Vue.component("组件名",{ 

    })

2、全局组件的使用

  先声明创建,不需要挂载,在其他组件中直接使用

<slot></slot>   是Vue的内置组件,

<Vbtn>登录</Vbtn> 中的文字会代替<slot></slot>

 

<div id="app">
    <App></App>
    <Vbtn></Vbtn>
</div>


<script src="../vue.js"></script>
<script>
----------------------全局子组件------------------------------------------------

     //全局组件:第一个参数是组件的名字,第二个参数 options参数 它是全局组件
    Vue.component('Vbtn',{
        data(){
            return{

            }
        },
        template:`<button>
            <slot></slot> //设置<slot>可以先占位,以后使用全局组件时,<Vbtn>d注册<Vbtn>,那么'注册'会代替<slot>。如果没有事先设置的话,那么即便写了注册,也不能更改<button>中的内容
          </button>
     `,
    });


---------------------局部子组件--------------------------------------------------------

    //如果仅仅是实例化vue对象中 既有el 又有template,如果template中定义模板的内容
    //        那么template模板的优先级大于el

    let Vheader = {
        data(){
            return{}
        },
        template:`
            <div>
                <h2>alex</h2>
                <Vbtn>登录</Vbtn>    //使用,之所以写登录有用,是因为全局组件<Vvbtn>中设置了<slot>
            </div>

        `,
    };

-------------------------局部子组件---------------------------------------------------------

    // 1.声子(创建子组件,相当于自定义的标签)  Vue中 组件的名字 首字母要大写 跟标签区分 组件中的data必须是个函数 一定要有返回值  (注意没有el,其它都有)
    let App = {
        data(){ //数据属性
            return{}
        },
        //template相当于表示自定义组件(标签)的具体功能
        template:`
        <div id="a">
            <!--<h2>我是lilz</h2>-->
            <Vheader/>
            <Vbtn></Vbtn>
        </div>
        `,
        methods:{   //

        },
        components:{
            Vheader
        }
    };

------------------------根vue--------------------------------------------------
    new Vue({
        el:'#app',
        data(){
            return{
                msg:'alex'
            }
        },

        components:{   //字面意思:组件们

            //2.挂子组件
            //如果key和value一样 可以只写一个
            //App:App
            App
        }
    })
</script>

组件的嵌套

数据,数据是单向数据流的,因此组件之间存在着嵌套关系

组件传值

组件之间不管是全局组件还是子组件,都有可能是父组件或子组件

一、父组件向子组件传值(props)

子组件使用父组件中的数据,也就是父组件往子组件中传值

<div id="app">
    <App></App>
</div>
<script src="../vue.js"></script>

<script>

------------------------------------子组件-------------------------------------------------------------------
        let Vheader = {
        data(){
            return{}
        },
        //1.在子组件中声明一个props,挂载父组件中的属性,就可以在模板中使用
        props:['msg','post'],
        template:`
            <div>
                <h2>alex</h2>
                <h2>{{ msg }}</h2>
         <h2>{{ post.title }}</h2>
            </div>

        `,
    };

------------------------------------父组件--------------------------------------------------
    let App = {
        data(){ //数据属性
            return{
                text:"我是父组件中的数据",
          post:{
            id:1,
            title:'my book'
          }

            }
        },

      //2.绑定自定义属性msg(必须与子组件中的名字相同) template:`   
<div id="a">   <Vheader :msg = 'text' :post = 'post'></Vheader>    </div> `, methods:{ }, components:{ Vheader } }; ---------------------------------------------------------------------------------------------- new Vue({ el:'#app', data(){ return{ msg:'alex' } }, components:{ //字面意思:组件们 //2.挂子组件 //如果key和value一样 可以只写一个 //App:App App } }) </script>

 

二、子组件往父组件中传值($.emit)

<div id="app">
    <App></App>
</div>
<script src="../vue.js"></script>

<script>

--------------------子组件:VBtn-----------------------------------------------------------

    Vue.component('VBtn', {
        data() {
            return {}
        },
        template: `
                <button @click = 'clickHandler1'>{{ id }}</button>              一:点击按钮,调用clickHandler1方法
            `,
        props: ['id'],
        methods: {
            clickHandler1() {
                this.id ++,
//1.子组件 this.$emit('父组件中声明的自定义的事件','传值')  触发参数一的事件
                this.$emit('clickHandler2',this.id)                                    二:调用clickHandler1方法执行$emit事件,触发父组件的clickHandler2点击事件,携带值
            }
        },

    });
---------------------VBtn组件的父组件:Vheader--------------------------------------------------------------------------------------
    let Vheader = {
        data() {
            return {}
        },
        //1.在子组件中声明一个props,挂载父组件中的属性,就可以在模板中使用
        props: ['msg', 'post'],
        template: `
            <div>
                <h2>alex</h2>
                <h2>{{ msg }}</h2>
                <VBtn :id = 'post.id' @clickHandler2 = 'clickHandler3'></VBtn>               三:父组件中clickHandler2事件调用clickHandler3方法
            </div>

        `,                      //2.clickHandler2 自定义监控的事件,调用clickHandler3方法
        methods:{
            clickHandler3(value){
                alert(value);
                this.$emit('fatherHandler1',value)                         四:该方法获取到子组件中传递的值
            }
        }
    };

------------------Vheader组件的父组件-----------------------------------------------------------------------------
    let App = {
        data() { //数据属性
            return {
                text: "我是父组件中的数据",
                post: {
                    id: 1,
                    title: 'My Journey with Vue'
                }
            }
        },

        template: `
        <div id="a">
            <div>{{ post.id }} </div>
            <Vheader :msg = 'text' :post = 'post' @fatherHandler1="fatherHandler2"></Vheader>

        </div>
        `,    //2.绑定自定义属性msg(必须与子组件中的名字相同)
        methods: {
            fatherHandler2(value){
                this.post.id = value;
            }
        },
        components: {
            Vheader
        }
    };


    new Vue({
        el: '#app',
        data() {
            return {
                msg: 'alex'
            }
        },

        components: {   //字面意思:组件们

            //2.挂子组件
            //如果key和value一样 可以只写一个
            //App:App
            App
        }
    })
</script>

 

三、平行组件之间传值( $.on    $.emit)

首先声明一个公交车 vue 对象

$.emit:将数据放到公交车上

$.on:接收公交车上的数据

<div id="app">
    <App></App>
</div>

<script src="../vue.js"></script>
<script>

        let bus = new Vue();     公交车(通过公交车传送数据)

---------------------------平行组件Test2-------------------------------------------------------------

        // 这里我们可以看到Test和Test2是平行组件
        // Test==传值===》Test2   ;那么Test2要声明事件 :$on('声明的事件的名字',function(val){})   ; Test要触发事件$emit('Test2组件中声明的事件名','要传的值')
        //
        // 前提:这两个方法必须绑定在同一个实例化对象(bus对象)
        Vue.component('Test2',{
        data(){
            return{
                text:'',      //Test2组件数据是空的
            }
        },
        template:`
        <div>
            <h2>{{ text }}</h2>
        </div>
        `,
        methods:{

        },
        created(){
            bus.$on('testDate', (val)=> {
                alert(val);
                
                this.text = val;      //当另一个平行组件传值过来的时候,这里接受到数据,要使用箭头函数
            })
         }
    });
-------------------------平行组件Test---------------------------------------------------------------------------
    Vue.component('Test',{
        data(){
            return{
                msg:'我是test组件的数据',
            }
        },
        props:['txt'],
        template:`
        <div>
            <button @click = 'clickHander'>{{ txt }}</button>     //我们点击这个按钮是调用下面的方法
        </div>
        `,
        methods:{
            clickHander(){
                bus.$emit('testDate',this.msg)      //触发事件,把数据放在bus公交车上
            }
        }
    });
--------------------------------------------------------------------------------------------
    let Vheader = {
        data(){
            return{
                txt:'wusir'
            }
        },
        template:`
        <div class="header">
            <Test :txt = 'txt'></Test>
            <Test2></Test2>
        </div>
        `,   //这里可以看出Test和Test2组件是平行组件

    };

    let App = {
        data(){
            return{

            }
        },
        template:`
        <div class="app">
            <Vheader></Vheader>
        </div>
        `,
        components:{
            Vheader
        },
    };


    new Vue({
        el:'#app',
        data(){
            return{

            }
        },
        components:{
            App
        }
    })
</script>

 

posted @ 2018-11-29 09:42  葡萄想柠檬  Views(200)  Comments(0)    收藏  举报
目录代码