Vue组件的传值
在vue由于组件化开发的思想,所以组件间的传值变得很重要,如何理解组件之间的传值有助于理解整个设计思想。
一.属性传值
Vue组件之间可以通过props进行值的传递。props是父组件向子组件传递数据的一种方式,子组件通过props属性接收数据。
在父组件中,首先将相应的组件模块传入该组件然后注册后可以通过v-bind指令将数据传递给子组件的props属性。
<template>
<div>
<child-component :message="parentMessage"></child-component>
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
data() {
return {
parentMessage: 'Hello from parent component'
};
},
components: {
ChildComponent
}
};
</script>
在子组件中,可以通过props选项声明接收的属性,并在模板中使用它。
<template>
<div>
<p>{{ message }}</p>
</div>
</template>
<script>
export default {
props: ['message']
};
</script>
二.自定义事件实现子传值给父
子组件向父组件传递值可以通过自定义事件的方式实现。子组件可以通过通过(
通过emit方法触发一个自定义事件,并传递需要传递的值,然后在父组件中通过监听该事件来接收传递的值。
在子组件中,可以通过$emit方法触发一个自定义事件,并传递需要传递的值。例如:
<template>
<div>
<button @click="sendMessage">Send Message</button>
</div>
</template>
<script>
export default {
methods: {
sendMessage() {
this.$emit('message', 'Hello from child component');
}
}
};
</script>
在父组件中,可以通过在子组件上监听自定义事件来接收传递的值。例如:
<template>
<div>
<child-component @message="receiveMessage"></child-component>
<p>{{ receivedMessage }}</p>
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
data() {
return {
receivedMessage: ''
};
},
components: {
ChildComponent
},
methods: {
receiveMessage(message) {
this.receivedMessage = message;
}
}
};
</script>
三.$listeners
$listeners是Vue实例的一个属性,它包含了父组件传递给当前组件的所有事件监听器。可以通过listeners将这些事件监听器绑定到当前组件上,从而实现事件的传递。
以下是一个示例,展示了如何使用listeners在子组件中绑定父组件传递的事件监听器:
<!-- ParentComponent.vue -->
<template>
<div>
<child-component @customEvent="handleCustomEvent"></child-component>
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: {
ChildComponent
},
methods: {
handleCustomEvent() {
console.log('Custom event triggered in parent component');
}
}
};
</script>
<!-- ChildComponent.vue -->
<template>
<div>
<button v-on="$listeners">Click me</button>
</div>
</template>
四.$attrs
$attrs是Vue实例的一个属性,它包含了父组件传递给当前组件的所有非 prop 属性。可以通过attrs将这些非 prop 属性绑定到当前组件的子组件上,从而实现属性的传递。
以下是一个示例,展示了如何使用attrs将父组件传递的非 prop 属性传递给子组件:
<!-- ParentComponent.vue -->
<template>
<div>
<child-component custom-attribute="some value"></child-component>
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: {
ChildComponent
}
};
</script>
<!-- ChildComponent.vue -->
<template>
<div>
<grandchild-component v-bind="$attrs"></grandchild-component>
</div>
</template>
<script>
import GrandchildComponent from './GrandchildComponent.vue';
export default {
components: {
GrandchildComponent
}
};
</script>
<!-- GrandchildComponent.vue -->
<template>
<div>
<p>{{ customAttribute }}</p>
</div>
</template>
<script>
export default {
props: ['customAttribute']
};
</script>
五.使用v-model实现组件之间的双向数据绑定。
使用v-model可以简化组件之间的双向数据绑定。
<!-- ParentComponent.vue -->
<template>
<div>
<ChildComponent v-model="message"></ChildComponent>
<p>Parent: {{ message }}</p>
</div>
</template>
<script>
import { ref } from 'vue';
import ChildComponent from './ChildComponent.vue';
export default {
components: {
ChildComponent
},
setup() {
const message = ref('');
return {
message
};
}
};
</script>
<!-- ChildComponent.vue -->
<template>
<div>
<input v-model="localMessage" />
<p>Child: {{ localMessage }}</p>
</div>
</template>
<script>
import { ref, watch } from 'vue';
export default {
props: ['modelValue'],
emits: ['update:modelValue'],
setup(props, { emit }) {
const localMessage = ref(props.modelValue);
watch(localMessage, (newVal) => {
emit('update:modelValue', newVal);
});
return {
localMessage
};
}
};
</script>
六.使用 provide 和 inject 来实现组件之间的数据传递和绑定
使用 provide 在父组件中提供数据,并在子组件中使用 inject 来访问和使用这些数据
<!-- ParentComponent.vue -->
<template>
<div>
<ChildComponent></ChildComponent>
</div>
</template>
<script>
import { provide, reactive } from 'vue';
import ChildComponent from './ChildComponent.vue';
export default {
components: {
ChildComponent
},
setup() {
const data = reactive({
message: 'Hello from parent component'
});
provide('data', data);
return {};
}
};
</script>
<!-- ChildComponent.vue -->
<template>
<div>
<p>Child: {{ data.message }}</p>
<button @click="changeMessage">Change Message</button>
</div>
</template>
<script>
import { inject } from 'vue';
export default {
setup() {
const data = inject('data');
const changeMessage = () => {
data.message = 'New message from child component';
};
return {
data,
changeMessage
};
}
};
</script>