ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Vue 父子组件通信

2021-05-02 21:04:41  阅读:153  来源: 互联网

标签:Vue const app 父子 template 组件 data


@

目录



一. Vue的组件化开发实现

  • 任何一个应用都可以抽象成一颗组件树
  • 组件里面可以再包含组件,每个组件也可以有自己的内容
    在这里插入图片描述


二. 注册组件的基本步骤

  • 创建组件构造器
  • 注册组件 (全局注册,局部注册)
  • 使用组件

在这里插入图片描述



三.组件的基本使用过程

组件化开发是用来解决什么问题的?

比如下边一块代码,我想把它在多个地方重复使用,那么怎么用呢?就是他抽象化为一个组件。

<div>
    <h1>找是个标题</h1>
    <p>今天天气真的不错</p>
    <p>哈哈。今天好开心</p>
</div>

根据步骤:写代码:

<body>
    <div id="app">
        <my-cpn></my-cpn>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        //构建组件构造函数
        const cpnC = Vue.extend({
            template: `
            <div>
               <h1>找是个标题</h1>
               <p>今天天气真的不错</p>
               <p>哈哈。今天好开心</p>
            </div>`
        })
        //注册组件

        //第一个参数是要使用的组件的名字,第二个是组件的模板名字
        Vue.component("my-cpn",cpnC)

        const app = new Vue({
            el: '#app',
            data: {
                message: '你好啊'
            }
        },)
        //使用组件
    </script>
</body>

效果图:
在这里插入图片描述
Vue可以进行嵌套使用,但是必须要挂载到一个 vue 的实例里面才行,写外边不行。:

在这里插入图片描述




3.局部组件和全局组件

刚刚注册的那种方式就是一个全局组件,可以在任何 Vue 实例中都可以进行使用,如何创建局部组件呢?

其实就是可以在某个vue实例中注册就可以了

const app = new Vue({
            el: '#app',
            data: {
                message: '你好啊'
            },
            components:{ //只能在一个实例中注册使用
                my_cpn:cpnC
            }
        },)


四. 父子组件

就是在一个组件里面嵌套一个组件:如果是在嵌套的里面注册的,那么只能在嵌套的里面使用。

<body>
    <div id="app">
        <my_cpn></my_cpn>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        //构建组件构造函数
        const cpnC1 = Vue.extend({
            template: `
            <div>
               <h1>我是标题1</h1>
               <p>今天天气真的不错,哈哈</p>
            </div>`
        })
        const cpnC2 = Vue.extend({
            template: `
            <div>
               <h1>我是标题2</h1>
               <p>今天天气真的不错,呵呵</p>
               <cpnC1></cpnC1>
            </div>`,
            components: {
                cpnC1: cpnC1
            }
        })
        //注册组件

        const app = new Vue({
            el: '#app',
            data: {
                message: '你好啊'
            },
            components: {
                my_cpn: cpnC2
            }
        }, )
        //使用组件
    </script>
</body>

在这里插入图片描述



五.注册组件语法糖

<body>
    <div id="app">
    
       <cpn1></cpn1> 全局语法糖注册
       <cpn2></cpn2> 局部语法糖注册

    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        //语法糖全局注册
        Vue.component('cpn1',{
            template: `
            <div>
               <h1>我是标题1</h1>
               <p>今天天气真的不错,哈哈</p>
            </div>`
        })


        const app = new Vue({
            el: '#app',
            data: {
                message: '你好啊'
            },
            //组件局部注册的语法糖
            components: {
                "cpn2":{
                    template:`
                    <div>
                    <h1>我是标题2</h1>
                    <p>今天天气真的不错,呵呵</p>
                    </div>`
                }
            }
        }, )
        //使用组件
    </script>
</body>



六. 组件模板抽离的写法

在上边的模板中写,多多少少的有点乱,因为在 templata 的模板里,你写了 html5 的文件,所以最好的方法,是把 html5的部分,抽象出来

使用 <template>标签进行抽象:然后通过id进行连接

 <template id="cpn">
        <div>
            <h1>我是标题1</h1>
            <p>我是内容一</p>
        </div>
    </template>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
     
        //语法糖全局注册
        Vue.component('cpn1',{
            template:'#cpn'  // 通过此处与上边 template 联系起来
        })



七. 为啥 data() 一定要是函数?

其实就是解决,用 template 不能直接访问 Vue 里面的数据,他只能访问template 自己里面的数据。

<body>
    <div id="app">
        <cpn1></cpn1>
        <cpn2></cpn2>
    </div>
    <template id="cpn">
        <div>
            <h1>我是标题1</h1>
            <p>我是内容一</p>
            <p>{{title}}</p>
        </div>
    </template>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        //语法糖全局注册
        Vue.component('cpn1', {
            template: '#cpn', // 通过此处与上边 template 联系起来
            data(){
                return{
                    title:'abc'
                }},
           methods: {
                
            },
        })


        const app = new Vue({
            el: '#app',
            data: {
                message: '你好啊'
            }
        })
    </script>
</body>

效果图:

在这里插入图片描述




八.父子组件的通信

  • 通过 props 向子组件传递数据
  • 通过事件向父组件发送消息
    在这里插入图片描述

8.1父->子组件通信

 <div id="app">
        <cpn v-bind:cmovies="movies" :cmessage="message"></cpn>
        <p>正常</p>
    </div>
    <!-- 定义一个组件 -->
    <template id="cpn">
        <div>
            <h1>标题</h1>
            <p>{{cmovies}}</p>
            <p>{{cmessage}}</p>
            <p>{{cmessages}}</p>
            <ul>
                <li v-for="item in cmovies">{{item}}</li>
            </ul>
        </div>
    </template>


    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        const cpn = {
            template: "#cpn",

            // 普通的传值写法
           // props: ['cmovies','cmessage'],
           props:{
               cmovies:Array,  //直接指名传输的数据类型
               cmessage:{
                   type:String,          // 除了指定传输类型以外,还可以指定默认值。
                   default:"暂时没有传值",
               },
               cmessages:{
                   type:String,
                   default:"暂时没有传值",
                   //required:true //这个就是默认的必须要传递的,不穿的话会有错误。
               }
               
           },
            data() {
                return {
                    
                }
            },}

        const app = new Vue({
            el: '#app',
            data: {
                message: "你好啊",
                movies: ["海王", "海贼王", "海尔兄弟"]
            },
            components: {
                // 当组件的原名和要命的名重合,就可以这样简写
                cpn
            }
        })
    </script>

效果图:

在这里插入图片描述

props的通信的类型

在这里插入图片描述
目前Vue 中不支持驼峰的命名方式:

使用类型传值(可以使用这种方法把父组件的data 里的东西提出来);

  // 往子组件传东西
        props: {
            cmonte: Array,
            wwe: String,
            message:{
                type:String,
                default:"aaaa",
            }
        },

父传子的第二个例子:

我们用的最多方式,可以通过Prop向子组件传递数据。
用一个形象的比喻来说,父子组件之间的数据传递相当于自上而下的下水管子,只能从上往下流,不能逆流。这也正是Vue的设计理念之单向数据流。而Prop正是管道和管道之间的一个衔接口,这样(水)数据才能向下流.


    <div id="app">
        <counter :count='1'></counter>
        <counter :count='2'></counter>
    </div>
    <script>
        Vue.component('counter', {
            props: ['count'], // 声明组件的时候,就声明这样一个props。
            data: function () {
                return {
                    number: this.count
                }
            },
            template: '<div @click="add">{{number}}----{{count}}</div>', // 后面当自己组件的用
            methods: {
                add: function () {
                    this.number++;
                }
            },
        })
        let vm = new Vue({
            el: "#app",
        })
    </script>

父子通信的参考资料 https://blog.csdn.net/qq_37288477/article/details/86630428


8.2子--> 父组件通信

子组件往父组件通信,更多的是传递的事件,比如手机导航栏,点击以后,应该给,在另一个显示组件里进行不同的显示。

<body>

    <!-- 父组件模板 -->
    <div id='app'>
        <cpn @itemclick="cpnclick"></cpn>
    </div>


    <!-- 子组件模板 -->
    <template id="cpn">
        <div>
            <button v-for="item in categories" @click="btnClick(item)">{{item.name}}</button>
        </div>
    </template>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>

        // 子组件
        const cpn = {
            template: '#cpn',
            data() {
                return {
                    categories: [{
                            id: 'aaa',
                            name: '热门推荐'
                        },
                        {
                            id: 'aaa',
                            name: '手机数码'
                        },
                        {
                            id: 'aaa',
                            name: '家用家电'
                        },
                        {
                            id: 'aaa',
                            name: '电脑办公'
                        },
                    ]
                }
            },
            methods: {
                btnClick(item) {
                    console.log(item);
                    // 把这个事件发送出去
                    // 都不要使用驼峰的写法
                    // 自定义事件
                    this.$emit('itemclick',item) //(事件名和参数)
                }
            },
        }

        // 父组件
        const app = new Vue({
            el: '#app',
            data: {
                message: "你好啊",
                movies: ["海王", "海贼王", "海尔兄弟"]
            },
            components: {
                // 当组件的原名和要命的名重合,就可以这样简写
                cpn
            },
            methods:{
               cpnclick(item){
                   console.log("00cpnclick",item.name)
               }
         }})
    </script>
</body>

标签:Vue,const,app,父子,template,组件,data
来源: https://www.cnblogs.com/changHai-yiXiao/p/14726395.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有