Vue - Vue3 组合 API 道具接收问题
Vue - Vue3 composition API props receiving problem
我无法在 Vue3 中工作:
Counter1 向 App 主页面发送值,
应用程序页面提供 Counter2 组件的道具(因此 Counter2 应该基本上显示 Counter1 发出的数据):
https://codesandbox.io/s/priceless-ishizaka-md3el?file=/src/components/Counter2.vue
我无法让它工作,我想在 Counter2 中还有更多工作要做(我尝试使用反应对象等,但没有成功)。
我有用 Vue2 编写的相同示例(单页),您可以在此处查看:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>
</head>
<body>
<div id="app">
<Counter1 @counted="handleCount"></Counter1>
<Counter2 :received="clicksReceivedAndPassedToCounter2"></Counter2>
</div>
<script>
Vue.component('Counter1', {
template: `<button @click="handleClick">Clicked {{ clicks }} times</button>`,
data: () => ({
clicks: 0
}),
methods: {
handleClick() {
this.clicks++;
this.$emit('counted', this.clicks);
}
}
});
Vue.component('Counter2', {
template: `<p>Counter2 received: {{received}}</p>`,
props: {
'received': {
type: Number,
default: 0,
required: true
}
}
});
new Vue({
el: '#app',
data() {
return {
clicksReceivedAndPassedToCounter2: 0
}
},
methods: {
handleCount(clicksReceived) {
this.clicksReceivedAndPassedToCounter2 = clicksReceived;
}
}
});
</script>
</html>
您缺少在 App
组件的模板中添加 state
:
<Counter2 :received="clicksReceivedAndPassedToCounter2"></Counter2>
应该是:
<Counter2 :received="state.clicksReceivedAndPassedToCounter2"></Counter2>
如果你想摆脱模板中的 state
并保持反应性,你可以使用 toRef
如下:
<template>
<Counter1 @counted="handleCount"></Counter1>
<p>Main page received: {{ valCounter2}}</p>
<Counter2 :received="valCounter2"></Counter2>
</template>
<script>
import { reactive, toRef } from "vue";
import Counter1 from "./components/Counter1.vue";
import Counter2 from "./components/Counter2.vue";
export default {
name: "App",
components: {
Counter1,
Counter2,
},
setup() {
const state = reactive({
clicksReceivedAndPassedToCounter2: 0,
});
function handleCount(clicksReceived) {
state.clicksReceivedAndPassedToCounter2 = clicksReceived;
}
return {
valCounter2: toRef(
state,
"clicksReceivedAndPassedToCounter2"
),
handleCount,
};
},
};
</script>
我无法在 Vue3 中工作: Counter1 向 App 主页面发送值, 应用程序页面提供 Counter2 组件的道具(因此 Counter2 应该基本上显示 Counter1 发出的数据):
https://codesandbox.io/s/priceless-ishizaka-md3el?file=/src/components/Counter2.vue
我无法让它工作,我想在 Counter2 中还有更多工作要做(我尝试使用反应对象等,但没有成功)。
我有用 Vue2 编写的相同示例(单页),您可以在此处查看:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>
</head>
<body>
<div id="app">
<Counter1 @counted="handleCount"></Counter1>
<Counter2 :received="clicksReceivedAndPassedToCounter2"></Counter2>
</div>
<script>
Vue.component('Counter1', {
template: `<button @click="handleClick">Clicked {{ clicks }} times</button>`,
data: () => ({
clicks: 0
}),
methods: {
handleClick() {
this.clicks++;
this.$emit('counted', this.clicks);
}
}
});
Vue.component('Counter2', {
template: `<p>Counter2 received: {{received}}</p>`,
props: {
'received': {
type: Number,
default: 0,
required: true
}
}
});
new Vue({
el: '#app',
data() {
return {
clicksReceivedAndPassedToCounter2: 0
}
},
methods: {
handleCount(clicksReceived) {
this.clicksReceivedAndPassedToCounter2 = clicksReceived;
}
}
});
</script>
</html>
您缺少在 App
组件的模板中添加 state
:
<Counter2 :received="clicksReceivedAndPassedToCounter2"></Counter2>
应该是:
<Counter2 :received="state.clicksReceivedAndPassedToCounter2"></Counter2>
如果你想摆脱模板中的 state
并保持反应性,你可以使用 toRef
如下:
<template>
<Counter1 @counted="handleCount"></Counter1>
<p>Main page received: {{ valCounter2}}</p>
<Counter2 :received="valCounter2"></Counter2>
</template>
<script>
import { reactive, toRef } from "vue";
import Counter1 from "./components/Counter1.vue";
import Counter2 from "./components/Counter2.vue";
export default {
name: "App",
components: {
Counter1,
Counter2,
},
setup() {
const state = reactive({
clicksReceivedAndPassedToCounter2: 0,
});
function handleCount(clicksReceived) {
state.clicksReceivedAndPassedToCounter2 = clicksReceived;
}
return {
valCounter2: toRef(
state,
"clicksReceivedAndPassedToCounter2"
),
handleCount,
};
},
};
</script>