Vue组件父子组件传参

295 阅读3分钟

Vue组件

在我们了解组件之前我们先来了解一下单页面应用

单页应用对于大家而言,可能是一个比较陌生的概念,但是其实大家都和单页应用打过交道。之所以这么说,是因为目前平台开发的所有中台系统的前端部分,包括Kadmin、TGS、OTA都属于单页应用。那么,到底什么是单页应用呢?

什么是单页面应用?(single page web application,SPA)

单页面应用,顾名思义,就是整个应用只有一个页面,其余的页面则是一个一个的组件。在单页面应用中所谓的页面跳转,实际上是组件之间的切换。在切换的过程中,只会引起局部的更新,而页面不会整个刷新。

单页应用的优点

  1. 局部刷新,渲染速度快。
  2. 允许浏览器在后台向服务器发出请求以完全获取其他内容或新“页面”的同时,保持当前页面的打开状态,交互性好。
  3. “页面”间数据传递十分方便,可以使用全局变量。
  4. 公共资源只需要加载一次,减少了HTTP请求数。
  5. 组件可复用。

单页应用的缺点

  1. 静态资源更新后,不会因为“页面切换”重新加载,必须手动刷新,否则可能出错。
  2. 在首页可能加载不必要的资源,当初次加载文件过多时,需要做相关的调优。否则,资源间的下载和执行相互阻塞,会导致页面初次加载速度变慢。
  3. 单页应用不利于SEO。

接下来我们来了解组件

在Vue中,每一个.vue文件都是一个组件(也是Vue的实例),而App.vue是我们的页面入口。如下图所示,页面是由一个一个的组件组成的。在组件中的data必须是一个函数返回一个对象的形式,这是为了保证组件数据的独立性,不管组件被使用多少次,都不会互相影响。

image.png

那么我们如何使用这些组件呢?

首先我们要在使用之前先进行导入,然后通过components和component在页面中注册组件,这样我们就可以在页面中去使用这些插件了。

<script>
import cateLst from '@/components/categoryList.vue'
export default {
  name: 'category',
  components: {
    "cateList":cateLst/*此处可以简写为cateList  可以自定义命名*/
  },
  data() {
    return {
    }
  },


};
</script>

接着我们这样使用即可,具体的样式和逻辑我们在使用的组件中进行编写

<template>
  <div>
      <cateLst></cateLst>
  </div>
</template>

那么,在组件进行使用的时候,我们怎么进行传值呢?

父传子 : 父组件自定义行内属性 + 子组件 props

子传父 : 父组件 自定义事件 + 子组件 $emit

第一种方法 通过v-bind:自定义属性=“xxx”进行传值 通过@(v-on)定义事件,

在组件中行内编写的属性,专业称为父传子。注意:在子组件上定义的事件都是自定义事件,即使是@click之类的也不例外。

<template>
    <div>
        <list :ary="ary" :obj="obj" @myfn="fn"></list>
    </div>
</template>
<script>
/* 
组件的本质就是实例
使用几次就创建几个实例
*/
import list from '../day1/componets/list';
export default {
    components: {
        "list": list,
    },
    data() {
        return {
            name:'小明'ary: [11, 22, 33, 44, 55, 66, 77, 88],
            obj: {
                aa: 11,
                bb: 22,
                cc: 33,
            }
        }
    },
    methods: {
        fn(value) {
            this.name = value;
        }
    },
}
</script

在App.vue使用了list组件,我们把APP.vue称为父组件 把list称为子组件,APP2是list的父组件, list是APP的子组件.

在子组件中,我们通过props接收,而父组件的事件我们通过$emit进行触发

<template>
    <div>
        <ul>
            <li v-for="(item, index) in ary" :key="index">{{ item.name }</li>
        </ul>
    </div>
</template>

<script>
export default {
    props: {
        ary: {
            type: Array,//执行传过来的数据类型
            default:function(){//默认值
            return [];
            },
        },
        obj: {
            type: Object,
            default:function(){
            return {};
            },
        }
    },
    data() {
        return {

        }
    },
    created() {
        this.$emit('add', this.value)
    },
}
</script>

2.第二种方法就是通过Vuex进行组件通信

3.通过ref获取组件实例 然后就可以使用组件的数据了

$children 是个数组 里边放的是当前组件使用的所有的子组件 vue3移除掉了 $parent 当前组件的父组件

<template>
  <div @click="f">
    <Child ref='ccc' />
  </div>
</template>
<script>
import Child from './Child'
export default {
  components: { Child},
  data() {
    return {
      ary: [111, 222, 333],
    }
  },
  methods: {
    f() {
       this.$refs.ccc//获取组件实例
    }
  },
 
}
</script>

4.provide/inject

祖先组件通过provide提供数据 所有的后代组件都可以通过inject使用数据

<script>
export default {
  provide() {//父组件提供数据
    return {
      qqq: 666
    }
  },
  data() {
    return {
      ary: [111, 222, 333],
      aaa: 'leizai'
    }
  },
  methods: {
  },
}
</script>
/* 自组件进行接收并使用*/
<template>
  <div>
    {{ qqq }}
  </div>
</template>
<script>
export default {
  name: 'child1',
  inject: ['qqq'],
  data() {
    return {
    }
  },
  methods: {
  },
}
</script>

5.通过$root获取,

$root对应的是 new Vue得到的那个根组件

6. $listeners/$attrs 一般用于组件的二次封装

  $listeners 里边存储的是父组件传进来的事件
  $attrs 里边存储的是没有被props接收的哪些父组件传进来的属性

7 利用this实例中的$parent属性

$parent属性中有父组件的所有属性和状态,但是不建议使用,封装组件时使用不安全