Book List Case
1. Book List
- static list effect
- Template effect based on data
- Handle action buttons for each row (disables default behavior)
1. Static data provided
- The data is stored in the data attribute in vue
var vm = new Vue({
el: '#app',
data: {
books: [{
id: 1,
name: 'Three Kingdoms',
date: ''
},{
id: 2,
name: 'Water Margin',
date: ''
},{
id: 3,
name: 'A Dream of Red Mansions',
date: ''
},{
id: 4,
name: 'Journey to the West',
date: ''
}]
}
});
copy
2. Render the provided data to the page
- Use v-for loop to traverse books to render each item of data into the corresponding data
<tbody>
<tr :key='item.id' v-for='item in books'>
<!-- corresponding id render on the page -->
<td>{{item.id}}</td>
<!-- corresponding name render on the page -->
<td>{{item.name}}</td>
<td>{{item.date}}</td>
<td>
<!-- Prevent a Default jump for labels -->
<a href="" @click.prevent>Revise</a>
<span>|</span>
<a href="" @click.prevent>delete</a>
</td>
</tr>
</tbody>
copy
2. Add books
- Implement the static effect of the form
- Add book form field data binding
- Add button event binding
- Implement adding business logic
<div>
<h1>library management</h1>
<div class="book">
<div>
<label for="id">
Numbering:
</label>
<!-- 3.1,Get the input in the input box through two-way binding id -->
<input type="text" id="id" v-model='id'>
<label for="name">
name:
</label>
<!-- 3.2,Get the input in the input box through two-way binding name -->
<input type="text" id="name" v-model='name'>
<!-- 3.3,Add click event to button -->
<button @click='handle'>submit</button>
</div>
</div>
</div>
<script type="text/javascript">
/*
Book Management - Add Books
*/
methods: {
handle: function(){
// 3.4 Define a new object book to store and get the id and name of the book in the input box
var book = {};
book.id = this.id;
book.name = this.name;
book.date = '';
// 3.5 Put the book into books through the array mutation method push
this.books.push(book);
//3.6 Clear the input box
this.id = '';
this.name = '';
}
}
</script>
copy
3. Modify the book - on
- When the edit button is clicked, the list of books to be modified is obtained
- 4.1 To add a click event to the modification button, you need to pass the id of the current book so that you know which book you need to modify
- Fill in the list of books to be modified into the form
- 4.2 Find out the detailed information of the corresponding book in books according to the passed id
- 4.3 Fill the form with the obtained information
<!---
4.1 To add a click event to the modify button, you need to change the current book's id pass the past
That way you know which book you need to revise
--->
<a href="" @click.prevent='toEdit(item.id)'>Revise</a>
<script type="text/javascript">
/*
Book Management - Add Books
*/
toEdit: function(id){
console.log(id)
//4.2 Find out the detailed information of the corresponding book in books according to the passed id
var book = this.books.filter(function(item){
return item.id == id;
});
console.log(book)
//4.3 Fill the form with the obtained information
// this.id and this.name are bound to the form through two-way binding and the view is automatically updated once the data changes
this.id = book[0].id;
this.name = book[0].name;
}
</script>
copy
4. Modify the book - next
- 5.1 Define an identifier, mainly to control the id of the currently edited book in the editing state cannot be modified, that is, in the editing state, the input box currently controlling the number of the book is disabled
- 5.2 Binding the disabled attribute flag to the book number through the attribute is true, it is disabled
- 5.3 The default value of flag is false and it is in editing state. To change the flag to true, the current form is disabled.
- 5.4 Reuse adding method When the user clicks submit, the logic in the handle is still executed. If the flag is true, the form is in an uninputable state. At this time, the user edits the data.
<!-- 5.2 Binding via property binding disabled properties of flag for true is disabled -->
<input type="text" id="id" v-model='id' :disabled="flag">
<script type="text/javascript">
/*Book Management - Add Books*/
var vm = new Vue({
el: '#app',
data: {
// 5.1 Define an identifier, mainly to control the id of the currently edited book in the editing state cannot be modified
// That is, in the editing state, the input box that currently controls the book number is disabled
flag: false,
id: '',
name: '',
},
methods: {
handle: function() {
/*
5.4 Reuse add method When the user clicks submit, the logic in the handle is still executed
If the flag is true, that is, the form is in a non-input state, and the user edits the data data executed at this time.
*/
if (this.flag) {
// edit book
// 5.5 Update the corresponding data in the array according to the current ID
this.books.some((item) => {
if (item.id == this.id) {
// This in the arrow function points to the this of the parent scope
item.name = this.name;
// After completing the update operation, the loop needs to be terminated
return true;
}
});
// 5.6 After editing the data, the form should be in a state that can be entered
this.flag = false;
// 5.7 If the flag is false and the form is in the input state, the user added data executed at this time
} else {
var book = {};
book.id = this.id;
book.name = this.name;
book.date = '';
this.books.push(book);
// clear form
this.id = '';
this.name = '';
}
// clear form
this.id = '';
this.name = '';
},
toEdit: function(id) {
/*
5.3 flag The default value is false. It is in the editing state. To change the flag to true, the current form is disabled.
*/
this.flag = true;
console.log(id)
var book = this.books.filter(function(item) {
return item.id == id;
});
console.log(book)
this.id = book[0].id;
this.name = book[0].name;
}
}
});
</script>
copy
5. Delete Books
- 6.1 Add an event to the delete button and pass the id of the book that needs to be deleted currently
- 6.2 Find the index of an element from an array based on its id
- 6.3 Deleting array elements by index
<tbody>
<tr :key='item.id' v-for='item in books'>
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<td>{{item.date}}</td>
<td>
<a href="" @click.prevent='toEdit(item.id)'>Revise</a>
<span>|</span>
<!-- 6.1 Add an event to the delete button to delete the current book id pass over -->
<a href="" @click.prevent='deleteBook(item.id)'>delete</a>
</td>
</tr>
</tbody>
<script type="text/javascript">
/*
Book Management - Add Books
*/
var vm = new Vue({
methods: {
deleteBook: function(id){
// delete book
// 6.2 Find the index of an element from an array based on its id
// var index = this.books.findIndex(function(item){
// return item.id == id;
// });
// 6.3 Deleting array elements by index
// this.books.splice(index, 1);
// -------------------------
// Method 2: delete through the filter method
//6.4 Filter out the id according to the filter method, not the id of the book to be deleted
//Because filter is a replacement array and will not modify the original data, it is necessary to assign the id of the book that is not to be deleted to books
this.books = this.books.filter(function(item){
return item.id != id;
});
}
}
});
</script>
copy
6. Common feature application scenarios
1 filter (formatted date)
- Vue.filter defines a global filter
<tr :key='item.id' v-for='item in books'>
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<!-- 1.3 call filter -->
<td>{{item.date | format('yyyy-MM-dd hh:mm:ss')}}</td>
<td>
<a href="" @click.prevent='toEdit(item.id)'>Revise</a>
<span>|</span>
<a href="" @click.prevent='deleteBook(item.id)'>delete</a>
</td>
</tr>
<script>
//1.1 Vue.filter defines a global filter
Vue.filter('format', function(value, arg) {
function dateFormat(date, format) {
if (typeof date === "string") {
var mts = date.match(/(\/Date\((\d+)\)\/)/);
if (mts && mts.length >= 3) {
date = parseInt(mts[2]);
}
}
date = new Date(date);
if (!date || date.toUTCString() == "Invalid Date") {
return "";
}
var map = {
"M": date.getMonth() + 1, //month
"d": date.getDate(), //day
"h": date.getHours(), //Hour
"m": date.getMinutes(), //Minute
"s": date.getSeconds(), //Second
"q": Math.floor((date.getMonth() + 3) / 3), //quarter
"S": date.getMilliseconds() //millisecond
};
format = format.replace(/([yMdhmsqS])+/g, function(all, t) {
var v = map[t];
if (v !== undefined) {
if (all.length > 1) {
v = '0' + v;
v = v.substr(v.length - 2);
}
return v;
} else if (t === 'y') {
return (date.getFullYear() + '').substr(4 - all.length);
}
return all;
});
return format;
}
return dateFormat(value, arg);
})
//1.2 The provided data contains a timestamp in milliseconds
[{
id: 1,
name: 'Three Kingdoms',
date: 2525609975000
},{
id: 2,
name: 'Water Margin',
date: 2525609975000
},{
id: 3,
name: 'A Dream of Red Mansions',
date: 2525609975000
},{
id: 4,
name: 'Journey to the West',
date: 2525609975000
}];
</script>
copy
2 Custom instructions (get form focus)
- Make the form automatically get focus
- Customization via Vue.directive
<!-- 2.2 pass v-custom attribute name call custom command -->
<input type="text" id="id" v-model='id' :disabled="flag" v-focus>
<script>
//2.1 Customize through Vue.directive
Vue.directive('focus', {
inserted: function (el) {
el.focus();
}
});
</script>
copy
3 Calculated properties (counting the number of books)
- Calculate the total number of books by calculating a property
- The total number of books is to calculate the length of the array
<div class="total">
<span>Total Books:</span>
<!-- 3.2 display on the page -->
<span>{{total}}</span>
</div>
<script type="text/javascript">
/*
Difference between computed properties and methods: computed properties are cached based on dependencies, while methods are not cached
*/
var vm = new Vue({
data: {
flag: false,
submitFlag: false,
id: '',
name: '',
books: []
},
computed: {
total: function(){
// 3.1 Calculate the total number of books
return this.books.length;
}
},
});
</script>
copy
4 Listener (verifies book existence)
watch: {
name: function (val) {
var flag = this.books.some(function (item) {
return item.name == val;
});
if (flag) {
// Disable button if book title exists
this.submitFlag = true;
} else {
this.submitFlag = false;
}
}
},
copy
5 Life Cycle (Book Data Processing)
mounted: function () {
// When the lifecycle hook function is triggered, the template is already available
// Generally, it is used to obtain background data at this time, and then fill the data into the template
var data = [{
id: 1,
name: 'Three Kingdoms',
date: new Date()
}, {
id: 2,
name: 'Water Margin',
date: new Date()
}, {
id: 3,
name: 'A Dream of Red Mansions',
date: new Date()
}, {
id: 4,
name: 'Journey to the West',
date: 343534647586
}];
this.books = data;
}
copy
Posted by newbiehacker on Tue, 10 May 2022 05:41:44 +0300