我正在使用 Vue 3 開發用戶CRUD 應用程式。我想以相反的順序顯示用戶(最新添加的應該在頂部),為此,我使用自定義過濾器 bolow:
reverse(array) {
return array.slice().reverse();
}
我得到一個Property "reverse" was accessed during render but is not defined on instance錯誤,而不是想要的結果。
const usersApp = {
data() {
return {
users: [{
id: 1,
first_name: "John",
last_name: "Doe",
email: "[email protected]"
},
{
id: 2,
first_name: "Jane",
last_name: "Doe",
email: "[email protected]"
}
],
formData: {
first_name: "",
last_name: "",
email: ""
},
formErrors: [],
userAdded: false
};
},
methods: {
isNotEmpty() {
return (
this.formData.first_name &&
this.formData.last_name &&
this.formData.email
);
},
isEmail(email) {
return String(email)
.toLowerCase()
.match(
/^(([^<>()[\]\\.,;:\s@"] (\.[^<>()[\]\\.,;:\s@"] )*)|(". "))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9] \.) [a-zA-Z]{2,}))$/
);
},
formValidation() {
this.formErrors = [];
if (!this.isNotEmpty()) {
this.formErrors.push("There are empty filelds");
}
if (this.isNotEmpty() && !this.isEmail(this.formData.email)) {
this.formErrors.push("The email is invalid");
}
},
resetAddFormData() {
this.formData.first_name = "";
this.formData.last_name = "";
this.formData.email = "";
this.userAdded = false;
},
addUser() {
// Validate form data
this.formValidation();
// Make New User
let newUser = {
first_name: this.formData.first_name,
last_name: this.formData.last_name,
email: this.formData.email
};
// Add new user
if (!this.formErrors.length) {
this.users.push(newUser);
this.userAdded = true;
window.setTimeout(this.resetAddFormData, 1000);
}
}
},
watch: {
users() {
this.users();
}
},
filters: {
reverse(array) {
return array.slice().reverse();
}
}
};
Vue.createApp(usersApp).mount("#app");
.logo {
width: 30px;
}
.nav-item {
width: 100%;
}
@media (min-width: 768px) {
.nav-item {
width: auto;
}
}
.user-row {
transition: all 1s ease;
opacity: 1;
height: auto;
}
.user-row-active {
opacity: 0;
height: 0;
}
.alert {
padding: 0.6rem 0.75rem;
text-align: center;
font-weight: 600;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
<script src="https://unpkg.com/vue@next"></script>
<div id="app">
<nav class="navbar navbar-expand-sm bg-dark navbar-dark">
<!-- Brand -->
<a class="navbar-brand p-0" href="#">
<img src="https://www.pngrepo.com/png/303293/180/bootstrap-4-logo.png" alt="" class="logo">
</a>
<!-- Links -->
<div class="navbar-nav w-100">
<ul class="navbar-nav ml-auto" id="navbarSupportedContent">
<li class="nav-item">
<button type="button" class="btn btn-sm btn-success" data-toggle="modal" data-target="#exampleModalCenter">
Add user
</button>
</li>
</ul>
</div>
</nav>
<div class="container">
<div class="card my-2">
<h5 class="card-header px-2">Users</h5>
<div class="card-body p-0">
<table class="table table-striped m-0">
<thead>
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Email</th>
</tr>
</thead>
<tbody name="users-table" is="transition-group">
<tr v-for="user in users | reverse" :key="user.id" class="user-row">
<td>{{user.first_name}}</td>
<td>{{user.last_name}}</td>
<td>{{user.email}}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="modal fade" id="exampleModalCenter" tabindex="-1" role="dialog" aria-labelledby="exampleModalCenterTitle" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h3 class="modal-title h6" id="exampleModalLongTitle">New User</h3>
<button type="button" class="close" data-dismiss="modal" aria-label="Close" @click="resetAddFormData">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div v-if="this.formErrors.length">
<div v-for="error in formErrors" class="alert alert-danger">
{{error}}
</div>
</div>
<div v-if="userAdded" class="alert alert-success">User added successfully!</div>
<form @submit.prevent="addUser" novalidate>
<div class="form-group mb-2">
<input type="text" class="form-control input-sm" placeholder="First name" v-model="formData.first_name">
</div>
<div class="form-group mb-2">
<input type="text" class="form-control input-sm" placeholder="Last name" v-model="formData.last_name">
</div>
<div class="form-group mb-2">
<input type="email" class="form-control input-sm" placeholder="Email address" v-model="formData.email">
</div>
<div class=" mt-2">
<button type="submit" class="btn btn-sm btn-block btn-success">Submit</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
問題:
- 我究竟做錯了什么?
- 為此目的使用過濾器有更好的替代方法嗎?
uj5u.com熱心網友回復:
好吧,正如檔案所說,過濾器可用于常見的文本格式,因此您不能在陣列元素上使用它,因此獲取反向陣列的替代解決方案是使用計算屬性。
所以你可以像這樣創建一個計算屬性:
reversedUsers() {
return this.users.slice().reverse();
}
然后得到如下結果:
顯示代碼片段
const usersApp = {
data() {
return {
users: [{
id: 1,
first_name: "John",
last_name: "Doe",
email: "[email protected]"
},
{
id: 2,
first_name: "Jane",
last_name: "Doe",
email: "[email protected]"
}
],
formData: {
first_name: "",
last_name: "",
email: ""
},
formErrors: [],
userAdded: false
};
},
methods: {
isNotEmpty() {
return (
this.formData.first_name &&
this.formData.last_name &&
this.formData.email
);
},
isEmail(email) {
return String(email)
.toLowerCase()
.match(
/^(([^<>()[\]\\.,;:\s@"] (\.[^<>()[\]\\.,;:\s@"] )*)|(". "))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9] \.) [a-zA-Z]{2,}))$/
);
},
formValidation() {
this.formErrors = [];
if (!this.isNotEmpty()) {
this.formErrors.push("There are empty filelds");
}
if (this.isNotEmpty() && !this.isEmail(this.formData.email)) {
this.formErrors.push("The email is invalid");
}
},
resetAddFormData() {
this.formData.first_name = "";
this.formData.last_name = "";
this.formData.email = "";
this.userAdded = false;
},
addUser() {
// Validate form data
this.formValidation();
// Make New User
let newUser = {
first_name: this.formData.first_name,
last_name: this.formData.last_name,
email: this.formData.email
};
// Add new user
if (!this.formErrors.length) {
this.users.push(newUser);
this.userAdded = true;
window.setTimeout(this.resetAddFormData, 1000);
}
}
},
watch: {
users() {
this.users();
}
},
computed: {
reversedUsers() {
return this.users.slice().reverse();
}
}
};
Vue.createApp(usersApp).mount("#app");
.logo {
width: 30px;
}
.nav-item {
width: 100%;
}
@media (min-width: 768px) {
.nav-item {
width: auto;
}
}
.user-row {
transition: all 1s ease;
opacity: 1;
height: auto;
}
.user-row-active {
opacity: 0;
height: 0;
}
.alert {
padding: 0.6rem 0.75rem;
text-align: center;
font-weight: 600;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
<script src="https://unpkg.com/vue@next"></script>
<div id="app">
<nav class="navbar navbar-expand-sm bg-dark navbar-dark">
<!-- Brand -->
<a class="navbar-brand p-0" href="#">
<img src="https://www.pngrepo.com/png/303293/180/bootstrap-4-logo.png" alt="" class="logo">
</a>
<!-- Links -->
<div class="navbar-nav w-100">
<ul class="navbar-nav ml-auto" id="navbarSupportedContent">
<li class="nav-item">
<button type="button" class="btn btn-sm btn-success" data-toggle="modal" data-target="#exampleModalCenter">
Add user
</button>
</li>
</ul>
</div>
</nav>
<div class="container">
<div class="card my-2">
<h5 class="card-header px-2">Users</h5>
<div class="card-body p-0">
<table class="table table-striped m-0">
<thead>
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Email</th>
</tr>
</thead>
<tbody name="users-table" is="transition-group">
<tr v-for="user in reversedUsers" :key="user.id" class="user-row">
<td>{{user.first_name}}</td>
<td>{{user.last_name}}</td>
<td>{{user.email}}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="modal fade" id="exampleModalCenter" tabindex="-1" role="dialog" aria-labelledby="exampleModalCenterTitle" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h3 class="modal-title h6" id="exampleModalLongTitle">New User</h3>
<button type="button" class="close" data-dismiss="modal" aria-label="Close" @click="resetAddFormData">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div v-if="this.formErrors.length">
<div v-for="error in formErrors" class="alert alert-danger">
{{error}}
</div>
</div>
<div v-if="userAdded" class="alert alert-success">User added successfully!</div>
<form @submit.prevent="addUser" novalidate>
<div class="form-group mb-2">
<input type="text" class="form-control input-sm" placeholder="First name" v-model="formData.first_name">
</div>
<div class="form-group mb-2">
<input type="text" class="form-control input-sm" placeholder="Last name" v-model="formData.last_name">
</div>
<div class="form-group mb-2">
<input type="email" class="form-control input-sm" placeholder="Email address" v-model="formData.email">
</div>
<div class=" mt-2">
<button type="submit" class="btn btn-sm btn-block btn-success">Submit</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
uj5u.com熱心網友回復:
的遷移指南建議使用計算機屬性:
在 3.x 中,過濾器被移除,不再受支持。相反,我們建議用方法呼叫或計算屬性替換它們。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/368812.html
上一篇:Nuxt3中與Nuxt2中的“匿名中間件”最接近的等價物是什么?
下一篇:Vue:渲染串列顯示選定的復選框
