Hag*_*ild 5 svelte svelte-component
假设我有这个主要的应用程序:
import Field from '../components/Field.svelte';
var fields = [
{
id: 'Check',
type: 'CheckBox',
value: false,
},
{
id: 'Text'
}
];
var components = {};
$: console.log(components);
</script>
<style>
</style>
<form>
{#each fields as item}
<Field {...item} bind:bind={components[item.bind]} bind:this={components[item.id]}></Field>
{/each}
</form>
Run Code Online (Sandbox Code Playgroud)
我有两个组件,CheckBox和TextArea,都只实现 HTML 输入,而 Field 组件是这样实现的:
import CheckBox from './CheckBox.svelte';
import TextArea from './TextArea.svelte';
export let attributes = {};
export let type = 'TextArea';
export let value = '';
export let id;
export let bind;
const fieldComponents = {
'CheckBox': CheckBox,
'TextArea': TextArea
};
</script>
<svelte:component {bind} {id} value={value} this={fieldComponents[type]} {attributes}></svelte:component>
Run Code Online (Sandbox Code Playgroud)
这样我就创建了一个动态表单,它有一个复选框和一个文本区域。
我想要的是可以从组件内部访问的“绑定”属性,并且能够绑定另一个组件,这样我就可以实现这样的事情:
<input type="checkbox" bind:checked={bind.value}>
Run Code Online (Sandbox Code Playgroud)
这意味着如果 textarea 将有文本,复选框将被选中,如果它为空,复选框将被取消选中。
在所有组件渲染后,我可以使用components对象访问它们,因为我像这样绑定它们bind:this={components[item.id]}
但是在它们呈现之前我无法访问它们,有没有办法让它这样一个组件可以动态绑定到另一个?我只演示了使用 2 个组件,它也可能是一大组组件。
我想确定绑定的方法是使用数组中与另一个字段匹配的bind属性。fieldsid
我的建议是使用 Svelte 商店并将表单配置对象保存在商店中。这将允许您的任何 Svelte 组件访问表单状态。
可以在https://svelte.dev/repl/3f161dd253624d4ea7a3b8b9e5763e96?version=3.21.0上测试和分叉一个工作示例
其中 App.svelte 是:
<script>
/*
@abstract This app is used to demonstrate one way to track form state with Svelte.
We use the 'store' to save an object that will contain our form field configurations
and field values. A JSON string formatted configuration is used as opposed to a purely javascipt object so that we can for instance pull in our form configuration from a back-end database to dynmaically build our form (in this example we are simply hard-coding the JSON into the app, but for production you might want to pull from an server-side API).
*/
import Field from './Field.svelte'; // used to build our form fields
import Box from './Box.svelte'; // just for show
import { storeFE } from './store.js'; // store our form state
let objForm; // @testing - used to listen for changes in our form state
// @testing - keep up to date on the form object
const unsubscribe = storeFE.subscribe(value => {
objForm = value;
});
// opting for JSON string config (which is what we would want if we are pulling this config from say a server data API)
// the 'fIndex' value is used within our form components know which form element object to work with within our main 'storeFE' object store. the 'fType' value tells the Field.svelte component which form element to build
let objFormConfig = JSON.parse(`{
"formElements": [
{
"fIndex":0,
"fId":"cc2",
"fType": "CheckBox",
"fValue": "true",
"fDisable":"ct1.fValue==''"
},
{
"fIndex":1,
"fId":"ct1",
"fType": "TextArea",
"fValue": "textee area",
"fChangeEvent":"cc2 disable",
"fDisable":"cc2 checked is false"
}
]
}`);
// @testing: let us know when the form values have changed (the storeFE object has updated)
$: {
console.log('objForm:');
console.log(objForm);
}
$storeFE = objFormConfig; // save the initial form configuration to the store
</script>
<form>
{#each objFormConfig.formElements as item}
<Box>
<Field objAttributes={item}></Field>
</Box>
{/each}
</form>
Run Code Online (Sandbox Code Playgroud)
其中Field.svelte是:
<script>
import CheckBox from './CheckBox.svelte';
import TextArea from './TextArea.svelte';
export let objAttributes = {};
const fieldComponents = {
'CheckBox': CheckBox,
'TextArea': TextArea
};
</script>
<div>
<svelte:component this={fieldComponents[objAttributes.fType]} {objAttributes} />
</div>
Run Code Online (Sandbox Code Playgroud)
其中CheckBox.svelte是:
<script>
/* Here we want to get the store index */
import { storeFE } from './store.js';
export let objAttributes = {};
const fIndex = objAttributes.fIndex;
const strDisable = objAttributes.fDisable;
function fDisable() {
if (strDisable) {
console.log('do some stuff like check: '+strDisable);
}
}
console.log("checkbox here, showing you my field attributes:");
console.log(objAttributes);
</script>
<h2>
My checkbox
</h2>
<input id={objAttributes.fId} type=checkbox bind:checked={$storeFE.formElements[fIndex].fValue} on:change={fDisable}>
Run Code Online (Sandbox Code Playgroud)
其中TextArea.svelte是:
<script>
import { storeFE } from './store.js';
export let objAttributes = {};
const fIndex = objAttributes.fIndex;
console.log("textarea here, showing you my field attributes:");
console.log(objAttributes);
</script>
<h2>
My text
</h2>
<textarea bind:value={$storeFE.formElements[fIndex].fValue}></textarea>
Run Code Online (Sandbox Code Playgroud)
其中store.js是:
import { writable } from 'svelte/store';
export let storeFE = writable({});
Run Code Online (Sandbox Code Playgroud)
Box.svelte不是必需的,只是为了展示(从 Svelte 教程中提取):
<style>
.box {
width: 300px;
border: 1px solid #aaa;
border-radius: 2px;
box-shadow: 2px 2px 8px rgba(0,0,0,0.1);
padding: 1em;
margin: 0 0 1em 0;
}
</style>
<div class="box">
<slot></slot>
</div>
Run Code Online (Sandbox Code Playgroud)
带有表单验证的代码的另一个示例可以在此 Svelte REPL 应用程序中找到: https://svelte.dev/repl/253ddd578806497b8b54c339490f8221 ?version=3.21.0
| 归档时间: |
|
| 查看次数: |
3325 次 |
| 最近记录: |