vue.js - Vue.js 3 - 如何在 Vue 组件之间传递数据并让两个视图也更新?
问题描述
我尝试了以下。请注意 parent.vue 中的注释行,它甚至没有为我提交新状态。但是,也许有人可以指导我为多个组件共享的全局状态找到更好的解决方案?
main.js
import { createApp } from 'vue'
import App from './App.vue'
import { createStore } from 'vuex'
const app = createApp(App);
export const store = createStore({
state: {
textProp: 'test',
count: 1
},
mutations: {
setState(state, newState) {
console.log('setState');
state = newState;
}
},
getters: {
getAll: (state) => () => {
return state;
}
}
});
app.use(store);
app.mount('#app')
父.vue
<template>
<div class="parent">
<div class="seperator" v-bind:key="item" v-for="item in items">
<child></child>
</div>
<button @click="toonAlert()">{{ btnText }}</button>
<button @click="veranderChild()">Verander child</button>
</div>
</template>
<script>
import child from "./child.vue";
import {store} from '../main';
export default {
name: "parent",
components: {
child,
},
store,
data: function () {
return {
items: [
{
id: 1,
valueText: "",
valueNumber: 0,
},
{
id: 2,
valueText: "",
valueNumber: 0,
},
{
id: 3,
valueText: "",
valueNumber: 0,
},
],
};
},
props: {
btnText: String,
},
methods: {
toonAlert() {
alert(JSON.stringify(this.$store.getters.getAll()));
},
veranderChild() {
console.log('child aan het veranderen (parentEvent)');
this.$store.commit('setState', { // This is especially not working.
textProp: 'gezet via de parent',
count: 99
})
this.$store.commit({type: 'setState'}, {
'textProp': 'gezet via de parent',
'count': 99
});
},
},
};
</script>
<style>
.seperator {
margin-bottom: 20px;
}
.parent {
/* background: lightblue; */
}
</style>
孩子.vue
<template>
<div class="child">
<div class="inputDiv">
text
<input @change="update" v-model="deText" type="text" name="deText" />
</div>
<div class="inputDiv">
nummer
<input v-model="hetNummer" type="number" name="hetNummer" />
</div>
<button @click="toonState">Toon huidige state</button>
</div>
</template>
<script>
import {store} from '../main';
export default {
name: "child",
store,
data: function() {
return {
'hetNummer': 0
}
},
methods: {
update(e) {
let newState = this.$store.state;
newState.textProp = e.target.value;
// this.$store.commit('setState', newState);
},
toonState()
{
console.log( this.$store.getters.getAll());
}
},
computed: {
deText: function() {
return '';
// return this.$store.getters.getAll().textProp;
}
}
};
</script>
<style>
.inputDiv {
float: right;
margin-bottom: 10px;
}
.child {
max-width: 300px;
height: 30px;
margin-bottom: 20px;
/* background: yellow; */
margin: 10px;
}
</style>
解决方案
你对与 Vue/Vuex 无关的 JavaScript 有一个误解。这不符合您的期望:
state = newState;
解决方案 (TL;DR)
setState(state, newState) {
Object.assign(state, newState);
}
不要设置state
变量,而是合并新属性。
解释
- JavaScript 中的对象变量是引用。这就是为什么如果您有多个变量引用同一个对象,并且您更改一个属性,它们都会发生变异。它们都只是指内存中的同一个对象,它们不是克隆。
上面的state
变量作为对 Vuex 的 state 对象的引用,你知道的。因此,当你改变它的属性时,你也改变了 Vuex 的状态属性。这都很好。
但是,当您将整个变量(不仅仅是一个属性)更改为其他内容时,它不会改变原始引用的对象(即 Vuex 的状态)。它只是破坏了引用链接并为对象创建了一个新链接newState
。所以 Vuex 状态根本不会改变。这是一个更简单的演示。
观点
state
避免这种模式,而是创建一个对象属性。然后你就可以做state.obj = newState
。
推荐阅读
- android - 有没有办法在 Flutter 中逐个滚动 ListView?
- ruby-on-rails - 在使用 RSpec 和 Factory-bot-rails 对控制器进行测试时,我得到“KeyError: Factory not registered: "user"'
- angular - 如何使用 `ng build --watch=true` 将所有 JS/CSS 内联到 html 中
- javascript - Express/Node.js .. 我阻塞了事件循环吗?
- powershell - 将具有多个工作表的多个 Excel 工作簿转换为 CSV:如何提取由公式构造的 url?
- javascript - 另一个承诺中的承诺
- php - 如何给页面一个特殊的 url 以在外部打开
- python - 了解贝叶斯过滤在 SciKit 中的工作原理并提高准确性
- php - 我如何制作一个表格来更新我的表格并在我的 TeamStats 页面上显示为一行?
- python - Python - 为什么我的数据没有被 sqlite3 中的这个循环正确添加?