VueBloghyhero6

vue 中组件的自定义事件,组件之间通信

2020-06-01 / 2020-07-01 / 381次浏览

首先看一个写法上的报错

不同于组件 和 prop,事件名不存在任何自动化的大小写转换。二是触发的事件名需要完全匹配监听这个事件所用的名称。举个🌰

文档说大小写会被转换 不适合用驼峰命名法,适合使用文档推荐的方法。 就短横线式 传递。

组件之间的通信。

eventBus,props,vuex,v-on,ref... 等几种

props

props是响应式的,可以做数据绑定

index.vue 父组件相关的代码

如果传给子组件的是一个变量或者数字,则需要前面加上:( v-bind的缩写 ) 绑定。这边的imgHeight 是一个变量,closeFuction 是一个方法。

<template>
    <div>
        <child :img-width = '344' :img-height='imgHeight' title='静态文字' :before-close='closeFuction'></child>
    </div>
</template>

props: {
    imgWidth: {
        type: Number,
        default: 300
    },
    imgHeight: {
        type: Number
    },
    beforeClose: {
        type: Function,
        default: function () {
            console.log( '' )
        }
    }
}

因为html对于大小写并不敏感,所以子组件中驼峰命名在在父组件中建议采用下划线。传递给子组件的方法类似于一个回调函数,调用之后可以更改父组件中的内容,也算是子组件向父组件通信了。

v-on
在使用组件时,经常会用到model。官方解释 是 v-model 本质上不过是语法糖。它负责监听用户的输入事件以更新数据。

对于v-on 官网解释用在普通元素上时,只能监听原生DOM事件。用在自定义元素组件上时,也可以监听子组件触发的自定义事件。

父组件相关代码

<template>
    <div>
        <child :img-width =  '344' :img-height='imgHeight' title="静态文字" @before-close='closeFuction'></child>
    </div>
</template>

closeFunction 是 一个方法,带参数

closeFuction (val){
    console.log( val );
    // todo
}

method: {
    doSomething( ){
        // todo
        const val = '需要传给父组件的参数';
        this.$emit('before-close',val)
        console.log( '在需要调用的地方 用this.$emit触发' )
    }
}

理解v-on 在组件上的机制。

$ref

ref 被用来给元素或子组件注册引用信息。就是绑定在普通元素上,则获取到这个DOM元素,若是绑定在组件上,则获取到的是这个组件的Vue实例vm。

<div ref='child'></div>
mounted ( ) {
    let domA = document.querySelector( '[ ref = child ]' );
    let domB = this.$ref.child;
    console.log( '$ref 可以减少获取dom节点的损耗' )
}
<template>
    <div>
        <child ref = 'childName'> <child>
    <div>
</template>

mounted ( ) {
    let childData = this.$ref.childName.$data.childDate;
    let childMethod = this.$ref.childName.doSomething;
    console.log( '都可以访问到' )
}

有一个需要注意的点,vue 更新数据是异步的,我们需要等到DOM更新完成。所以使用$ ref 进行DOM 操作的时候,需要放在created 的 $nextTick( () => {} ),或者直接放在mounted。

兄弟组件通信

vueX eventBus

vueX 比较大单独拎出去,先说eventBus。

eventBus 的原理是引入一个新的Vue实例,然后通过分别调用这个实例的事件触发和监听来实现通信和参数传递。

eventBus.js 一般会直接用公共一个文件来存放vue实例。

import Vue from 'vue';
export default new Vue( );

我们在 apple.vue 中监听一个事件

apple.vue

import eventBus from 'eventBus.js

// 我们在create 钩子中监听方法

create() {
    console.log('this.getTarhget 是一个带参数的方法,但是这边只要将俩者关联起来');
    eventBus.$on( 'getTarget',this.getTarget );
},
beforeDestroy() {
    console.log( '组件销毁前需要解绑事件。否则会出现重复触发事件的问题' );
    eventBus.$off( 'getTarget',this.getTarget )    
},
methods: {
    getTarget( param ){
        // todo
    }
}

在 orange.vue 中触发

import eventBus from 'eventBus.js';
// 必须引入同一个实例
methods: {
    doSomething() 
        eventBus.$emit(' getTarget ',22)
        console.log( '向getTarget 方法传参 22' )
    }
}

eventBus 其实非常方便,任何的组件通信都能用它来完成。但是,我们会根据情况来选择维护模式。 在模块之间通信利用eventBus。 各大模块之间的通信依旧是 vuex

vue篇之事件总线
https://juejin.im/post/5bb355dae51d450ea4020b42


vuex 有哪几种属性
答: State, Getter, Mutation, Action, Module

vuex 的 State 特性是
答:

  1. vuex 就是一个仓库,仓库里面放了好多的对象。其中state 就是数据源存放地。对应于一般的Vue对象里面的data

2.state里面存放的数据是响应式的,Vue组件从store 中读取数据。若是store中的数据发生改变,依赖这个数据的组件也会发生更新。

3.它通过mapState把全局的state 和 getters 映射到当前组件的computed 计算属性里.

vuex 的 Getter特性是

  1. getters 可以对State进行计算操作,它就是Store 的计算 属性

  2. 虽然在组件内也可以做计算属性,但是getters 可以在多个组件之间复用

  3. 如果一个状态只在一个组件内使用,是可以不用getters (getters用于状态属性计算在多个组件内)
    官网文档上面是这样描述 Getter, 需要从store中的 state中派生出一些状态,例如对列表进行过滤并且计数:

如果内部多个组件需要用到此属性,我们要么复制这个函数,或者抽取到一个共享函数然后在多处导入它。

但是无论哪种方式均不理想。

Vuex 允许我们在store 中定义'getter'( 可以认为是store 的计算属性 )。就像计算属性一样,getter的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生变化才会被重新计算。

vuex 的Mutation 特性是

  1. action 类似 mutation。

  2. 不同在于 Action 提交的是mutation,而不是直接变更状态。

  3. Action 可以包含任意异步操作

vue.js 中ajax 请求代码应该写在组件的methods 中还是 vuex 的 actions 中

  1. 如果请求来的数据 是不是要被其他组件公用,仅仅是请求的组件内使用,就不需要放在vuex 的 state 里。

  2. 如果被其他地方复用,这个很大几率上是需要的,如果需要,请将请求放入action 里,方便复用,并且包装成promise返回,在调用 async await 处理返回数据。如果不要复用这个请求,那么直接写在vue 文件里。

// 关于为什么不能在mutation 中提交代码,网上解释了一波为什么Redux 的 reducer 里 不能有异步操作。

先从Redux 的 设计层面来解释为什么Reducer 必须是纯函数

整个redux 都是函数式编程的范式,要求reducer 是纯函数是自然而然的事情,使用纯函数才能保证相同的的输入得到相同的输入。保证状态的可预测。

Redux 有三大原则:

1.单一数据源,也就是state

2.state是只读, Redux 并没有暴露出直接修改state的接口,必须通过action来触发修改。

3.使用纯函数来修改state,reducer必须是纯函数。

在Redux的源码中只用一行来表示:

currentState = currentReducer( currentState, action )

currentReducer 就是我们在createStore 中传入的 reducer,reducer是用来计算state的,所以它的返回值必须是state,也就是我们整个应用的状态,而不能是promse 之流。

这个问题也是Redux中为什么不能有副作用的原因。

Vuex 是 在 对state 进行的提交,返回当前状态, 要完整的state, 你给个异步回调算什么意思。 所以包括 redux 在内 以及 Vuex Mutation 必须是同步函数。