vue组件及组件通讯通用用法详解(包括非父子组件传值时重复传值的bug解决方案)

vue组件的基本使用:

  1. 定义组件

Vue.component(组件名, 组件配置项)
组件是可复用的vue实例, 所以vue实例怎么配置, 组件就怎么配置
注意点: 除了 el, el是根实例独有的属性, 用于指定视图, 但是可以指定 template

//全局组件
Vue.component('my-div', {
    // 模板就是将来组件使用时, 展示出来的内容
    template: `
      <div>
          <div>
            你好哇
            <a href='#'>嘎嘎</a>
          </div>
          
          <button>你好哇</button>
      </div>
      `
})

//局部组件
components: {
  hello: {
    template: `
      <div>这是局部的hello组件</div>
    `
  }
}
  1. 使用组件
    直接将定义的组件名, 可以当成 自定义的html标签 使用
//HTML
<div id="app">
  <my-div></my-div>
</div>

注意点:

  1. 定义组件, 不要和 默认存在html标签 重名
  2. 定义组件, 模板内容, 必须有且只有一个根元素

组件的配置

  1. vue组件是可复用的 vue实例, 所以vue实例怎么配置, 组件就怎么配置
  2. 除了 el, el是 vue根实例的 独有属性, 指定视图, 一般组件配置的是 template
  3. data 在vue根实例中, 配置的直接是一个对象, 但是在组件中配置的是一个函数, 返回一个对象 (保证组件数据的独立性)
Vue.component('demo', {
// methods, data, template, 八个钩子函数, filter, computed
template: `
  <div>
    //这是demo组件 
    <button @click="fn">按钮</button>
    <p>{{ count }}</p>
  </div>
`,
data() {
  // 每个组件实例在被初始化时, 都会执行 data 函数, 将返回的对象, 作为数据使用
  // 每次执行 data 函数, 都会新创建一个 obj 对象, 可以保证每个组件实例的数据是独立的
  // const obj = {
  //   count: 100
  // }
  // return obj

  return {
    count: 100
  }
},
methods: {
  fn () {
    this.count++
  }
}
})

组件通讯

组件中的数据定义在data中,data是一个函数,这个函数会返回一个对象

父传子

父传子利用props

**父组件代码**
<template>
    <header-box :title-txt="showTitleTxt"></header-box>
</template>
<script>
    import Header from './header'
    export default {
        name: 'index',
        components: {
            'header-box': Header
        },
        data () {
            return {
                showTitleTxt: '首页'
            }
        }
    }
</script>


**子组件代码**
<template>
    <header>
        {{thisTitleTxt}}
    </header>
</template>
<script>
    export default {
        name: 'header-box',
        props: {
            titleTxt: String
        },
        data () {
            return {
                thisTitleTxt: this.titleTxt
            }
        }
    }
</script>

子传父

  1. 利用 o n 和 on和 onemit 即子组件利用一个事件来触发$emit来传递出去一个事件及参数,然后在父组件里绑定这个事件,然后处理这个事件,获取传递的参数
  2. 子组件改变父组件传递的props(你会发现通过props可传递复杂类型数据,可以通过子组件改变数据内容,不推荐使用,因为vue是规定props是单向绑定)
*通过$on,$emit*
**父组件代码**
<template>
    <div id="counter-event-example">
      <p>{{ total }}</p>
      <button-counter v-on:increment="incrementTotal"></button-counter>
</div>
</template>
<script>
    import ButtonCounter from './buttonCounter'
    export default {
        name: 'index',
        components: {
            'button-conuter': ButtonCounter
        },
        data () {
            return {
                total: 0
            }
        },
        methods: {
            incrementTotal () {
                this.total++
            }
        }
    }
</script>


**子组件代码**
<template>
    <button @click="incrementCounter">{{counter}}</button>
</template>
<script>
    export default {
        name: 'button-counter',
        data () {
            return {
                counter: 0
            }
        },
        metheds: {
            incrementCounter () {
                this.$emit('increment')
                this.counter++
            }
        }
    }
</script>

非父子

创建一个空的vue实例,然后挂载到当前的vue实例的原型上,然后一个组件进行 e m i t 传 递 事 件 以 及 需 要 传 递 的 数 据 。 在 另 一 个 组 件 那 里 就 可 以 进 行 使 用 emit传递事件以及需要传递的数据。在另一个组件那里就可以进行使用 emit使on来接受这个事件并处理这个传递参数

//在main.js中引入
let bus =new Vue()
Vue.prototype.bus = bus
使用过程中的有两个坑
  1. 在点击跳转的第一次之后值没有传递过去
  2. 从第二次开始传递过去,但是之后传递的都是累积重复传值重复次数是(n-1)次
坑一原因及解决方法
  1. 第一个原因是因为当我们还停留在第一个组件的时候,第二个组件还没有被created,所以emit事件是无法在另一个组件被on到的。
  2. 在组件跳转过程中两个组件是这样进行生命周期转换的 ,点击跳转-B组件created-B组件beforeMount-A组件beforeDestory-A组件destory
//解决方法:在A组件beforeDestroy里进行emit,这个时候B组件就已经created了
 beforeDestroy () {

 bus.$emit('get', {
        item: this.item,
        date: this.date
      })
 },

坑二原因及解决方法

因为emit里的事件会不断的累加,所以会按次数进行加载上去,要在on完之后要销毁才行

解决方法:

// 传值完成之后,在beforeDestroy里面使用off消除事件
   beforeDestroy () {
    bus.$off('get', this.myhandle)
  },

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值