<p>私たちは、typescript を使用して、ノックアウトから vue 3 合成 API に段階的に移行することを決定し、プロパティの変更のアンチパターンを理解しようとしています。意図した仕事をしている動作コンポーネントがありますが、基本的に、その記述方法が推奨されるアプローチであることを確認したいと考えています。 </p>
<p>非常に単純な例は、トグルを備えたチェックボックス リスト コンポーネントです。</p>
<p>私の最大の質問は、AppList.vue で行っていることが正しいかどうかです。取得するために <code>const InternalModel = toRef(props.selected ?? []);</code> を行っています。コンポーネント内の使用できない変数と <code>selectedHandler</code> - イベントと <code>toggleAll</code> - OUT を出力するように評価されますが、ここでは手動で <code>selected</code> と <Code> を維持します;内部モデル</Code>の同期。同じものに 2 つの変数を使用するのは面倒に感じますが、同時に、内部モデルがビューを妨げる必要がないため、合理的でもあります。 </p>
<p>vuejs.org に、<code>v-model</code> で配列を使用して複数のチェックボックスを表すことができる例があることは知っていますが、それはコンポーネント内またはプロップとしてではないため、まったく同じではなく、より複雑に感じられます。私はそれを正しく解決するために一日のほとんどを費やしましたが、vue 3 の検索結果はそれほど多くなく、この特定の問題に関する結果はまったく見つかりませんでした。 </p>
<p>HomeView.vue:</p>
<p>
<pre class="brush:html;toolbar:false;"><script set lang="ts">
'vue' から { ref } をインポートします。
import AppList, { type Item } from '@/components/AppList.vue';
const fooItems = ref<Item[]>([
{ id: 1, 名前: 'foo 1' },
{ id: 2, 名前: 'foo 2' },
{ id: 3、名前: 'foo 3' }、
{ id: 4、名前: 'foo 4' }、
{ id: 5、名前: 'foo 5' }、
]);
const fooSelected = ref
([]);
</スクリプト>
<テンプレート>
<AppList :items="fooItems" v-model:selected="fooSelected"></AppList>
<div>fooselected: {{ fooSelected }}</div>
</template></pre>
</p>
<p>集合体/Applist.vue:</p>
<p>
<pre class="brush:html;toolbar:false;"><スクリプト セットアップ lang="ts">
import { computed, toRef } from 'vue';
エクスポートインターフェイス項目 {
ID番号;
名前: 文字列;
}
const props =defineProps<{
アイテム: アイテム[];
選択されましたか?: 番号[];
}>();
const innerModel = toRef(props.selected ?? []);
const Emit = defineEmits<{
'update:selected': [selected:number[]];
}>();
const selectedHandler = (e: イベント) => {
const target = <HTMLInputElement>e.target;
if (props.selected && target) {
if (target.checked) {
Emit('update:selected', [...props.selected, Number(target.value)]);
} それ以外 {
放出(
'更新:選択済み',
props.selected.filter((i: 数値) => i !== 数値(ターゲット.値))
);
}
}
};
const toggleAll = 計算済み({
取得: () => InternalModel.value.length === props.items.length && InternalModel.value.every((s) => props.items.map((item) => item.id).includes(s)),
設定: (値) => {
if (値) {
放出(
'更新:選択済み',
props.items.map((i) => i.id)
);
InternalModel.value = props.items.map((i) => i.id);
} それ以外 {
Emit('update:selected', []);
内部モデル.値 = [];
}
}、
});
</スクリプト>
<テンプレート>
<ラベル>
<input type="checkbox" v-model="toggleAll" />
すべてを切り替える
</ラベル>
<li v-for="アイテム内のアイテム" :key="item.id">
<ラベル>
<input type="checkbox" :value="item.id" v-model="internalModel" @change="selectedHandler" />
<span>id {{ item.name }}</span>
</ラベル>
</li>
</ul>
内部モデル: {{ 内部モデル }}
</template></pre>
</p>
これはもっと簡単な方法で実行できるように思えます。
fooItems
おそらく初期状態は「チェック済み」になっているはずです。selectedHandler
で、emit()
を呼び出すだけです。toggleAll
は、最終的にinternalModel
で動作する関数を作成します。Vue SFC Playground の例を次に示します。
HomeView.vue:
リーリーAppList.view:
リーリー