组件间常见的传值方式

在Vue.js中,以下是十种常见的组件间传值方式:

  1. Props(父组件向子组件传值):使用props属性来向子组件传递数据。

  2. Emit(子组件向父组件传值):子组件通过$emit方法触发自定义事件,父组件通过监听这些事件来接收子组件传递的值。

  3. Provide/Inject(祖先组件向后代组件传值):使用provide选项在祖先级组件中提供数据,然后在后代组件中使用inject选项来接收这些数据。

  4. Vuex(全局状态管理):使用Vuex来创建全局的store,组件通过dispatch触发action来改变状态,其他组件通过getters或订阅变化来获取状态。

  5. $attrs/$listeners(透传属性和事件):通过设置inheritAttrs选项和$attrs/$listeners来在高层组件传递属性和事件给低层组件。

  6. $parent 和 $children(父子组件之间的直接引用):通过parent属性可以直接访问父组件的实例,通过$children数组可以直接访问子组件的实例。

  7. $refs(通过引用访问组件实例):通过ref属性可以为组件添加一个唯一的引用标识,在父组件中可以通过refs属性访问到子组件的实例。

  8. EventBus(事件总线):创建一个Vue实例作为事件总线,组件通过这个实例的emit和on方法进行事件的发布和订阅,传递数据。

  9. 状态提升(兄弟组件之间传值):将需要共享的数据放到它们共同的父组件中,然后通过props和emit在父组件中传递数据。

  10. URL参数(路由传参):使用路由的params、query、hash等方式,将数据通过URL传递给目标组件。

这些传值方式可以根据具体场景和需求选择合适的方式来实现组件之间的数据传递和交互。

一.props

父组件:

<template>
  <child-component :propName="propValue"></child-component>
</template>

<script>
import ChildComponent from './ChildComponent.vue';

export default {
  components: {
    ChildComponent
  },
  data() {
    return {
      propValue: 'Value from parent component'
    };
  }
};
</script>

 子组件:

<template>
  <div>{{ propName }}</div>
</template>

<script>
export default {
  props: ['propName']
};
</script>

 二.Emit

子组件:

<template>
  <button @click="emitValue">Emit Value</button>
</template>

<script>
export default {
  methods: {
    emitValue() {
      this.$emit('custom-event', 'Value from child component');
    }
  }
};
</script>

 父组件:

<template>
  <child-component @custom-event="handleEvent"></child-component>
</template>

<script>
import ChildComponent from './ChildComponent.vue';

export default {
  components: {
    ChildComponent
  },
  methods: {
    handleEvent(value) {
      console.log(value); // Output: Value from child component
    }
  }
};
</script>

 三.Provide/Inject

祖先组件:

<template>
  <child-component></child-component>
</template>

<script>
import ChildComponent from './ChildComponent.vue';

export default {
  components: {
    ChildComponent
  },
  provide: {
    providedValue: 'Value from ancestor component'
  }
};
</script>

后代组件: 

<template>
  <div>{{ injectedValue }}</div>
</template>

<script>
export default {
  inject: ['providedValue'],
  computed: {
    injectedValue() {
      return this.providedValue;
    }
  }
};
</script>

 四.Vuex

创建store.js文件:

import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    globalValue: 'Global value'
  },
  mutations: {
    updateGlobalValue(state, payload) {
      state.globalValue = payload;
    }
  },
  actions: {
    updateGlobalValue({ commit }, payload) {
      commit('updateGlobalValue', payload);
    }
  },
  getters: {
    getGlobalValue(state) {
      return state.globalValue;
    }
  }
});

 在main.js中引入store.js:

import Vue from 'vue';
import store from './store';

new Vue({
  store,
  render: h => h(App)
}).$mount('#app');

组件中使用Vuex: 

<template>
  <div>
    <div>{{ globalValue }}</div>
    <button @click="updateValue">Update Value</button>
  </div>
</template>

<script>
import { mapState, mapActions } from 'vuex';

export default {
  computed: {
    ...mapState(['globalValue'])
  },
  methods: {
    ...mapActions(['updateGlobalValue']),
    updateValue() {
      this.updateGlobalValue('New global value');
    }
  }
};
</script>

 五.$attrs/listeners:

高层组件:

<template>
  <child-component v-bind="$attrs" v-on="$listeners"></child-component>
</template>

<script>
import ChildComponent from './ChildComponent.vue';

export default {
  components: {
    ChildComponent
  }
};
</script>

 低层组件:

<template>
  <input v-bind="$attrs" v-on="$listeners">
</template>

 六.$parent 和 $children

父组件:

<template>
  <child-component></child-component>
</template>

<script>
import ChildComponent from './ChildComponent.vue';

export default {
  components: {
    ChildComponent
  },
  mounted() {
    console.log(this.$children); // Output: [ChildComponent instance]
  }
};
</script>

 子组件:

<template>
  <div>{{ $parent.propValue }}</div>
</template>

<script>
export default {
  mounted() {
    console.log(this.$parent.propValue); // Output: Value from parent component
  }
};
</script>

七.$refs

父组件:

<template>
  <child-component ref="childComponent"></child-component>
</template>

<script>
import ChildComponent from './ChildComponent.vue';

export default {
  components: {
    ChildComponent
  },
  mounted() {
    console.log(this.$refs.childComponent);
this.$refs.childComponent.someMethod(); // Call a method in child component
}
};
</script>

 子组件:


<template>
  <div>Child Component</div>
</template>

<script>
export default {
  methods: {
    someMethod() {
      console.log('Method called in child component');
    }
  }
};
</script>

 八.EventBus

事件总线:

// eventBus.js
import Vue from 'vue';
export const eventBus = new Vue();

// main.js
import { eventBus } from './eventBus';

new Vue({
  created() {
    eventBus.$on('custom-event', this.handleEvent);
  },
  methods: {
    handleEvent(value) {
      console.log(value); // Output: Value from child component
    }
  },
  render: h => h(App)
}).$mount('#app');

 子组件:

<template>
  <button @click="emitValue">Emit Value</button>
</template>

<script>
import { eventBus } from './eventBus';

export default {
  methods: {
    emitValue() {
      eventBus.$emit('custom-event', 'Value from child component');
    }
  }
};
</script>

九.状态提升 

父组件:

<template>
  <div>
    <child-component v-bind:propValue="sharedValue" v-on:updateValue="updateSharedValue"></child-component>
    <another-child-component v-bind:propValue="sharedValue"></another-child-component>
  </div>
</template>

<script>
import ChildComponent from './ChildComponent.vue';
import AnotherChildComponent from './AnotherChildComponent.vue';

export default {
  components: {
    ChildComponent,
    AnotherChildComponent
  },
  data() {
    return {
      sharedValue: ''
    };
  },
  methods: {
    updateSharedValue(value) {
      this.sharedValue = value;
    }
  }
};
</script>

 子组件1:

<template>
  <div>
    <input v-model="propValue" @input="updateValue">
  </div>
</template>

<script>
export default {
  props: ['propValue'],
  methods: {
    updateValue() {
      this.$emit('updateValue', this.propValue);
    }
  }
};
</script>

 子组件2:

<template>
  <div>
    <div>{{ propValue }}</div>
  </div>
</template>

<script>
export default {
  props: ['propValue']
};
</script>

 

 十.URL参数

路由配置:

import VueRouter from 'vue-router';

const router = new VueRouter({
  routes: [
    {
      path: '/component/:id',
      component: MyComponent
    }
  ]
});

组件中获取参数: 

<template>
  <div>{{ $route.params.id }}</div>
</template>

<script>
export default {
  created() {
    console.log(this.$route.params.id);
  }
};
</script>

 

在上面的代码中,我们使用不同的方式展示了传值的示例:

  1. Props:使用props属性将数据传递给子组件。
  2. Emit:子组件通过触发自定义事件,父组件通过@custom-event监听事件并处理传递的数据。
  3. Provide/Inject:在祖先组件中提供数据,后代组件使用inject接收数据。
  4. Vuex:使用Vuex库来管理全局状态,组件之间通过store进行状态共享。
  5. $attrs/$listeners:透传属性和事件给子组件。
  6. $parent/$children:通过parent和children访问父子组件的实例。
  7. refs:使用ref属性给组件添加引用,通过refs访问组件实例。
  8. EventBus:通过事件总线发布和订阅事件进行组件间通信。
  9. 状态提升:将共享数据放到共同的父组件中,通过props和emit在父组件中传递数据给子组件。
  10. URL参数:使用路由的params、query、hash等方式传递数据。

请注意,以上代码仅用于演示不同的传值方式,具体实现可能需要在组件中添加逻辑和事件处理。

  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 React 中,有多种方式可以实现组件之间的值传递。以下是一些常见方式: 1. Props(属性):通过在父组件中给组件传递属性,组件可以通过 props 对象来获取这些属性值。父组件中的属性变化会触发组件的重新渲染。 2. State(状态):每个组件都有自己的状态对象,可以通过 setState 方法来更新状态并触发重新渲染。父组件可以通过 props 将状态值传递给组件,并通过回调函数来修改父组件的状态。 3. Context(上下文):Context 提供了一种在组件树中共享数据的方式,可以在父组件中创建一个 Context 对象,并通过 Provider 组件将数据传递给组件组件可以通过 Consumer 组件或 useContext 钩来访问这些数据。 4. Redux 或其他状态管理库:使用 Redux 或其他状态管理库可以将应用的状态集中管理,并通过提供的 API 来进行状态的读取和更新。这样不同组件之间可以共享和传递状态,而不需要通过 props 层层传递。 5. 发布订阅模式或事件总线:可以使用发布订阅模式或事件总线来实现组件之间的解耦和通信。一个组件可以发布一个事件,其他组件可以订阅该事件并执行相应的操作。 这些是常见组件传值方式,选择哪种方式取决于具体的场景和需求。在实际开发中,根据项目的规模和复杂度,选择合适的方式来进行组件的数据传递。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值