Achieve results The code is as follows html <template> <div> <div class="biggestBox"> <ul> <!-- data-type=0 Hide the delete button data-type=1 Show the delete button --> <li class="li_vessel" v-for="(item,index) in lists " data-type="0" :key="index"> <!-- "touchstart" is triggered when the finger touches the screen "touchend" is triggered when the finger leaves the screen "capture" is used for event capture --> <div @touchstart.capture="touchStart" @touchend.capture="touchEnd" @click="oneself"> <div class="contant"> <img class="image" :src="item.imgUrl" alt /> <div class="rightBox"> <div>{{item.title}}</div> <div>{{item.subheading}}</div> <div>{{item.faddish}}</div> <div>{{item.price}}</div> </div> </div> </div> <div class="removeBtn" @click="remove" :data-index="index">Delete</div> </li> </ul> </div> </div> </template> js export default { name: "index", data() { return { lists: [ { title: "Title 1", imgUrl: "https://z3.ax1x.com/2021/05/18/gfwKHg.jpg", subheading: "Subheading 1", faddish: "hot item", price: "¥12.00", }, { title: "Title 2", imgUrl: "https://z3.ax1x.com/2021/05/18/gfwKHg.jpg", subheading: "Subheading 2", faddish: "hot item", price: "¥58.00", }, { title: "Title 3", imgUrl: "https://z3.ax1x.com/2021/05/18/gfwKHg.jpg", subheading: "Subheading 3", faddish: "hot item", price: "¥99.99", }, { title: "Title 4", imgUrl: "https://z3.ax1x.com/2021/05/18/gfwKHg.jpg", subheading: "Subheading 4", faddish: "hot item", price: "¥88.32", }, { title: "Title 5", imgUrl: "https://z3.ax1x.com/2021/05/18/gfwKHg.jpg", subheading: "Subheading 5", faddish: "hot item", price: "¥9999.99", }, ], startX: 0, //slide start endX: 0, //slide end}; }, methods: { // When the delete button appears when swiping left, click the product information area to cancel the deletion oneself() { if (this.checkSlide()) { this.restSlide(); } else { // Click on the product information to pop up the alert box ("hello Word!"); } }, //Slide start touchStart(e) { //Record the initial position this.startX = e.touches[0].clientX; }, //Slide end touchEnd(e) { // The parent element of the current slide let parentElement = e.currentTarget.parentElement; // Record end position this.endX = e.changedTouches[0].clientX; // Delete if the left slide distance is greater than 30 if (parentElement.dataset.type == 0 && this.startX - this.endX > 30) { this.restSlide(); parentElement.dataset.type = 1; } // Swipe right if (parentElement.dataset.type == 1 && this.startX - this.endX < -30) { this.restSlide(); parentElement.dataset.type = 0; } this.startX = 0; this.endX = 0; }, // Check if there is a slider in the sliding state checkSlide() { let listItems = document.querySelectorAll(".li_vessel"); for (let i = 0; i < listItems.length; i++) { if (listItems[i].dataset.type == 1) { return true; } } return false; }, //Reset sliding state restSlide() { let listItems = document.querySelectorAll(".li_vessel"); // Reset for (let i = 0; i < listItems.length; i++) { listItems[i].dataset.type = 0; } }, //Delete data information remove(e) { // Current index value let index = e.currentTarget.dataset.index; // Reset this.restSlide(); // Delete a data in the array lists this.lists.splice(index, 1); }, }, }; CSS <style> * { /* Remove default inner and outer margins*/ margin: 0; padding: 0; } body { background: rgb(246, 245, 250); } .biggestBox { overflow: hidden; /*The exceeding part is hidden*/ } ul { /* Eliminate ul default style */ list-style: none; padding: 0; margin: 0; } .li_vessel { /* 0.2 second easing for all styles*/ transition: all 0.2s; } /* =0 to hide */ .li_vessel[data-type="0"] { transform: translate3d(0, 0, 0); } /* =1 display */ .li_vessel[data-type="1"] { /* The larger the -64px setting, the farther you can swipe left. It is best to set the same value as the width and positioning distance of the delete button below*/ transform: translate3d(-64px, 0, 0); } /* Delete button */ .li_vessel .removeBtn { width: 64px; height: 103px; background: #ff4949; font-size: 16px; color: #fff; text-align: center; line-height: 22px; position: absolute; top: 0px; right: -64px; line-height: 103px; text-align: center; border-radius: 2px; } /* Left picture style*/ .contant { overflow: hidden; /*Eliminate the floating caused by the image*/ padding: 10px; background: #ffffff; } .contant .image { width: 80px; height: 80px; border-radius: 4px; float: left; } /* Text information style on the right*/ .rightBox { overflow: hidden; padding-left: 8px; } .rightBox div:first-child { font-weight: bold; } .rightBox div:nth-child(2) { margin-top: 4px; font-size: 14px; } .rightBox div:nth-child(3) { width: 24px; background: rgb(219, 91, 113); color: white; font-size: 12px; text-align: center; padding: 2px 4px 2px 4px; margin-left: auto; } .rightBox div:last-child { color: red; font-size: 14px; font-weight: bold; } </style> The complete code is as follows <template> <div> <div class="biggestBox"> <ul> <!-- data-type=0 Hide the delete button data-type=1 Show the delete button --> <li class="li_vessel" v-for="(item,index) in lists " data-type="0" :key="index"> <!-- "touchstart" is triggered when the finger touches the screen "touchend" is triggered when the finger leaves the screen "capture" is used for event capture --> <div @touchstart.capture="touchStart" @touchend.capture="touchEnd" @click="oneself"> <div class="contant"> <img class="image" :src="item.imgUrl" alt /> <div class="rightBox"> <div>{{item.title}}</div> <div>{{item.subheading}}</div> <div>{{item.faddish}}</div> <div>{{item.price}}</div> </div> </div> </div> <div class="removeBtn" @click="remove" :data-index="index">Delete</div> </li> </ul> </div> </div> </template> <script> export default { name: "index", data() { return { lists: [ { title: "Title 1", imgUrl: "https://z3.ax1x.com/2021/05/18/gfwKHg.jpg", subheading: "Subheading 1", faddish: "hot item", price: "¥12.00", }, { title: "Title 2", imgUrl: "https://z3.ax1x.com/2021/05/18/gfwKHg.jpg", subheading: "Subheading 2", faddish: "hot item", price: "¥58.00", }, { title: "Title 3", imgUrl: "https://z3.ax1x.com/2021/05/18/gfwKHg.jpg", subheading: "Subheading 3", faddish: "hot item", price: "¥99.99", }, { title: "Title 4", imgUrl: "https://z3.ax1x.com/2021/05/18/gfwKHg.jpg", subheading: "Subheading 4", faddish: "hot item", price: "¥88.32", }, { title: "Title 5", imgUrl: "https://z3.ax1x.com/2021/05/18/gfwKHg.jpg", subheading: "Subheading 5", faddish: "hot item", price: "¥9999.99", }, ], startX: 0, //slide start endX: 0, //slide end}; }, methods: { // When the delete button appears when swiping left, click the product information area to cancel the deletion oneself() { if (this.checkSlide()) { this.restSlide(); } else { // Click on the product information to pop up the alert box ("hello Word!"); } }, //Slide start touchStart(e) { //Record the initial position this.startX = e.touches[0].clientX; }, //Slide end touchEnd(e) { // The parent element of the current slide let parentElement = e.currentTarget.parentElement; // Record end position this.endX = e.changedTouches[0].clientX; // Delete if the left slide distance is greater than 30 if (parentElement.dataset.type == 0 && this.startX - this.endX > 30) { this.restSlide(); parentElement.dataset.type = 1; } // Swipe right if (parentElement.dataset.type == 1 && this.startX - this.endX < -30) { this.restSlide(); parentElement.dataset.type = 0; } this.startX = 0; this.endX = 0; }, // Check if there is a slider in the sliding state checkSlide() { let listItems = document.querySelectorAll(".li_vessel"); for (let i = 0; i < listItems.length; i++) { if (listItems[i].dataset.type == 1) { return true; } } return false; }, //Reset sliding state restSlide() { let listItems = document.querySelectorAll(".li_vessel"); // Reset for (let i = 0; i < listItems.length; i++) { listItems[i].dataset.type = 0; } }, //Delete data information remove(e) { // Current index value let index = e.currentTarget.dataset.index; // Reset this.restSlide(); // Delete a data in the array lists this.lists.splice(index, 1); }, }, }; </script> <style> * { /* Remove default inner and outer margins*/ margin: 0; padding: 0; } body { background: rgb(246, 245, 250); } .biggestBox { overflow: hidden; /*The exceeding part is hidden*/ } ul { /* Eliminate ul default style */ list-style: none; padding: 0; margin: 0; } .li_vessel { /* 0.2 second easing for all styles*/ transition: all 0.2s; } /* =0 to hide */ .li_vessel[data-type="0"] { transform: translate3d(0, 0, 0); } /* =1 display */ .li_vessel[data-type="1"] { /* The larger the -64px setting, the farther you can swipe left. It is best to set the same value as the width and positioning distance of the delete button below*/ transform: translate3d(-64px, 0, 0); } /* Delete button */ .li_vessel .removeBtn { width: 64px; height: 103px; background: #ff4949; font-size: 16px; color: #fff; text-align: center; line-height: 22px; position: absolute; top: 0px; right: -64px; line-height: 103px; text-align: center; border-radius: 2px; } /* Left picture style*/ .contant { overflow: hidden; /*Eliminate the floating caused by the image*/ padding: 10px; background: #ffffff; } .contant .image { width: 80px; height: 80px; border-radius: 4px; float: left; } /* Text information style on the right*/ .rightBox { overflow: hidden; padding-left: 8px; } .rightBox div:first-child { font-weight: bold; } .rightBox div:nth-child(2) { margin-top: 4px; font-size: 14px; } .rightBox div:nth-child(3) { width: 24px; background: rgb(219, 91, 113); color: white; font-size: 12px; text-align: center; padding: 2px 4px 2px 4px; margin-left: auto; } .rightBox div:last-child { color: red; font-size: 14px; font-weight: bold; } </style> The above is the detailed content of Vue's implementation of the left swipe to delete function. For more information about Vue's left swipe to delete, please pay attention to other related articles on 123WORDPRESS.COM! You may also be interested in:
|
<<: Mybatis mysql delete in operation can only delete the first data method
Table of contents Preface Related Materials Vue p...
How to write configuration files and use MyBatis ...
Table of contents index - General index - Unique ...
Table of contents Preface 1. Install NJS module M...
Let's start with the body: When viewing a web ...
Due to the initial partitioning of the system, th...
Table of contents 1. Clever use of indexes and va...
Practice is the only way to test the truth. This ...
HTML img tag: defines an image to be introduced in...
Table of contents Preface 1. Technical Principle ...
Note: In web development, after adding autocomplet...
cause The reason for writing this blog is that I ...
When modifying Magento frequently, you may encount...
I recently encountered a problem at work. The doc...
When learning mybatis, I encountered an error, th...