为什么我的视图部分消失了?
Why is the section of my view disappears?
我有一个用 livewire 制作的视图,它包含两个动态添加的口语部分和另一个课程和证书部分。在我添加添加证书部分之前,语言部分工作正常。现在,当用户单击证书部分的添加部分以添加新的部分时,添加的语言部分之一会消失,然后在您添加另一个语言部分后会再次出现。我猜它会在视图重新呈现后再次出现。我一直在返回并强制将函数从 render
方法移动到 update/updated/hydrate/dehydrate
但没有运气。起初,我认为它与我在我的视图中使用的 $loop->index
有关,但在更改之后我意识到它不是。我在这里遇到了死胡同,无法弄清楚这里发生了什么。
我还对正在发生的事情进行了屏幕记录,这样可能会有所帮助:
https://drive.google.com/file/d/1Hq2wTKcPvhs05SKFMICaRoOAzpSyj9Iz/view?usp=sharing
查看部分:
<!-- language section -->
<div class="card card-profile shadow-sm mt-4">
<div class="px-4 mt-4 mb-4">
<div class="h5 font-weight-bold mb-4">Spoken languages</div>
<div class="heading text-muted mb-4">you only can add 3 languages to your profile.</div>
@foreach ($languages as $lindex => $language)
<div class="card card-body mb-4" wire:key="{{ $lindex }}">
<div class="text-left"><span class="fa fa-trash text-gray language-delete" wire:click="removeLanguage({{ $lindex }}, {{ !empty($language['id']) ? $language['id'] : 0 }})"></span></div>
<div class="row">
<div class="form-group col-md-6">
<label class="" for="languageName">language</label>
<select class="form-control form-control-alternative" name="language-name" {{-- id="languageName" --}} wire:model="languages.{{ $lindex }}.language_name">
<option value="" class="form-control" selected disabled>select language</option>
@foreach ($language_names as $name)
<option value="{{ $name->abbreviation }}" class="form-control">{{ $name->language }}</option>
@endforeach
</select>
</div>
<div class="form-group col-md-6">
<label class="" for="languageProficiency">proficiency level</label>
<select class="form-control form-control-alternative" name="language-proficiency" {{-- id="languageProficiency" --}} wire:model="languages.{{ $lindex }}.language_level">
<option value="" class="form-control" selected disabled>proficiency level</option>
@foreach ($language_levels as $level)
<option value="{{ $level->level }}" class="form-control">{{ $level->name }}</option>
@endforeach
</select>
</div>
</div>
</div>
@endforeach
@error('languages.*.language_level')
<small class="text-warning">{{ $message }}</small>
@enderror
@error('languages.*.language_language')
<small class="text-warning">{{ $message }}</small>
@enderror
@if (count($languages) < 3)
<div class="row">
<div class="col-md-12">
<button type="button" class="btn btn-outline-secondary btn-round btn-block" wire:click="addLanguage"><span class="btn-inner--icon"><i class="fa fa-plus fa-2x"></i></span></button>
</div>
</div>
@endif
</div>
</div>
<!-- end language section -->
<!-- other certificates section -->
<div class="card card-profile shadow-sm mt-4">
<div class="px-4 mt-4 mb-4">
<div class="h5 font-weight-bold mb-4">Other related certificates</div>
<div class="heading text-muted mb-4">if you have other related certificates in your files you can add then here.</div>
@foreach ($certificates as $cindex => $certificate)
<div class="card card-body mb-4" wire:key="{{ $cindex }}">
<div class="row">
<div class="form-group col-md-6">
<label class="" for="other-certificates-name">certificate name</label>
<input type="text" class="form-control form-control-alternative" placeholder="" name="ptherCertificatesName">
</div>
<div class="form-group col-md-6">
<label class="" for="other-certificates-school-name">School name</label>
<input type="text" class="form-control form-control-alternative" placeholder="" name="otherCertificatesSchoolName">
</div>
<div class="form-group col-md-6">
<label class="" for="other-certificates-verification-link">URL<small>(optional)</small></label>
<input type="text" class="form-control form-control-alternative text-left" placeholder="" name="otherCertificatesVerificationLink">
</div>
<div class="form-group col" dir="ltr">
<label class="" for="other-certificates-grad-date" dir="rtl">finished date</label>
<div class="input-group input-group-alternative">
<div class="input-group-prepend">
<span class="input-group-text"><i class="ni ni-calendar-grid-58"></i></span>
</div>
<input type="text" class="form-control form-control-alternative datePicker" placeholder="" name="otherCertificatesGradDate" value="">
</div>
</div>
</div>
</div>
@endforeach
@if (count($certificates) < 5)
<div class="row">
<div class="col-md-12">
<button type="button" class="btn btn-outline-secondary btn-round btn-block" wire:click="addCertificate"><span class="btn-inner--icon"><i class="fa fa-plus fa-2x"></i></span></button>
</div>
</div>
@endif
</div>
</div>
<!-- end other certificates section -->
Livewire 组件控制器:
<?php
namespace App\Http\Livewire;
use Livewire\Component;
use App\Models\CityName;
use App\Models\Language;
use App\Models\LanguageLevel;
use App\Models\User;
use App\Models\UserLanguage;
use App\Models\UserProfile;
use Illuminate\Validation\Rule;
use Illuminate\Support\Facades\Auth;
class UserInfo extends Component
{
public $name;
public $email;
public $phone;
public $states = [];
public $selectedstate;
public $cities = [];
public $selectedcity;
public $jobTitle;
public $aboutMe;
public $employer;
public $position;
public $edu_course;
public $edu_school;
public $edu_level;
public $edu_start_date;
public $edu_end_date;
public $employment_looking;
public $employment_hired;
public $twitter;
public $linkedin;
public $github;
public $instagram;
public $website;
public $languages = [];
public $language_names;
public $language_levels;
public $languageToDelete = [];
public $certificates = [];
public $certificate_name;
public $certificate_school;
public $certificate_link;
public $certificate_date;
public $certificateToDelete = [];
public $skillsQuery;
public $skillResults;
public $skills;
public function render()
{
$this->retriveStates();
$this->retriveCities();
$this->retriveLanguages();
return view('livewire.user-info');
}
public function retriveStates()
{
$this->states = CityName::distinct()->get(['state']);
}
public function retriveCities()
{
$this->cities = CityName::where('state', $this->selectedstate)->get(['city']);
}
public function updatedSkillsQuery()
{
$this->skillResults = $this->skills->where('name', 'like', $this->skillsQuery) ?? collect();
}
public function retriveLanguages()
{
$this->language_names = Language::all();
$this->language_levels = LanguageLevel::all();
}
public function addLanguage()
{
if (count($this->languages) <= 3)
{
array_push($this->languages, ['language_name'=>'', 'language_level'=>'', 'id'=>'']);
}
else
{
$this->sweetAlert('error', 'you only can add 3 languages to your profile.');
}
}
public function getUserLanguages()
{
$this->languages = auth()->user()->userLanguages->toArray();
}
public function removeLanguage($languagePosition, $languageId)
{
if (isset($languageId))
{
if ($languageId == 0)
{
array_splice($this->languages, $languagePosition, 1);
}
else
{
array_push($this->languageToDelete, $languageId);
array_splice($this->languages, $languagePosition, 1);
}
}
}
public function addCertificate()
{
if (count($this->certificates) <= 5)
{
array_push($this->certificates, ['name'=>'', 'school'=>'', 'link'=>'', 'date'=>'', 'id'=>'']);
/* dd($this->languages); */
}
else
{
$this->sweetAlert('error', 'you only can add 5 certificates to your profile.');
}
}
public function mount()
{
$this->skills = collect([
['name' => 'vue'],
['name' => 'vue'],
['name' => 'vue'],
['name' => 'laravel'],
['name' => 'laravel'],
['name' => 'laravel'],
]);
$this->skillResults= [];
$this->skillsQuery = '';
/* $this->retriveLanguages();
$this->retriveStates();
$this->retriveCities(); */
$this->getUserLanguages();
$this->name = auth()->user()->name;
$this->email = auth()->user()->email;
$this->phone = auth()->user()->phone;
$this->selectedstate = auth()->user()->userprofile->state;
$this->selectedcity = auth()->user()->userprofile->city;
$this->jobTitle = auth()->user()->userprofile->job_title;
$this->aboutMe = auth()->user()->userprofile->about_me;
$this->employer = auth()->user()->userprofile->employer;
$this->position = auth()->user()->userprofile->position;
$this->edu_course = auth()->user()->userprofile->edu_course;
$this->edu_school = auth()->user()->userprofile->edu_school;
$this->edu_level = auth()->user()->userprofile->edu_level;
$this->edu_start_date = auth()->user()->userprofile->edu_start_date;
$this->edu_end_date = auth()->user()->userprofile->edu_end_date;
$this->employment_looking = auth()->user()->userprofile->employment_looking;
$this->employment_hired = auth()->user()->userprofile->employment_hired;
$this->twitter = auth()->user()->userprofile->twitter;
$this->linkedin = auth()->user()->userprofile->linkedin;
$this->github = auth()->user()->userprofile->github;
$this->instagram = auth()->user()->userprofile->instagram;
$this->website = auth()->user()->userprofile->website;
}
public function rules()
{
return [
'name' => ['required', 'string', 'max:250'],
'email' => [
'required',
'email',
'max:250',
Rule::unique('users')->ignore(auth()->id()),
],
'phone' => ['required', 'digits:11'],
'selectedstate' => 'required',
'selectedcity' => 'required',
'jobTitle' => ['required', 'string', 'max:250'],
'aboutMe' => ['required', 'string', 'max:250'],
'employer' => ['string', 'max:250'],
'position' => ['string', 'max:250'],
'edu_course' => ['nullable', 'string', 'max:250'],
'edu_school' => ['nullable', 'string', 'max:250'],
'edu_level' => ['nullable', 'string', 'max:250'],
'edu_start_date' => ['nullable', 'string'],
'edu_end_date' => ['nullable', 'string'],
'employment_looking' => ['nullable', 'boolean'],
'employment_hired' => ['nullable', 'boolean'],
'twitter' => ['nullable', 'string', 'max:250'],
'linkedin' => ['nullable', 'string', 'max:250'],
'github' => ['nullable', 'string', 'max:250'],
'instagram' => ['nullable', 'string', 'max:250'],
'website' => ['nullable', 'string', 'max:250'],
'languages.*.language_name' => ['required', 'exists:App\Models\Language,abbreviation'],
'languages.*.language_level' => ['required', 'exists:App\Models\LanguageLevel,level'],
];
}
public function submit()
{
$user = Auth::user();
$this->validate();
User::where('id', auth()->id())->update([
'name' => $this->name,
'email' => $this->email,
'phone' => $this->phone,
]);
UserProfile::where('user_id', auth()->id())->update([
'state' => $this->selectedstate,
'city' => $this->selectedcity,
'job_title' => $this->jobTitle,
'about_me' => $this->aboutMe,
'employer' => $this->employer,
'position' => $this->position,
'edu_course' => $this->edu_course,
'edu_school' => $this->edu_school,
'edu_level' => $this->edu_level,
'edu_start_date' => $this->edu_start_date,
'edu_end_date' => $this->edu_end_date,
'employment_looking' => $this->employment_looking,
'employment_hired' => $this->employment_hired,
'twitter' => $this->twitter,
'linkedin' => $this->linkedin,
'github' => $this->github,
'instagram' => $this->instagram,
'website' => $this->website,
]);
if (!empty($this->languageToDelete))
{
/* $user = Auth::user(); */
foreach ($this->languageToDelete as $delete)
{
$user->userLanguages()->where('id', $delete)->delete();
}
}
foreach ($this->languages as $language)
{
/* $user = Auth::user(); */
$user->userLanguages()->updateOrCreate([
'language_name' => $language['language_name'],
],
[
'language_name' => $language['language_name'],
'language_level' => $language['language_level']
]
);
}
$this->getUserLanguages();
$this->sweetAlert('success', 'changes saved!');
}
public function sweetAlert($type, $message)
{
$this->alert($type, $message, [
'position' => 'bottom-end',
'timer' => 5000,
'toast' => true,
'text' => null,
'showCancelButton' => false,
'showConfirmButton' => false
]);
}
}
问题已解决。问题确实是由多个循环索引引起的 DOM 问题。正如我最初所想的那样,$loop->index
导致了它,我在正确的轨道上将其更改为 $languages as $lindex => $language
之类的其他东西,但显然即使这样做,这两个部分仍然具有相同的 wire:key
因为循环迭代 returns 0,1,2
依此类推。因此,通过将字符串附加到 lang{{ $loop->index }}
之类的键,它们将是唯一的,因此问题得到解决。
我有一个用 livewire 制作的视图,它包含两个动态添加的口语部分和另一个课程和证书部分。在我添加添加证书部分之前,语言部分工作正常。现在,当用户单击证书部分的添加部分以添加新的部分时,添加的语言部分之一会消失,然后在您添加另一个语言部分后会再次出现。我猜它会在视图重新呈现后再次出现。我一直在返回并强制将函数从 render
方法移动到 update/updated/hydrate/dehydrate
但没有运气。起初,我认为它与我在我的视图中使用的 $loop->index
有关,但在更改之后我意识到它不是。我在这里遇到了死胡同,无法弄清楚这里发生了什么。
我还对正在发生的事情进行了屏幕记录,这样可能会有所帮助: https://drive.google.com/file/d/1Hq2wTKcPvhs05SKFMICaRoOAzpSyj9Iz/view?usp=sharing
查看部分:
<!-- language section -->
<div class="card card-profile shadow-sm mt-4">
<div class="px-4 mt-4 mb-4">
<div class="h5 font-weight-bold mb-4">Spoken languages</div>
<div class="heading text-muted mb-4">you only can add 3 languages to your profile.</div>
@foreach ($languages as $lindex => $language)
<div class="card card-body mb-4" wire:key="{{ $lindex }}">
<div class="text-left"><span class="fa fa-trash text-gray language-delete" wire:click="removeLanguage({{ $lindex }}, {{ !empty($language['id']) ? $language['id'] : 0 }})"></span></div>
<div class="row">
<div class="form-group col-md-6">
<label class="" for="languageName">language</label>
<select class="form-control form-control-alternative" name="language-name" {{-- id="languageName" --}} wire:model="languages.{{ $lindex }}.language_name">
<option value="" class="form-control" selected disabled>select language</option>
@foreach ($language_names as $name)
<option value="{{ $name->abbreviation }}" class="form-control">{{ $name->language }}</option>
@endforeach
</select>
</div>
<div class="form-group col-md-6">
<label class="" for="languageProficiency">proficiency level</label>
<select class="form-control form-control-alternative" name="language-proficiency" {{-- id="languageProficiency" --}} wire:model="languages.{{ $lindex }}.language_level">
<option value="" class="form-control" selected disabled>proficiency level</option>
@foreach ($language_levels as $level)
<option value="{{ $level->level }}" class="form-control">{{ $level->name }}</option>
@endforeach
</select>
</div>
</div>
</div>
@endforeach
@error('languages.*.language_level')
<small class="text-warning">{{ $message }}</small>
@enderror
@error('languages.*.language_language')
<small class="text-warning">{{ $message }}</small>
@enderror
@if (count($languages) < 3)
<div class="row">
<div class="col-md-12">
<button type="button" class="btn btn-outline-secondary btn-round btn-block" wire:click="addLanguage"><span class="btn-inner--icon"><i class="fa fa-plus fa-2x"></i></span></button>
</div>
</div>
@endif
</div>
</div>
<!-- end language section -->
<!-- other certificates section -->
<div class="card card-profile shadow-sm mt-4">
<div class="px-4 mt-4 mb-4">
<div class="h5 font-weight-bold mb-4">Other related certificates</div>
<div class="heading text-muted mb-4">if you have other related certificates in your files you can add then here.</div>
@foreach ($certificates as $cindex => $certificate)
<div class="card card-body mb-4" wire:key="{{ $cindex }}">
<div class="row">
<div class="form-group col-md-6">
<label class="" for="other-certificates-name">certificate name</label>
<input type="text" class="form-control form-control-alternative" placeholder="" name="ptherCertificatesName">
</div>
<div class="form-group col-md-6">
<label class="" for="other-certificates-school-name">School name</label>
<input type="text" class="form-control form-control-alternative" placeholder="" name="otherCertificatesSchoolName">
</div>
<div class="form-group col-md-6">
<label class="" for="other-certificates-verification-link">URL<small>(optional)</small></label>
<input type="text" class="form-control form-control-alternative text-left" placeholder="" name="otherCertificatesVerificationLink">
</div>
<div class="form-group col" dir="ltr">
<label class="" for="other-certificates-grad-date" dir="rtl">finished date</label>
<div class="input-group input-group-alternative">
<div class="input-group-prepend">
<span class="input-group-text"><i class="ni ni-calendar-grid-58"></i></span>
</div>
<input type="text" class="form-control form-control-alternative datePicker" placeholder="" name="otherCertificatesGradDate" value="">
</div>
</div>
</div>
</div>
@endforeach
@if (count($certificates) < 5)
<div class="row">
<div class="col-md-12">
<button type="button" class="btn btn-outline-secondary btn-round btn-block" wire:click="addCertificate"><span class="btn-inner--icon"><i class="fa fa-plus fa-2x"></i></span></button>
</div>
</div>
@endif
</div>
</div>
<!-- end other certificates section -->
Livewire 组件控制器:
<?php
namespace App\Http\Livewire;
use Livewire\Component;
use App\Models\CityName;
use App\Models\Language;
use App\Models\LanguageLevel;
use App\Models\User;
use App\Models\UserLanguage;
use App\Models\UserProfile;
use Illuminate\Validation\Rule;
use Illuminate\Support\Facades\Auth;
class UserInfo extends Component
{
public $name;
public $email;
public $phone;
public $states = [];
public $selectedstate;
public $cities = [];
public $selectedcity;
public $jobTitle;
public $aboutMe;
public $employer;
public $position;
public $edu_course;
public $edu_school;
public $edu_level;
public $edu_start_date;
public $edu_end_date;
public $employment_looking;
public $employment_hired;
public $twitter;
public $linkedin;
public $github;
public $instagram;
public $website;
public $languages = [];
public $language_names;
public $language_levels;
public $languageToDelete = [];
public $certificates = [];
public $certificate_name;
public $certificate_school;
public $certificate_link;
public $certificate_date;
public $certificateToDelete = [];
public $skillsQuery;
public $skillResults;
public $skills;
public function render()
{
$this->retriveStates();
$this->retriveCities();
$this->retriveLanguages();
return view('livewire.user-info');
}
public function retriveStates()
{
$this->states = CityName::distinct()->get(['state']);
}
public function retriveCities()
{
$this->cities = CityName::where('state', $this->selectedstate)->get(['city']);
}
public function updatedSkillsQuery()
{
$this->skillResults = $this->skills->where('name', 'like', $this->skillsQuery) ?? collect();
}
public function retriveLanguages()
{
$this->language_names = Language::all();
$this->language_levels = LanguageLevel::all();
}
public function addLanguage()
{
if (count($this->languages) <= 3)
{
array_push($this->languages, ['language_name'=>'', 'language_level'=>'', 'id'=>'']);
}
else
{
$this->sweetAlert('error', 'you only can add 3 languages to your profile.');
}
}
public function getUserLanguages()
{
$this->languages = auth()->user()->userLanguages->toArray();
}
public function removeLanguage($languagePosition, $languageId)
{
if (isset($languageId))
{
if ($languageId == 0)
{
array_splice($this->languages, $languagePosition, 1);
}
else
{
array_push($this->languageToDelete, $languageId);
array_splice($this->languages, $languagePosition, 1);
}
}
}
public function addCertificate()
{
if (count($this->certificates) <= 5)
{
array_push($this->certificates, ['name'=>'', 'school'=>'', 'link'=>'', 'date'=>'', 'id'=>'']);
/* dd($this->languages); */
}
else
{
$this->sweetAlert('error', 'you only can add 5 certificates to your profile.');
}
}
public function mount()
{
$this->skills = collect([
['name' => 'vue'],
['name' => 'vue'],
['name' => 'vue'],
['name' => 'laravel'],
['name' => 'laravel'],
['name' => 'laravel'],
]);
$this->skillResults= [];
$this->skillsQuery = '';
/* $this->retriveLanguages();
$this->retriveStates();
$this->retriveCities(); */
$this->getUserLanguages();
$this->name = auth()->user()->name;
$this->email = auth()->user()->email;
$this->phone = auth()->user()->phone;
$this->selectedstate = auth()->user()->userprofile->state;
$this->selectedcity = auth()->user()->userprofile->city;
$this->jobTitle = auth()->user()->userprofile->job_title;
$this->aboutMe = auth()->user()->userprofile->about_me;
$this->employer = auth()->user()->userprofile->employer;
$this->position = auth()->user()->userprofile->position;
$this->edu_course = auth()->user()->userprofile->edu_course;
$this->edu_school = auth()->user()->userprofile->edu_school;
$this->edu_level = auth()->user()->userprofile->edu_level;
$this->edu_start_date = auth()->user()->userprofile->edu_start_date;
$this->edu_end_date = auth()->user()->userprofile->edu_end_date;
$this->employment_looking = auth()->user()->userprofile->employment_looking;
$this->employment_hired = auth()->user()->userprofile->employment_hired;
$this->twitter = auth()->user()->userprofile->twitter;
$this->linkedin = auth()->user()->userprofile->linkedin;
$this->github = auth()->user()->userprofile->github;
$this->instagram = auth()->user()->userprofile->instagram;
$this->website = auth()->user()->userprofile->website;
}
public function rules()
{
return [
'name' => ['required', 'string', 'max:250'],
'email' => [
'required',
'email',
'max:250',
Rule::unique('users')->ignore(auth()->id()),
],
'phone' => ['required', 'digits:11'],
'selectedstate' => 'required',
'selectedcity' => 'required',
'jobTitle' => ['required', 'string', 'max:250'],
'aboutMe' => ['required', 'string', 'max:250'],
'employer' => ['string', 'max:250'],
'position' => ['string', 'max:250'],
'edu_course' => ['nullable', 'string', 'max:250'],
'edu_school' => ['nullable', 'string', 'max:250'],
'edu_level' => ['nullable', 'string', 'max:250'],
'edu_start_date' => ['nullable', 'string'],
'edu_end_date' => ['nullable', 'string'],
'employment_looking' => ['nullable', 'boolean'],
'employment_hired' => ['nullable', 'boolean'],
'twitter' => ['nullable', 'string', 'max:250'],
'linkedin' => ['nullable', 'string', 'max:250'],
'github' => ['nullable', 'string', 'max:250'],
'instagram' => ['nullable', 'string', 'max:250'],
'website' => ['nullable', 'string', 'max:250'],
'languages.*.language_name' => ['required', 'exists:App\Models\Language,abbreviation'],
'languages.*.language_level' => ['required', 'exists:App\Models\LanguageLevel,level'],
];
}
public function submit()
{
$user = Auth::user();
$this->validate();
User::where('id', auth()->id())->update([
'name' => $this->name,
'email' => $this->email,
'phone' => $this->phone,
]);
UserProfile::where('user_id', auth()->id())->update([
'state' => $this->selectedstate,
'city' => $this->selectedcity,
'job_title' => $this->jobTitle,
'about_me' => $this->aboutMe,
'employer' => $this->employer,
'position' => $this->position,
'edu_course' => $this->edu_course,
'edu_school' => $this->edu_school,
'edu_level' => $this->edu_level,
'edu_start_date' => $this->edu_start_date,
'edu_end_date' => $this->edu_end_date,
'employment_looking' => $this->employment_looking,
'employment_hired' => $this->employment_hired,
'twitter' => $this->twitter,
'linkedin' => $this->linkedin,
'github' => $this->github,
'instagram' => $this->instagram,
'website' => $this->website,
]);
if (!empty($this->languageToDelete))
{
/* $user = Auth::user(); */
foreach ($this->languageToDelete as $delete)
{
$user->userLanguages()->where('id', $delete)->delete();
}
}
foreach ($this->languages as $language)
{
/* $user = Auth::user(); */
$user->userLanguages()->updateOrCreate([
'language_name' => $language['language_name'],
],
[
'language_name' => $language['language_name'],
'language_level' => $language['language_level']
]
);
}
$this->getUserLanguages();
$this->sweetAlert('success', 'changes saved!');
}
public function sweetAlert($type, $message)
{
$this->alert($type, $message, [
'position' => 'bottom-end',
'timer' => 5000,
'toast' => true,
'text' => null,
'showCancelButton' => false,
'showConfirmButton' => false
]);
}
}
问题已解决。问题确实是由多个循环索引引起的 DOM 问题。正如我最初所想的那样,$loop->index
导致了它,我在正确的轨道上将其更改为 $languages as $lindex => $language
之类的其他东西,但显然即使这样做,这两个部分仍然具有相同的 wire:key
因为循环迭代 returns 0,1,2
依此类推。因此,通过将字符串附加到 lang{{ $loop->index }}
之类的键,它们将是唯一的,因此问题得到解决。