Vue组件

组件 (Component) 是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素,封装可重用的代码。是可复用的Vue实例。

组件树

局部组件

局部组件分为声子,挂子,用子

1.声子,声明一个组件
Vue 中组件的名字首字母要大写 跟标签区分,组件中的data必须是个函数,一定要有返回值

2.挂子,挂载组件components
挂载哪个组件,这个组件就是我的父组件


3.用子,用组件
<组件名/>
template中的模板一定要有一个根标签包裹
如果仅仅是实例化vue对象中既有el 又有template,如果template中定义模板的内容,那么template模板的优先级大于el,
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
<!--    //如果template也定义这个msg属性,这块不会在显示-->
    <h4>{{ msg }}</h4>
</div>
<script src="../vue.js"></script>
<script>
    // Vue 中组件的名字首字母要大写 跟标签区分,组件中的data必须是个函数,一定要有返回值
    // 1.声子,声明一个组件
    let App = {
         data(){
            return{
                text:'天选之子'
            }
        },
        //template定义模板中的内容
        template: `
            <div id="a">
                <h3>{{ text }}</h3>
            </div>
        `
    };
    new Vue({
        //如果仅仅是实例化vue对象中既有el 又有template,如果template中定义模板的内容,
    // 那么template模板的优先级大于el
        el:'#app',
        data(){
            return{
               msg:'wind'
            }
        },
        template:`
        <div class="app">
<!--            <h1>{{ msg }}</h1>-->
<!--            //  3.用子,用组件-->
            <App/>
        </div>
        `,
        // 2.挂子,挂载组件components
        components:{
            //如果key和value一样,可以只写一个App,这里的value :App就是上面声明的App
            App:App
        }
    })
</script>



</body>
</html>
局部组件-示例1
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
<!--    在这里调用-->
   <App></App>
</div>
<script src="../vue.js"></script>
<script>

    let App = {
         data(){
            return{
                text:'天选之子'
            }
        },
        template: `
            <div id="a">
                <h3>{{ text }}</h3>
            </div>
        `
    };
    new Vue({
        //如果仅仅是实例化vue对象中既有el 又有template,如果template中定义模板的内容,
    // 那么template模板的优先级大于el
        el:'#app',
        data(){
            return{
            }
        },
        // 2.挂子,挂载组件components
        components:{
            App
        }
    })
</script>
</body>
</html>
局部组件-示例2(没有用子)
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <App></App>
</div>

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

    let Vheader = {
        data() {
            return {}
        },
        template: `
            <div>
                <h1>随风</h1>
                <h2>浪翻云</h2>
            </div>
        `
    };

    let App = {
        data() {
            return {
                text: '天选之子'
            }
        },
        template: `
            <div id="a">
                <h3>{{ text }}</h3>
                <Vheader></Vheader>
            </div>
        `,
        components: {
            Vheader
        }
    };
    new Vue({
        el: '#app',
        data() {
            return {}
        },
        // 2.挂子,挂载组件components
        components: {
            App
        }
    })
</script>
</body>
</html>
局部组件-示例3(2个组件)

 全局组件

 Vue.component('',{})

全局组件第一个参数是组件的名字,第二个参数options,全局组件不需要挂载,
在哪个组件中使用这个全局组件,这个组件就是这个全局组件的父组件,当然可以有多个父组件哈
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <App></App>
</div>

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

    // 全局组件第一个参数是组件的名字,第二个参数options,全局组件不需要挂载,
    // 在哪个组件中使用这个全局组件,这个组件就是这个全局组件的父组件,当然可以有多个父组件哈
    Vue.component('Global',{
        data(){
            return{}
        },
        template:`<button>按钮</button>`
    })
    
    let Vheader = {
        data() {
            return {}
        },
        template: `
            <div>
                <h1>随风</h1>
                <h2>浪翻云</h2>
                <Global>登录</Global>
                <Global>注册</Global>
                <Global>关闭</Global>

            </div>
        `
    };

    let App = {
        data() {
            return {
                text: '天选之子'
            }
        },
        template: `
            <div id="a">
                <h3>{{ text }}</h3>
                <Vheader></Vheader>
                <br>
                <Global></Global>
            </div>
        `,
        components: {
            Vheader
        }
    };
    new Vue({
        el: '#app',
        data() {
            return {}
        },
        // 2.挂子,挂载组件components
        components: {
            App
        }
    })
</script>
</body>
</html>
全局组件-示例1

slot内容分发

solt是vue的内置的,只需要在全局组件中加上slot标签,父组件就可以内容分发替换哈

    Vue.component('Global',{
        data(){
            return{}
        },
        template:`<button>
                <slot></slot>
</button>`
    })
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <App></App>
</div>

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

    // 全局组件第一个参数是组件的名字,第二个参数options,全局组件不需要挂载,
    // 在哪个组件中使用这个全局组件,这个组件就是这个全局组件的父组件,当然可以有多个父组件哈
    Vue.component('Global',{
        data(){
            return{}
        },
        template:`<button>
                <slot></slot>
</button>`
    })

    let Vheader = {
        data() {
            return {}
        },
        template: `
            <div>
                <h1>随风</h1>
                <h2>浪翻云</h2>
                <Global>登录</Global>
                <Global>注册</Global>
                <Global>关闭</Global>

            </div>
        `
    };

    let App = {
        data() {
            return {
                text: '天选之子'
            }
        },
        template: `
            <div id="a">
                <h3>{{ text }}</h3>
                <Vheader></Vheader>
                <br>
                <Global>按钮</Global>
            </div>
        `,
        components: {
            Vheader
        }
    };
    new Vue({
        el: '#app',
        data() {
            return {}
        },
        // 2.挂子,挂载组件components
        components: {
            App
        }
    })
</script>
</body>
</html>
全局组件solt

 父往子传值

  1.props 属性,在子组件中定义props:[ ' 任意变量名' ] 来接收父组件传过来的值,可以在子组件中任意使用

  2.父组件要定义自定义的属性,自定义的属性名字(key)要和子组件定义的props:['变量名']相同,自定义属性的值(value)要和父组件本身return

     的属性名相同

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <App></App>
</div>

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

    let Vheader = {
        data() {
            return {}
        },
        props:['msg'],
        template: `
            <div>
                <h1>随风</h1>
                <h3>{{ msg }}</h3>
            </div>
        `
    };

    let App = {
        data() {
            return {
                text: '我是父组件的数据'
            }
        },
        template: `
            <div id="a">
                <h3>{{ text }}</h3>
                <Vheader :msg = 'text'></Vheader>


            </div>
        `,
        components: {
            Vheader
        }
    };
父往子传值
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <App></App>
</div>

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

    let Vheader = {
        data() {
            return {}
        },
        // 接收父组件传来的数据
        props:['msg','post'],
        template: `
            <div>
                <h1>随风</h1>
                <h1>{{ msg }}</h1>
                <h4>{{ post.title }}</h4>
            </div>
        `
    };

    let App = {
        data() {
            return {
                text: '我是父组件的数据',
                post:{
                    id:1,
                    title:'vue太帅了'
                }
            }
        },
        template: `
            <div id="a">
                <h5>{{ text }}</h5>
                <Vheader :msg = 'text' v-bind:post ="post"></Vheader>


            </div>
        `,
传一个对象

 子往父传值

$emit()方法第一个参数:(父组件声明的自定义事件,第二参数是要传的值)

  1. 先在父组件中,子组件用子的标签上,声明一个自定义的事件(名字不能和原生JS事件名重复),绑定一个自定义的方法.

  2. 在子组件中声明一个事件,绑定一个自定义的方法.使用this.$emit('',)进行传值

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <App></App>
</div>

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

    Vue.component('Global', {
        data() {
            return {}
        },
        template: `<button @click ='clickHandler'>
                <slot></slot>
                <h1>{{ id }}</h1>
</button>`,
        props: ['id'],
        methods: {
            clickHandler() {
                this.id++;//每点一次就让值+1
                // $emit方法第一个参数:父组件声明的自定义事件,第二参数是要传的值
                this.$emit('clickHand', this.id)

            }

        }
    });

    let Vheader = {
        data() {
            return {
                post: {'id': 1, 'name': 'wind'}
            }
        },
        // 接收父组件传来的数据
        props: ['msg', 'post'],
        template: `
            <div>
                <h1>我是head组件</h1>
                <h1>随风</h1>
                <h1>{{ msg }}</h1>
                <h4>{{ post.title }}</h4>
                <Global v-bind:id="post.id" @clickHand="func"></Global>
            </div>
        `,
        methods: {
            func(val) {
                alert(val);
                this.$emit('Father',666)
            }
        }
    };

    let App = {
        data() {
            return {
                text: '我是父组件的数据',
                post: {
                    id: 1,
                    title: 'vue太帅了'
                }
            }
        },
        template: `
            <div id="a">
                我是父组件的 {{ post.id }}
                <Vheader :msg = 'text' v-bind:post ="post" @Father="father"></Vheader>
            </div>
        `,
        components: {
            Vheader
        },
        methods: {
            father(value) {
                console.log(value);
                this.post.id = value
            }
        }
    };
    new Vue({
        el: '#app',
        data() {
            return {}
        },
        components: {
            App
        }
    })
</script>
</body>
</html>
子往父传值

 平行组件传值

$on 和 $emit

  $on('Test1组件中声明的事件的名',function(val){})

  $emit('Test1组件中声明的事件名','传的值')

1.实例化一个全局的Vue对象当作公交车
2.Test1 往Test2传值  ,Test2要声明事件 $on('Test1组件中声明的事件的名',function(val){})
3.Test1 要触发事件用$emit('Test1组件中声明的事件名','传的值')
前提:这两个方法必须绑定在同一个实例化对象上
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <App></App>
</div>
<div></div>
<script src="../vue.js"></script>
<script>

    // 1.实例化一个全局的Vue对象当作公交车
    let bus = new Vue();

    // 2.Test1 往Test2传值  ,Test2要声明事件 $on('Test1组件中声明的事件的名',function(val){}) ,
    // 3.Test1 要触发事件用$emit('Test1组件中声明的事件名','传的值')
    // 前提:这两个方法必须绑定在同一个实例化对象上
    Vue.component('Test2', {
        data() {
            return {
                text: ''
            }
        },
        template: `
          <div>{{ text }}</div>
        `,
        methods: {},
        created() {

            bus.$on('testdata', (val)=> {
                alert(val);
                this.text = val
            })
        }
    });

    //
    Vue.component('Test1', {
        data() {
            return {
                msg: '我是子组件数据'
            }
        },
        template: `
            <button @click="clickHandler">传递</button>

        `,
        methods: {
            clickHandler() {
                bus.$emit('testdata', this.msg)
            }
        }
    });

    let Vhead = {
        data() {

        },
        template: `
            <div class="head">
            <Test1></Test1>
            <Test2></Test2>
            </div>
            `
    };

    let App = {
        data() {
            return {}
        },
        template: `
            <div class="app">
            <Vhead></Vhead>
</div>
            `,
        components: {
            Vhead
        }
    };

    new Vue({
        el: '#app',
        data() {
            return {}
        },
        components: {
            App
        }
    })
</script>
</body>
</html>
平行组件传值
幻想毫无价值,计划渺如尘埃,目标不可能达到。这一切的一切毫无意义——除非我们付诸行动。
原文地址:https://www.cnblogs.com/TodayWind/p/13950474.html