十分钟教会你Vue组件

什么是组件 , 为什么要使用组件 ?

组件是一个vue实例, 封装标签, 样式和JS代码

因为各自独立 , 便于复用 , 还有遇到重复的标签很麻烦 , 代码重复冗余 , 不利于维护 , 这个时候就需要用组件

组件的概念

  • 组件是可复用的 Vue 实例, 封装标签, 样式和JS代码
  • 组件化 :封装的思想,把页面上 `可重用的部分` 封装为 `组件`,从而方便项目的 开发 和 维护
  • 一个页面, 可以拆分成一个个组件,一个组件就是一个整体, 每个组件可以有自己独立的 结构 样式 和 行为(html, css和js)

如何使用组件

1.创建组件, 封装要复用的标签, 样式, JS代码

2.注册组件

全局注册 – main.js中
import Vue from 'vue'
import 组件对象 from 'vue文件路径'

Vue.component("组件吗",组件对象)
局部注册 – 某.vue文件内 
import 组件对象 from 'vue文件路径'
export default {
  components:{
      "组件名":组件对象
  }
}
3.使用组件
template>
  <div id="app">
    <组件名></组件名>
  </div>
</template>

注意:组件内template只能有一个根标签

组件通信

父------>子

从一个vue组件里把值传给另一个vue组件(父---->子) , 此时就需要使用父传子技术
步骤是什么?
子组件内, props定义变量, 在子组件使用变量
父组件内, 使用子组件, 属性方式给props变量传值
<template>
  <div>
    <!-- 
      目标: 父(App.vue) -> 子(MyProduct.vue) 分别传值进入
      需求: 每次组件显示不同的数据信息
      步骤(口诀):
        1. 子组件 - props - 变量 (准备接收)
        2. 父组件 - 传值进去
     -->
    <Product title="鞋子" price="100" intro="开业大酬宾, 全场8折"></Product>
    <Product title="裤子" price="80" intro="买一送一,不打折"></Product>
    <Product title="衣服" price="120" :intro="str"></Product>
  </div>
</template>

<script>
// 1. 创建组件 (.vue文件)
// 2. 引入组件
import Product from './components/MyProduct.vue'
export default {
  data(){
    return {
      str: "老板不在,买一送二"
    }
  },
  // 3. 注册组件
  components: {
    // Product: Product // key和value变量名同名 - 简写
    Product
  }
}
</script>

<style>

</style>
// 这个是子组件
<template>
  <div class="my-product">
    <h3>标题: {
    
    { title }}</h3>
    <p>价格: {
    
    { price }}元</p>
    <p>{
    
    { intro }}</p>
  </div>
</template>

<script>
export default {
  props: ['title', 'price', 'intro']
}
</script>

<style>
.my-product {
  width: 400px;
  padding: 20px;
  border: 2px solid #000;
  border-radius: 5px;
  margin: 10px;
}
</style>

如果想循环遍历的话就把父组件改为

props是只读的 , 不能修改

从父到子的数据流向叫做单向数据流

<template>
  <div>
    <MyProduct v-for="obj in list" :key="obj.id"
    :title="obj.proname"
    :price="obj.proprice"
    :intro="obj.info"
    ></MyProduct>
  </div>
</template>

<script>
// 目标: 循环使用组件-分别传入数据
// 1. 创建组件
// 2. 引入组件
import MyProduct from './components/MyProduct'
export default {
  data() {
    return {
      list: [
        {
          id: 1,
          proname: "鞋子",
          proprice: 100,
          info: "开业大酬宾, 全场8折",
        },
        {
          id: 2,
          proname: "裤子",
          proprice: 80,
          info: "买一送一,不打折",
        },
        {
          id: 3,
          proname: "衣服",
          proprice: 120,
          info: "老板不在,买一送二",
        },
      ],
    };
  },
  // 3. 注册组件
  components: {
    // MyProduct: MyProduct
    MyProduct
  }
};
</script>

<style>
</style>

子------>父 (当子想要去改变父里的数据)

1.父组件内, 绑定自定义事件和事件处理函数

父: @自定义事件名="父methods函数"

2.子组件内, 恰当的时机, 触发 父给我绑的 自定义事件 , 导致 父methods里 事件处理函数 执行

子: this.$emit("自定义事件名", 传值) - 执行父methods里函数代码

 来看看源代码

// 父组件
<template>
  <div>
    <p>{
   
   {msg}}</p>
    <product @handle="show"/>
  </div>
</template>

<script>
// 1. 创建组件 (.vue文件)
// 2. 引入组件
import product from "./components/MyProduct.vue"
export default {
  data(){
    return{
      msg:'父组件'
    }
  },
  // 3. 注册组件
  components:{
    product
  },
  methods: {
    show(str){
      this.msg = str
      console.log('子组件的');
    }
  },
}
</script>

<style>

</style>
// 子组件
<template>
  <div class="nav">
      <p>子组件</p>
      <button @click="fn">触发子组件</button>
  </div>
</template>

<script>
export default {
    methods: {
        fn(){
            this.$emit('handle','子组件')
        }
    },
}
</script>

<style>
.nav{
    width: 300px;
    height: 200px;
    border: 1px solid skyblue;
}
</style>

组件通信EventBus

通常用于跨组件通信时使用  (当2个没有引用关系的组件之间要通信传值)

 步骤

  1.  src/EventBus/index.js – 创建空白Vue对象并导出
    import Vue from 'vue'
    // 导出空白vue对象
    export default new Vue()
  2. 在要接收值的组件(MyBrother.vue)        eventBus.$on('事件名', 函数体)
  3. 在要传递值的组件(MyProduct.vue)       eventBus.$emit('事件名', 值)

 来看看源代码

// app.vue 文件
<template>
  <div>
    <borther></borther>
    <product></product>
  </div>
</template>

<script>
//  引入两个不相干的文件
import borther from "./MyBrother.vue"
import product from "./MyProduct.vue"
export default {
  // 注册
  components:{
    borther,
    product
  }
}
</script>

<style>

</style>
// MyProduct.vue文件
<template>
  <div class="box">
      <button @click="fn">当点击时改变msg</button>
  </div>
</template>

<script>
// 引入空白vue对象(EventBus)
// 传递方 - $emit监听事件
import EventBus from "./EventBus"
export default {
    data(){
        return{
            msg:'独怆然而涕下'
        }
    },
    methods: {
        fn(){
            EventBus.$emit('send',this.msg)
            // 跨组件
        }
    },
}
</script>

<style scoped>
    .box{
    width: 400px;
    height: 200px;
    border: 1px solid #f40;
}
</style>
// MyBrother.vue 文件
<template>
  <div class="box">
      <span>{
   
   {msg}}</span>
  </div>
</template>

<script>
// 目标: 跨组件传值
// 1. 引入空白vue对象(EventBus)
// 2. 接收方 - $on监听事件
import EventBus from "./EventBus"
export default {
    data(){
        return{
            msg:'风萧萧兮易水寒'
        }
    },
    // 3. 组件创建完毕, 监听send事件
    created(){
        EventBus.$on('send',(val)=>{
            this.msg = val
        })
    }
}
</script>

<style scoped>
.box{
    width: 400px;
    height: 200px;
    border: 1px solid #f40;
}
</style>

猜你喜欢

转载自blog.csdn.net/weixin_59769148/article/details/120912085