在进行Vue狂欢时(最近开始,但是到目前为止,我真的很喜欢学习这个框架),出现了几个问题。其中之一是如何从多个组件发布表单。因此,在我继续前进之前,我想问你您对这种结构方式有何想法,如果我错了,请指出正确的方向。
在这里。 我正在使用ASP.NET CORE 2.1和Vue JS模板(带有webpack)(https://github.com/MarkPieszak/aspnetcore-Vue-starter)进行SPA项目,我的项目由多个容器构成,如下所示: 在我的应用程序根目录中,我注册了多个容器
<template>
<div id="app" class="container">
<app-first-container></app-first-container>
<app-second-container></app-second-container>
<!--<app-third-container></app-third-container>-->
<app-calculate-container></app-calculate-container>
<app-result-container></app-result-container>
</div>
</template>
<script>
// imported templates
import firstContainer from './first-container'
import secondContainer from './second-container'
import calculateContainer from './calculateButton-container'
//import thirdContainer from './third-container'
import resultContainer from './result-container'
export default {
components: {
'app-first-container': firstContainer,
'app-second-container': secondContainer,
// 'app-third-container': thirdContainer,
'app-calculate-container': calculateContainer,
'app-result-container': resultContainer
}
}
</script>
在我的第一个容器中,我的脚本文件包含多个下拉列表和两个输入字段,在这里我从API提取数据,并使用获取的数据填充下拉列表和输入字段。
这样的事情(输入了一些虚拟代码进行演示)
<template>
<div>
<h1>Crops table</h1>
<p>This component demonstrates fetching data from the server. {{dataMessage}}</p>
<div class="form-row">
<div class="form-group col-md-6">
<label for="exampleFormControlSelect1" class="col-form-label-sm font-weight-bold">1. Some text</label>
<select class="form-control" id="exampleFormControlSelect1" v-model="pickedCropType" @change="getCropsByType()">
<option v-for="(cropType, index) in cropTypes" :key="index" :value="cropType.id" :data-imagesrc="cropType.imgPath">{{ cropType.name }}</option>
</select>
</div>
<div class="form-group col-md-6">
<label for="exampleFormControlSelect2" class="col-form-label-sm font-weight-bold">2. Some text</label>
<select class="form-control" id="exampleFormControlSelect2">
<option v-for="(crop, index) in cropSelectList" :key="index" :value="crop.id">{{ crop.name }}</option>
</select>
</div>
</div>
</div>
</template>
<script>
import { mapActions, mapState } from 'vuex'
export default {
data() {
return {
cropTypes: null,
cropSelectList: null,
crops: null,
pickedCropType: null,
}
},
methods: {
loadPage: async function () {
try {
//Get crop types and create a new array with crop types with an added imgPath property
var cropTypesFinal = [];
let responseCropTypes = await this.$http.get(`http://localhost:8006/api/someData`);
responseCropTypes.data.data.forEach(function (element) {
cropTypesFinal.push(tmpType);
});
} catch (err) {
window.alert(err)
console.log(err)
}
},
getCropsByType: async function () {
//Get crops by crop type
let responseCrops = await this.$http.get(`http://localhost:8006/api/crop/Type/${this.pickedCropType}`);
var responseCropsData = responseCrops.data.data;
this.cropSelectList = responseCropsData;
}
},
async created() {
this.loadPage()
}
}
</script>
在我的第二个容器中,我具有不同的下拉菜单和具有不同脚本等的不同输入字段。
所以,我的问题是:
1。)。我在第一个容器中有必填数据表单字段,在第二个容器中有附加数据,我的提交按钮在第三个容器中分开了(app-result-container) 。那么,如果不能的话,这种构造容器的正确且合理的方法是否可以指向正确的方向呢?
2。)在要为该特定容器处理/获取/提交某些数据的每个容器中输入脚本标记是否明智?我应该将scripts标签放在分开的文件中并保持结构整洁,将html文件与js文件分开。
示例: 从“某物”中导入{某物}
export default {
data () {
return {
someData: 'Hello'
}
},
methods: {
consoleLogData: function (event) {
Console.log(this.someData)
}
}
}
3。)是否可以将输入值从一个容器发送到另一个容器(在我的特殊情况下,是从第一个容器和第二个容器到app-calculate-container(第三个容器))?
如何使用已计算的导入值提交退货结果容器
答案 0 :(得分:2)
如果您希望组件之间相互通信或共享数据,则需要emit
从一个组件到父组件的事件,并通过props传递给它,或者使用某种状态管理模型,例如Vuex,您的每个组件都可以在其中收听商店。
看看下面的代码沙箱:https://codesandbox.io/s/8144oy7xy2
App.vue
<template>
<div id="app">
<child-input @input="updateName" />
<child-output :value="name" />
</div>
</template>
<script>
import ChildInput from "@/components/ChildInput.vue";
import ChildOutput from "@/components/ChildOutput.vue";
export default {
name: "App",
components: {
ChildInput,
ChildOutput
},
data() {
return {
name: ""
};
},
methods: {
updateName(e) {
this.name = e.target.value;
}
}
};
</script>
ChildInput.vue
<template>
<input type="text" @input="changeHandler">
</template>
<script>
export default {
name: "ChildInput",
methods: {
changeHandler(e) {
this.$emit("input", e);
}
}
};
</script>
ChildOutput.vue
<template>
<p>{{ value }}</p>
</template>
<script>
export default {
name: "ChildOutput",
props: {
value: {
type: String,
default: ""
}
}
};
</script>
发生了什么事?
ChildInput
组件是一个文本字段,在其中的每个更改上都会触发一个事件(使用this.$emit()
发出并通过整个事件 up 传递)。
在触发此操作时,App
在监听更改,从而触发一种更新名称数据属性的方法。
由于name
是一种反应性数据属性,并且作为对ChildOutput
组件的支持而向下传递,因此屏幕将重新渲染并使用写入的文本进行更新。
ChildInput
和ChildOutput
都不认识。是父级侦听传递给它的事件,然后向下传递新的道具。
这种工作方式很好并且易于理解,但我强烈建议您查看Vuex,因为当您完成琐碎的任务时,这种方法可能会变得凌乱和复杂。