vue学习(三)组件传值

 组件

官网(https://cn.vuejs.org/v2/guide/components.html)

组件分为局部组件和全局组件

局部组件:是内容中国的一部分 只是在当前组件加载的时候

全部组件:如:导航栏 侧边栏 运用到任意地方

一 局部组件

简单版

<div id="app">
    <!--3. 用子-->
    <App></App>
</div>

<script>
    // App 组件  有 template + css + js
    // 1 生子
    const App = {
        template:`<h3>我是App组件</h3>`
    };

    let app = new Vue({
        el:'#app',
        data:{

        },
        // 2.挂子
        components:{
            App
        }
    })
</script>

复杂版-----主要是在生子处

<div id="app">
    <!--3. 用子-->
    <App></App>
</div>

<script>
    // App 组件  有 template + css + js
    // 1 生子
    // 在组件中的data数据 必须是一个函数,返回一个对象
    const App = {
        data() {
            return {
                msg: '我是App组件1'
            }
        },
        // template 标签必须在一个
        template: `
                <div>
                <h3>{{ msg }}</h3>
                <button @click="handelClick">提交</button>
                </div>

                    `,
        methods:{
            handelClick(){
                alert(123)
            }
        }

    };

    let app = new Vue({
        el: '#app',
        data: {},
        // 2.挂子
        components: {
            App
        }

    })
</script>

二 全局组件

全局组件

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <meta name="viewport" content="width=device-width ,initial-scale=1">
    <!--<script src="https://cdn.jsdelivr.net/npm/vue"></script>-->
    <script src="vue.js"></script>
</head>
<body>

<div id="app">
    <!--3. 用子-->
    <App></App>
</div>

<script>
    // 定义一个全局组件

    Vue.component('Vheader',{
       template:`<h1>我的导航组件</h1>`
    });
    Vue.component('Vaside',{
       template:`<h1>我的左侧导航</h1>`
    });
    // 局部组件
    const VConent = {
         template: `
                <div>
                    <h1>我是内容局部组件</h1>
                </div>

                    `
    };

    const App = {
        components:{
            VConent  // 挂载子组件
        },
        template: `
                <div>
                <Vheader></Vheader>
                <Vaside></Vaside>
                <VConent></VConent>   
                </div>

                    `

    };

    let app = new Vue({
        el: '#app',
        data: {},
        // 2.挂子
        components: {
            App
        }

    })
</script>

</body>
</html>

父传子组件

① 在子组件中写 props=[xxx] 接收父组件挂载的属性---也可以接收对象 【可以参考vue(四)作用域插槽】

② 父组件中 绑定  xxx=‘msg’

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <meta name="viewport" content="width=device-width ,initial-scale=1">
    <!--<script src="https://cdn.jsdelivr.net/npm/vue"></script>-->
    <script src="vue.js"></script>
</head>
<body>

<div id="app">
    <!--3. 用子-->
    <App></App>
</div>

<script>

    Vue.component('Vchild',{
        template:`
               <div>
                <div style="color: red">我是子组件</div>
                <h3>{{ childMsg }}</h3>
                </div>
        `,
        props:['childMsg']
    });
    const App = {
        data(){
          return{
              msg:'我是父组件传值'
          }
        },

        template: `
                <div>
                    <Vchild :childMsg="msg"></Vchild>
                </div>
                    `
    };

    let app = new Vue({
        el: '#app',
        data: {},
        // 2.挂子
        components: {
            App
        }

    })
</script>

</body>
</html>

子传父

① 在父组件中要绑定自定义事件 如: @input="inputHandler"

② 在子组件中触发原生事件,在事件函数中通过this.$emit触发自定义事件

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <meta name="viewport" content="width=device-width ,initial-scale=1">
    <!--<script src="https://cdn.jsdelivr.net/npm/vue"></script>-->
    <script src="vue.js"></script>
</head>
<body>

<div id="app">
    <!--3. 用子-->
    <App></App>
</div>

<script>

    // 子组件

    // 子传父
    // ① input框 在inputHandler使用
    Vue.component('Vchild', {
        template: `
               <div>
                <div style="color: red">我是子组件</div>
                <h3>{{ childMsg }}</h3>
                <input type="text" @input="inputHandler">
                </div>
        `,
        props: ['childMsg'],
        methods: {
            inputHandler(e) {
//                console.log(e.target.value)
                const val = e.target.value;
                this.$emit('Handlerinput', val)
            }
        }
    });
    // 父组件
    const App = {
        data() {
            return {
                msg: '我是父组件传值',
                newVal:''
            }
        },
        methods:{
            inputVal(newVal){
                this.newVal = newVal
            }
        },
        template: `
                <div>
                    <Vchild :childMsg="msg" @Handlerinput="inputVal"></Vchild>
                    <div class="father">
                        数据:{{ newVal }}
                    </div>
                </div>
                    `
    };
    let app = new Vue({
        el: '#app',
        data: {},
        // 2.挂子
        components: {
            App
        }

    })
</script>

</body>
</html>

 平行通信

① 创建一个 bus

② 通过bus.$on 绑定事件

③ 通过 bus.$emit 触发事件

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <meta name="viewport" content="width=device-width ,initial-scale=1">
    <!--<script src="https://cdn.jsdelivr.net/npm/vue"></script>-->
    <script src="vue.js"></script>

</head>
<body>

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

<script>

    const bus = new Vue();

    Vue.component('B', {
        data(){
            return {
                count:0
            }
        },
        template: `<div>{{count}}</div>`,
        // 当组件被创建出来的时候 就会立即被调用
        created(){
//            $on 绑定事件
            bus.$on('add',(n)=>{
                this.count+=n
            })
        }
    });
    Vue.component('A', {
        template: `
        <button @click="handleClick">加入购物车</button>
        `,
        methods:{
            handleClick(){
                // $emit 触发事件
                bus.$emit('add',1);
            }
        }
    });
    
    const App = {
        template: `
        <div>
            <A></A>
            <B></B>
        </div>

        `
    };


    let app = new Vue({
        el: '#app',
        components: {
            App
        }

    })
</script>

</body>
</html>

 组件通信其他方式(provide和inject)

在父组件中 provide 中提供变量,然后在子组件中通过inject来注入变量,无论组件嵌套多深,只要是调用了inject 就能拿到父组件中的变量

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <meta name="viewport" content="width=device-width ,initial-scale=1">
    <!--<script src="https://cdn.jsdelivr.net/npm/vue"></script>-->
    <script src="vue.js"></script>

</head>
<body>

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

<script>

    Vue.component('A', {
        inject:['msg'],  // 数组接收  
        template: `<div>{{msg}}</div>`,

    });


    const App = {
        provide(){
          return{
              msg:'老爹的数据'
          }
        },
        template: `
        <div>
            <A></A>
        </div>

        `
    };


    let app = new Vue({
        el: '#app',
        components: {
            App
        }

    })
</script>

</body>
</html>

原文地址:https://www.cnblogs.com/a438842265/p/11889922.html