我是 Vuetify 的新手,正在尝试构建一个 UI,显示已找到的 Wifi 网络以及每个 Wifi 属性的表格。对于每个已知网络,用户应该可以选择修改存储的密码,或从已知网络列表中删除 Wifi。
这是迄今为止我为实现这一目标所做的最佳尝试:
<template>
<div class="pa-4 text-center">
<v-dialog v-model="showEditDialog" max-width="600">
<v-card prepend-icon="mdi-account" title="Edit Wifi settings">
<v-card-text>
<v-row dense>
<v-col cols="12" md="4" sm="6">
<v-text-field
hint="Enter the Wifi password of your router."
label="Wifi Password *"
type="password"
required="true"
></v-text-field>
</v-col>
<v-col cols="12" sm="6">
<v-checkbox :model-value="true" label="Auto-Connect">
</v-checkbox>
</v-col>
</v-row>
<small class="text-caption text-medium-emphasis"
>* indicates a required field</small
>
</v-card-text>
<v-divider></v-divider>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn
text="Close"
variant="plain"
@click="showEditDialog = false"
></v-btn>
<v-btn
color="primary"
text="Save"
variant="tonal"
@click="showEditDialog = false"
></v-btn>
</v-card-actions>
</v-card>
</v-dialog>
<v-dialog v-model="showDeleteDialog" max-width="500">
<template v-slot:item.name="{ item }">
<v-card title="Delete Wifi">
<v-card-text>
Are you sure you want to remove {{ item.name }} from the list of
known Wifis?
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn
text="Cancel"
variant="plain"
@click="hideDeleteWifiDialog()"
></v-btn>
<v-btn
color="red"
text="Delete Wifi"
variant="tonal"
prepend-icon="$vuetify"
@click="deleteWifi(item)"
></v-btn>
</v-card-actions>
</v-card>
</template>
</v-dialog>
</div>
<v-data-table
:headers="headers"
:items="wifiNetworks"
:items-per-page="20"
:items-per-page-options="[ { value: 20, title: '20' }, { value: -1, title: 'All' } ]"
>
<template v-slot:item.autoConnect="{ item }">
<v-chip
:color="item.autoConnect ? 'green' : 'black'"
:text="item.autoConnect ? 'Yes' : 'No'"
:variant="item.autoConnect ? 'tonal' : 'text'"
size="small"
label
>
</v-chip>
</template>
<template v-slot:item.isConnected="{ item }">
<div class="text-end">
<v-chip
:color="item.isConnected ? 'green' : 'black'"
:text="item.isConnected ? 'Connected' : 'Connect'"
:variant="item.isConnected ? 'tonal' : 'outlined'"
@click="item.isConnected ? {} : { click: connect(item) }"
size="small"
label
>
</v-chip>
</div>
</template>
<template v-slot:item.action="{ item }">
<v-icon class="me-2" size="small" @click="editItem(item)">
mdi-pencil
</v-icon>
<v-icon
size="small"
@click="showDeleteWifiDialog(item)"
:disabled="false"
>
mdi-delete
</v-icon>
</template>
</v-data-table>
</template>
<script>
export default {
data: () => ({
showEditDialog: false,
showDeleteDialog: false,
headers: [
{ title: 'Network Name (SSID)', key: 'SSID' },
{ title: 'Security Type', key: 'security' },
{ title: 'Auto Connect', key: 'autoConnect' },
{ title: 'Action', key: 'action' },
{ title: 'Connection', key: 'isConnected' },
],
wifiNetworks: [
{
SSID: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
security: 'WEP',
isConnected: false,
autoConnect: true,
action: 'connect',
},
{
SSID: 'XYZ',
security: 'WPA2',
isConnected: true,
autoConnect: true,
action: 'connect',
},
{
SSID: '0x1234',
security: 'None',
isConnected: false,
autoConnect: false,
action: 'connect',
},
{
SSID: 'BGT',
security: 'WPA',
isConnected: false,
autoConnect: false,
action: 'connect',
},
],
}),
methods: {
editItem(item) {
this.showEditDialog = true
},
showDeleteWifiDialog(item) {
this.showDeleteDialog = true
},
hideDeleteWifiDialog() {
this.showDeleteDialog = false
},
deleteWifi(item) {
this.showDeleteDialog = false
// Handle deletion, send back data
},
},
}
</script>
现在的问题是我找不到将行数据传递到模式对话框(“编辑”和“删除”)的工作方法。我需要在模式对话框中打印 Wifi 的名称,并且还需要在用户单击“保存”时获取删除或修改 Wifi 时的含义信息。
有人可以帮我吗?谢谢!
您可以通过将编辑的项目保存在组件数据中来实现这一点。然后在对话框中操作该对象,并在保存时将其保存回项目数组(或在删除时将其从数组中删除)。
data: () => ({
editedItem: {},
// ...
}),
methods: {
editItem(item) {
this.editedItem = Object.assign({}, item);
this.showEditDialog = true;
},
saveItem() {
this.showEditDialog = false;
let index = this.wifiNetworks.findIndex(
(wifi) => wifi.SSID === this.editedItem.SSID
);
this.wifiNetworks[index] = Object.assign({}, this.editedItem);
},
showDeleteWifiDialog(item) {
this.editedItem = Object.assign({}, item);
this.showDeleteDialog = true;
},
hideDeleteWifiDialog() {
this.editedItem = {};
this.showDeleteDialog = false;
},
deleteWifi() {
this.wifiNetworks.splice(this.wifiNetworks.indexOf(this.editedItem), 1);
this.showDeleteDialog = false;
},
}
注意:在第二个对话框中,您有一个不属于该对话框的模板标签。
复制行项目模型的引用,以便在单击“保存”按钮之前不会更新行项目模型。
在组件实例上设置此引用,并在对话框中设置该引用的 v 模型。
实现
saveNetwork
方法以单击 Save
按钮,并将字段值从引用复制到行项目模型。
假设 SSID 是唯一的,请将
wifiNetworks
更新到网络列表,其中复制的参考中的 SSID 的网络已排除。
<template>
<div class="pa-4 text-center">
<v-dialog v-model="showEditDialog" max-width="600">
<v-card prepend-icon="mdi-account" title="Edit Wifi settings">
<v-card-text>
<v-row dense>
<v-col cols="12" md="4" sm="6">
<v-text-field
hint="Enter the Wifi password of your router."
label="Wifi Password *"
type="text"
required="true"
v-model="itemRef.value.SSID"
></v-text-field>
</v-col>
<v-col cols="12" sm="6">
<v-checkbox
v-model="itemRef.value.autoConnect"
label="Auto-Connect"
>
</v-checkbox>
</v-col>
</v-row>
<small class="text-caption text-medium-emphasis"
>* indicates a required field</small
>
</v-card-text>
<v-divider></v-divider>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn
text="Close"
variant="plain"
@click="showEditDialog = false"
></v-btn>
<v-btn
color="primary"
text="Save"
variant="tonal"
@click="saveNetwork()"
></v-btn>
</v-card-actions>
</v-card>
</v-dialog>
<v-dialog v-model="showDeleteDialog" max-width="500">
<v-card title="Delete Wifi">
<v-card-text>
Are you sure you want to remove {{ itemRef.value.SSID }} from the list
of known Wifis?
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn
text="Cancel"
variant="plain"
@click="hideDeleteWifiDialog()"
></v-btn>
<v-btn
color="red"
text="Delete Wifi"
variant="tonal"
prepend-icon="$vuetify"
@click="deleteWifi()"
></v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</div>
<v-data-table
:headers="headers"
:items="wifiNetworks"
:items-per-page="20"
:items-per-page-options="[
{ value: 20, title: '20' },
{ value: -1, title: 'All' },
]"
>
<template v-slot:item.autoConnect="{ item }">
<v-chip
:color="item.autoConnect ? 'green' : 'black'"
:text="item.autoConnect ? 'Yes' : 'No'"
:variant="item.autoConnect ? 'tonal' : 'text'"
size="small"
label
>
</v-chip>
</template>
<template v-slot:item.isConnected="{ item }">
<div class="text-end">
<v-chip
:color="item.isConnected ? 'green' : 'black'"
:text="item.isConnected ? 'Connected' : 'Connect'"
:variant="item.isConnected ? 'tonal' : 'outlined'"
@click="item.isConnected ? {} : { click: connect(item) }"
size="small"
label
>
</v-chip>
</div>
</template>
<template v-slot:item.action="{ item }">
<v-icon class="me-2" size="small" @click="editItem(item)">
mdi-pencil
</v-icon>
<v-icon
size="small"
@click="showDeleteWifiDialog(item)"
:disabled="false"
>
mdi-delete
</v-icon>
</template>
</v-data-table>
</template>
<script>
import { ref } from 'vue';
export default {
data: () => ({
showEditDialog: false,
showDeleteDialog: false,
headers: [
{ title: 'Network Name (SSID)', key: 'SSID' },
{ title: 'Security Type', key: 'security' },
{ title: 'Auto Connect', key: 'autoConnect' },
{ title: 'Action', key: 'action' },
{ title: 'Connection', key: 'isConnected' },
],
wifiNetworks: [
{
SSID: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
security: 'WEP',
isConnected: false,
autoConnect: true,
action: 'connect',
},
{
SSID: 'XYZ',
security: 'WPA2',
isConnected: true,
autoConnect: true,
action: 'connect',
},
{
SSID: '0x1234',
security: 'None',
isConnected: false,
autoConnect: false,
action: 'connect',
},
{
SSID: 'BGT',
security: 'WPA',
isConnected: false,
autoConnect: false,
action: 'connect',
},
],
}),
methods: {
editItem(item) {
this.item = item;
this.itemRef = ref({ ...item });
this.showEditDialog = true;
},
showDeleteWifiDialog(item) {
this.item = item;
this.itemRef = ref({ ...item });
this.showDeleteDialog = true;
},
saveNetwork() {
this.showEditDialog = false;
this.item.SSID = this.itemRef.value.SSID;
this.item.autoConnect = this.itemRef.value.autoConnect;
},
hideDeleteWifiDialog() {
this.showDeleteDialog = false;
},
deleteWifi(item) {
this.showDeleteDialog = false;
this.wifiNetworks = this.wifiNetworks.filter(
(w) => w.SSID !== this.itemRef.value.SSID
);
},
},
};
</script>