vue组件通信的方式?

父子通信:

1、父传子:在父组件的子组件标签绑定一个自定义属性,子组件通过props获取父组件传递的数据。

//父 
//子
 props: {
    data: {
      type: Array,
      required: true
    },
    value: { // 固定的名字(v-model)
      type: Boolean,
      default: false
    },
    isShow: {
      type: Boolean,
      default: false
    }
  },

vue3通过defineProps接受props数据

//vue3获取父组件数据

defineProps({
    goods: {
        type: Array
    }
})

2、子传父:在父组件的子组件的标签上绑定一个自定义方法,子组件通过$emit触发父组件传递的方法从而传递数据给父组件。

//父
//子
 
  • {{ item }}
  • vue3中通过defineEmits接受父组件的方法

    const emit = defineEmits(['del', 'add'])
    
    
    const del = (id) => {
        emit('del', id)
    }
    const add = () => {
        emit('add')
    }

    vue3以上代码都是在setup语法糖中写的

    3、ref:通过给子组件标签定义ref属性,通过this.$refs.ref属性名或租子组件的实例

    //父
    
    //子
     methods: {
        clickMe() {
          console.log(this.$refs.child.msg)
        }
      }

    4、$parent:通过this.$parent获取父节点

    //子
     methods: {
        clickMe() {
          console.log(this.$parent)
        }
      }

    5、$root:获取根节点

    //子
     methods: {
        clickMe() {
          console.log(this.$root)
        }
      }

    6、v-model:通过双向数据绑定实现数据传递

    //父
    
    //子
     

    我是子组件

    • {{ item }}

    //props获取父组件通过v-model传递的值,值只能是value,通过value判断数据显隐 props: { data: { type: Array, required: true }, value: { // 固定的名字(v-model) type: Boolean, default: false }, isShow: { type: Boolean, default: false } },

    v-model缺点:只能使用一次,因为父组件传递的值在子组件中只能通过props获取并且值为value,不能触发多次

    7、.sync修饰符:

    //父
    
    //子
    

    我是子组件

    • {{ item }}


    {{ title }}
    props: { data: { type: Array, required: true }, value: { // 固定的名字(v-model) type: Boolean, default: false }, isShow: { type: Boolean, default: false } },

    通过父组件传递属性的时候加上.sync修饰符,子组件通过$emit接受到传递的属性通过update:属性名可进行修改

    兄弟通信:

    8、全局事件总线(事件搭桥):

    main.js文件中创建一个实例对象,通过this.bus.$emit('方法名',传递的数据)发送数据

    兄弟组件可以通过this.bus.$on('方法名',回调)接受数据

    //main.js
    // 创建一个空的vue实例对象
    Vue.prototype.bus = new Vue()
    
    //html中button按钮
    
    
    //方法(发送数据)
     methods: {
        send() {
          this.bus.$emit('send', this.msg)
          // console.log(this.$root);
          console.log(this.$parent.list);
        }
      }
    
    //方法(接受数据)
     mounted() {
        this.bus.$on('send', val => {
          // console.log(val);
          this.msg = val;
        })
      }

    vue3中使用全局事件总线需要通过mitt插件从而实现。

    下载插件以后在main.js文件引入mitt,并且创建一个新的实例,通过创建的实例进行兄弟通讯

    //main.js
    import mitt from 'mitt'
    app.config.globalProperties.mittBus = new mitt()
    
    //传递数据组件 通过getCurrentInstance的proxy获取我们的全局属性mittBus
    import { getCurrentInstance, provide, reactive, toRefs } from 'vue'
    
    const { proxy } = getCurrentInstance()
    
    //方法传递数据
    const ShowData = () => {
      proxy.mittBus.emit('openData', name.value)
      proxy.mittBus.emit('openIsShow', true)
      console.log('展示');
    }
    
    //接受数据的组件 通过getCurrentInstance的proxy获取我们的全局属性mittBus
    import { getCurrentInstance, provide, reactive, toRefs } from 'vue'
    const { proxy } = getCurrentInstance()
    //通过on方法接受回调,从而进行逻辑操作
    onMounted(() => {
        proxy.mittBus.on('openData', (data) => {
            fatherData.value = data
        })
        proxy.mittBus.on('openIsShow', (data) => {
            isShow.value = data
        })
    })

    9、vuex:

    通过集中式管理工具,从而获取数据进行获取修改等

    vue3和vue2相似,vue3可以通过useStore引入直接获取数据或者dispatch调用方法等操作

    vue2通过this.$store.dispatch/state获取数据以及获取dispatch调用方法等操作

    这里展示vue3的

    //store/index.js
    import { createStore } from 'vuex'
    
    export default createStore({
      state: {
        vuexNum: 10
      },
      getters: {
      },
      mutations: {
        handleChangeNum(state, payload) {
          console.log(payload, 'payload');
          state.vuexNum += payload
        }
      },
      actions: {
    
      },
      modules: {
      }
    })
    
    import { useStore } from 'vuex';
    const store = useStore()
    
    const handleVuexNum = () => {
      store.commit('handleChangeNum', 10)//调用actions的方法
    }

    10、pinia:类似于vuex的集中式管理工具

    需要下载pinia插件main.js全局引入

    import { createPinia } from 'pinia'
    const pinia = createPinia()
    app.config.globalProperties.sname = '刘展通'
    app.use(plugin).use(router).use(store).use(pinia).mount('#app')

    使用:目录创建文件store或者什么都可以 目录下创建pinia.js

    import { defineStore } from 'pinia'
    
    const userStore = defineStore('user', {
        state: () => {
            return {
                count: 1,
                paw2: 1,
                paw3: 1
            }
        },
        getters: {
            doubleCount: (state) => state.count * 2,
            handleDoubleCount() {
                return this.doubleCount + 1
            }
        },
        actions: {
            inc() {
                this.count++
            },
            randomNum() {
                this.count = Math.random(100 + Math.random()).toFixed(2)
            }
        }
    })
    export default userStore;
    //代码使用
    
    
    
    
    

    pina通过引入我们store下pinia.js中抛出的defineStore可以获取数据以及调用方法

    通过pinia中引入storeToRefs可以获取我们pinia仓库中的所有数据

    store为我们pinia抛出的方法 通过赋值方法 store = useStore()使store拥有pinia的属性和方法

    通过store.$patch可以批量调用我们的方法实现更新效果。

    通过$store.reset()可以实现重置功能,重置为我们最初值。

    通过store也可以直接给按钮绑定方法直接store.方法名直接调用。

    跨组件通信:

    11、provide/inject:

    通过provide发布数据 inject接受数据

    //传递者 provide也可以是个对象
    provide('provideSendData', num.value)
    //接收者  inject也可以是个数组
    const provideData = inject('provideSendData')

    12、插槽(slot):

    分为匿名插槽、具名插槽、作用域插槽

    专门一篇文章进行讲解
     

    13、消息订阅与发布

    下载pubsub-js插件

    引入pubsub在需要发送和接受的组件

    pubsub.publish发布数据

    publish.subscribe接受数据 通过回调获取数据类似于事件总线on接受方法以后获取数据那样

    你可能感兴趣的:(vue面试题,vue.js,前端,javascript)