fix(settings): use local state in LLMTableRow to avoid props mutation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-21 11:29:49 +08:00
parent 6966ced359
commit fad41ce94a

View File

@@ -1,5 +1,5 @@
<script setup lang="ts">
import { ref, computed } from 'vue'
import { ref, computed, watch } from 'vue'
import { Eye, EyeOff, Play, ChevronDown, ChevronRight, Trash2 } from 'lucide-vue-next'
import type { LLMModelConfig } from '@/api/settings'
@@ -17,6 +17,14 @@ const emit = defineEmits<{
}>()
const showApiKey = ref(false)
const editingModel = ref<LLMModelConfig>({ ...props.model })
// Reinitialize editing model when expanding (handles editing different rows)
watch(() => props.isExpanded, (expanded, wasExpanded) => {
if (expanded && !wasExpanded) {
editingModel.value = { ...props.model }
}
})
const status = computed(() => {
if (!props.model.api_key || !props.model.model) return 'empty'
@@ -37,8 +45,8 @@ function onProviderChange() {
claude: 'https://api.anthropic.com',
deepseek: 'https://api.deepseek.com/v1'
}
if (!props.model.base_url || Object.values(defaults).includes(props.model.base_url)) {
emit('update', { ...props.model, base_url: defaults[props.model.provider] || '' })
if (!editingModel.value.base_url || Object.values(defaults).includes(editingModel.value.base_url)) {
editingModel.value.base_url = defaults[editingModel.value.provider] || ''
}
}
</script>
@@ -69,7 +77,7 @@ function onProviderChange() {
<div class="form-row">
<div class="form-group">
<label>// PROVIDER</label>
<select v-model="model.provider" @change="onProviderChange">
<select v-model="editingModel.provider" @change="onProviderChange">
<option value="openai">OpenAI</option>
<option value="claude">Claude</option>
<option value="ollama">Ollama</option>
@@ -79,18 +87,18 @@ function onProviderChange() {
</div>
<div class="form-group">
<label>// MODEL</label>
<input v-model="model.model" type="text" placeholder="gpt-4o" />
<input v-model="editingModel.model" type="text" placeholder="gpt-4o" />
</div>
</div>
<div class="form-group">
<label>// BASE URL</label>
<input v-model="model.base_url" type="text" />
<input v-model="editingModel.base_url" type="text" />
</div>
<div class="form-group">
<label>// API KEY</label>
<div class="input-with-toggle">
<input
v-model="model.api_key"
v-model="editingModel.api_key"
:type="showApiKey ? 'text' : 'password'"
placeholder="sk-..."
/>
@@ -101,13 +109,13 @@ function onProviderChange() {
</div>
</div>
<div class="panel-actions">
<button class="test-btn" @click="emit('test', model)">
<button class="test-btn" @click="emit('test', editingModel)">
<Play :size="12" /> 测试连接
</button>
<button
class="save-btn"
:disabled="status !== 'available'"
@click="emit('update', model)"
@click="emit('update', editingModel)"
>
保存
</button>