Vue的组件化与组件通信

262 阅读3分钟

组件化开发

组件:可以复用的vue实例,封装标签、样式和js代码
组件化:一个页面有一个或多个组件组成
组件化开发的意义:解决代码重复、冗余的问题

如何去封装一个组件

1. 定义组件

定义一个MySon的组件,并在app.vue中使用它
image.png

2.导入组件

//2. 导入组件
import MySon from './MySon.vue'

3.注册组件

export default {
  //3. 注册组件
  components: {
    MySon
  }
}

4. 使用组件

注意:在当前页面中当标签来使用,单标签、双标签都可以,但是不能和html中现有的标签同名

<template>
  <div>
    <!-- 4. 使用组件 -->
    <MySon />
  </div>
</template>

解决多个组件名样式相同,冲突的问题

默认组件style 中定义的样式是全局的=====>存在相同名字覆盖的情况

问题呈现

image.png

image.png

最后呈现到页面的结果

image.png

如何解决style属性全局覆盖的情况呢

在style标签的里面加上scoped属性
原理:

  • 会随机生成一个data-v开头的属性
  • 只要当前组件的元素和子组件的根元素才有
    image.png
    添加后的结果,解决了style标签的css样式全局覆盖的问题
    image.png

如何在父组件中修改子组件标签的样式

当父子组件都使用了scoped的情况下,我们的解决办法就是父组件的选择器 /deep/ .子组件的选择器
还是刚刚上面那个案例
在子组件中添加一个button按钮

    <button>我是子组件,要修改颜色</button>

在父组件中添加/deep/深度作用选择符

/* 给子组件的button按钮添加颜色 */
div /deep/ button{
    color: aqua;
}

没有添加前,button按钮是没有颜色的

image.png
添加后
image.png

vue的组件通信

一个页面是由多个组件构成的
每个组件的数据都是相互独立的
当我们想要使用其他组件的数据该怎么做呢

子组件想要使用父组件里面的数据,就要用到父传子的思想

父:使用其他vue组件的文件
子:被引入到这个vue文件中的组件
父子组件:如果一个组件A在组件B中被导入使用,称组件B是父组件,组件A是子组件

image.png
代码展示
父组件中的代码

<template>
  <div>
    <h1>父组件</h1>
    <!--3. 使用组件 -->
    <!-- 5. 父传子  给父组件自定义属性
        5.1 :动态绑定属性值
        5.2  自定义的属性名='数据中的属性名' -->
    <MySon :data="obj" />
  </div>
</template>

<script>
//1. 导入子组件
import MySon from './MySon.vue'
export default {
  //2. 注册组件
  components: {
    MySon
  },
  //4. 父元素定义了一些数据
  data() {
    return {
      obj: {
        name: 'xzq',
        age: 37
      }
    }
  }
}
</script>

<style>
</style>

子组件中的代码

<template>
  <div>
    <h1>子组件</h1>
    <!-- 7. 接收到的数据使用自定义属性  渲染到页面 -->
    <p>{{ data.name }}</p>
    <p>{{ data.age }}</p>
  </div>
</template>

<script>
export default {
  //6. 子组件接收   props配置项,用来接收父组件传过来的数据
  props: ['data']
}
</script>

<style>
</style>

展示出来的效果

image.png

vue的单向数据流-不要修改props

在vue中需要遵循单向数据流原则

  1. 在父传子的前提下,父组件的数据发生会通知子组件自动更新
  2. 子组件内部,不能直接修改父组件传递过来的props => props是只读的

从子组件的内部把数据传出来给父组件或者修改父组件的数据,就要用到子传父的思想

image.png
代码展示

image.png
展示到页面中的结果

image.png

小结

1.组件化的开发,一个页面是由一个或者多个组件构成的
2.如何封装一个组件,第一步先定义一个子组件,第二步再在父组件里面导入子组件,第三步注册组件,第四步是使用组件
3.默认情况下style标签是全局的,实现私有化的css样式,需要在style标签的里面加上scoped属性
4. 要想在父组件里面修改子组件里面的样式,需要在子组件的选择器前面加上/deep/
5.vue的组件通信,父传子,子传父
6. 父传子的格式:

  • 父组件::自定义属性='数据中的属性名'
  • 子组件:使用props拿到父组件传过来的数据,props:['自定义属性名']
    7.子传父的格式:
    父组件: @自定义事件='父组件里面methods的函数'
    子组件: 需要触发事件,this.$emit('自定义的事件名',需要传过去的数据)