1. Introduction

I’ve been working on projects with Vue for a while. However, I have not written the article about the basic introduction of VUE, so today I will write three small examples of vUE introduction. These three small examples are my practice works when I just got in touch with VUE. The difficulty ranges from very simple to simple, and they are all entry-level. I hope it can help you learn and understand VUE better, and also let me review VUE. If you find the article is not good, write wrong, or have any suggestions! Welcome to guide the maze!

1. Vue version 2.4.2 is used in this article. There may be some differences with the new version. 2. Now I also assume that you have a basic KNOWLEDGE of HTML, CSS,javascript, also have seen the basic introduction of the official website, have a general understanding of VUE, understand the commonly used VUE instructions (V-Model, V-show, V-if, V-for, V-ON, V-bind, etc.)! If you just touch the front end, you may be looking at the article, it is recommended to learn the basics, grasp the basic knowledge to see! 3. In the following example, I suggest you do it while reading the article! This way your thinking will be very clear and not messy! Also won’t feel the article is long (the article is long to let everyone see more information, posted a lot of repeated code, these code. HTML, CSS and so on can completely skip to see). If you only read the article, you may not finish it, because THE article IS more detailed, more long! 4. These examples are taken from my own common practice projects, and the code is already mentioned on Github (vue-demos). Welcome to Star. !

2. What is vue

Vue is a popular front-end MVVM framework. It is data-driven and componentized. It is one of the three front-end frameworks along with Angular and React. Compared to Angular and React, Vue is lightweight, high-performance, and easy to use. You can also take a look at the introduction of VUE and the official website of the core functions. The simple way to understand it is: when you develop with Vue, you manipulate the data, and then vue will process the data to change the DOM. The following is a simple example of this

The following code

html

<div id="app">
  <p>{{ message }}</p>
  <input v-model="message">
</div>Copy the code

js

new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue! '}})Copy the code



< span style = “box-width: border-box; color: RGB (74, 74, 74); display: block; display: block; Ok, let’s go to examples!

3. The TAB

Running effect

Principle analysis and implementation

This is simple, just a click to switch display. But you have to do it. If this makes sense, look at the next two! This example should just be a warm-up and familiarization function!

It’s a one-step process, and there’s nothing wrong with the principle. I directly in the code to comment, read the comments, you understand!

The complete code

<! DOCTYPE html> <html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<style>
    body{
        font-family:"Microsoft YaHei";
    }
    #tab{
        width: 600px;
        margin: 0 auto;
    }
    .tab-tit{
        font-size: 0;
        width: 600px;
    }
    .tab-tit a{
        display: inline-block;
        height: 40px;
        line-height: 40px;
        font-size: 16px;
        width: 25%;
        text-align: center;
        background: #ccc;
        color: # 333;
        text-decoration: none;
    }
    .tab-tit .cur{
        background: #09f;
        color: #fff;
    }
    .tab-con div{
        border: 1px solid #ccc;
        height: 400px;
        padding-top: 20px;
    }
</style>
<body>
<div id="tab">
    <div class="tab-tit"> <! If curId = 0, curId = 1, curId = 1, curId = 1. > < span style = "box-sizing: border-box; color: RGB (0, 0, 0); line-height: 22px; font-size: 13px! Important; white-space: inherit! Important;"javascript:;" @click="curId=0" :class="{'cur':curId===0}">html</a>
        <a href="javascript:;" @click="curId=1" :class="{'cur':curId===1}">css</a>
        <a href="javascript:;" @click="curId=2" :class="{'cur':curId===2}">javascript</a>
        <a href="javascript:;" @click="curId=3" :class="{'cur':curId===3}">vue</a>
    </div>
    <div class="tab-con"> <! If curId is equal to 0, the first div is displayed and the other three divs are not displayed. If curId is equal to 1, the second div is displayed and the other three divs are not. <div style = "box-sizing: border-box; color: RGB (74, 74, 74)"curId===0">
            html<br/>
        </div>
        <div v-show="curId===1">
            css
        </div>
        <div v-show="curId===2">
            javascript
        </div>
        <div v-show="curId===3">
            vue
        </div>
    </div>
</div>
</body>
<script src="vue.min.js"></script>
<script>
    new Vue({
        el: '#tab',
        data: {
            curId: 0
        },
        computed: {},
        methods: {},
        mounted: function () {
        }
    })
</script>
</html>Copy the code

4. Total price

Running effect

Principle analysis and implementation

First of all, let’s write the layout, introduce vUE, and prepare the vUE instance. I won’t say much about this, the code is as follows

<! DOCTYPE html> <html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .fl{
            float: left;
        }
        .fr{
            float: right;
        }
       blockquote, body, dd, div, dl, dt, fieldset, form, h1, h2, h3, h4, h5, h6, img, input, li, ol, p, table, td, textarea, th, ul {
            margin: 0;
            padding: 0;
        }
       .clearfix{
          zoom: 1;
       }
        .clearfix:after {
            clear: both;
        }
        .clearfix:after {
            content: '. ';
            display: block;
            overflow: hidden;
            visibility: hidden;
            font-size: 0;
            line-height: 0;
            width: 0;
            height: 0;
        }
        a{
            text-decoration: none;
            color: # 333;} img{vertical-align: middle; } .page-shopping-cart { width: 1200px; margin: 50px auto; font-size: 14px; border: 1px solid#e3e3e3;
            border-top: 2px solid #317ee7; }
        .page-shopping-cart .cart-title {
            color: #317ee7;
            font-size: 16px;
            text-align: left;
            padding-left: 20px;
            line-height: 68px; }
        .page-shopping-cart .red-text {
            color: #e94826; }
        .page-shopping-cart .check-span {
            display: block;
            width: 24px;
            height: 20px;
            background: url("shopping_cart.png") no-repeat 0 0; }
        .page-shopping-cart .check-span.check-true {
            background: url("shopping_cart.png") no-repeat 0 -22px; }
        .page-shopping-cart .td-check {
            width: 70px; }
        .page-shopping-cart .td-product {
            width: 460px; }
        .page-shopping-cart .td-num, .page-shopping-cart .td-price, .page-shopping-cart .td-total {
            width: 160px; }
        .page-shopping-cart .td-do {
            width: 150px; }
        .page-shopping-cart .cart-product-title {
            text-align: center;
            height: 38px;
            line-height: 38px;
            padding: 0 20px;
            background: #f7f7f7;
            border-top: 1px solid #e3e3e3;
            border-bottom: 1px solid #e3e3e3; }
        .page-shopping-cart .cart-product-title .td-product {
            text-align: center;
            font-size: 14px; }
        .page-shopping-cart .cart-product-title .td-check {
            text-align: left; }
        .page-shopping-cart .cart-product-title .td-check .check-span {
            margin: 9px 6px 0 0; }
        .page-shopping-cart .cart-product {
            padding: 0 20px;
            text-align: center; }
        .page-shopping-cart .cart-product table {
            width: 100%;
            text-align: center;
            font-size: 14px; }
        .page-shopping-cart .cart-product table td {
            padding: 20px 0; }
        .page-shopping-cart .cart-product table tr {
            border-bottom: 1px dashed #e3e3e3; }
        .page-shopping-cart .cart-product table tr:last-child {
            border-bottom: none; }
        .page-shopping-cart .cart-product table .product-num {
            border: 1px solid #e3e3e3;
            display: inline-block;
            text-align: center; }
        .page-shopping-cart .cart-product table .product-num .num-do {
            width: 24px;
            height: 28px;
            display: block;
            background: #f7f7f7; }
        .page-shopping-cart .cart-product table .product-num .num-reduce span {
            background: url("shopping_cart.png") no-repeat -40px -22px;
            display: block;
            width: 6px;
            height: 2px;
            margin: 13px auto 0 auto; }
        .page-shopping-cart .cart-product table .product-num .num-add span {
            background: url("shopping_cart.png") no-repeat -60px -22px;
            display: block;
            width: 8px;
            height: 8px;
            margin: 10px auto 0 auto; }
        .page-shopping-cart .cart-product table .product-num .num-input {
            width: 42px;
            height: 28px;
            line-height: 28px;
            border: none;
            text-align: center; }
        .page-shopping-cart .cart-product table .td-product {
            text-align: left;
            font-size: 12px;
            line-height: 20px; }
        .page-shopping-cart .cart-product table .td-product img {
            border: 1px solid #e3e3e3;
            margin-right: 10px; }
        .page-shopping-cart .cart-product table .td-product .product-info {
            display: inline-block;
            vertical-align: middle; }
        .page-shopping-cart .cart-product table .td-do {
            font-size: 12px; }
        .page-shopping-cart .cart-product-info {
            height: 50px;
            line-height: 50px;
            background: #f7f7f7;
            padding-left: 20px; }
        .page-shopping-cart .cart-product-info .delect-product {
            color: # 666; }
        .page-shopping-cart .cart-product-info .delect-product span {
            display: inline-block;
            vertical-align: top;
            margin: 18px 8px 0 0;
            width: 13px;
            height: 15px;
            background: url("shopping_cart.png") no-repeat -60px 0; }
        .page-shopping-cart .cart-product-info .product-total {
            font-size: 14px;
            color: #e94826; }
        .page-shopping-cart .cart-product-info .product-total span {
            font-size: 20px; }
        .page-shopping-cart .cart-product-info .check-num {
            color: # 333; }
        .page-shopping-cart .cart-product-info .check-num span {
            color: #e94826; }
        .page-shopping-cart .cart-product-info .keep-shopping {
            color: # 666;
            margin-left: 40px; }
        .page-shopping-cart .cart-product-info .keep-shopping span {
            display: inline-block;
            vertical-align: top;
            margin: 18px 8px 0 0;
            width: 15px;
            height: 15px;
            background: url("shopping_cart.png") no-repeat -40px 0; }
        .page-shopping-cart .cart-product-info .btn-buy {
            height: 50px;
            color: #fff;
            font-size: 20px;
            display: block;
            width: 110px;
            background: #ff7700;
            text-align: center;
            margin-left: 30px; }
        .page-shopping-cart .cart-worder {
            padding: 20px; }
        .page-shopping-cart .cart-worder .choose-worder {
            color: #fff;
            display: block;
            background: #39e;
            width: 140px;
            height: 40px;
            line-height: 40px;
            border-radius: 4px;
            text-align: center;
            margin-right: 20px; }
        .page-shopping-cart .cart-worder .choose-worder span {
            display: inline-block;
            vertical-align: top;
            margin: 9px 10px 0 0;
            width: 22px;
            height: 22px;
            background: url("shopping_cart.png") no-repeat -92px 0; }
        .page-shopping-cart .cart-worder .worker-info {
            color: # 666; }
        .page-shopping-cart .cart-worder .worker-info img {
            border-radius: 100%;
            margin-right: 10px; }
        .page-shopping-cart .cart-worder .worker-info span {
            color: # 000; }

        .choose-worker-box {
            width: 620px;
            background: #fff; }
        .choose-worker-box .box-title {
            height: 40px;
            line-height: 40px;
            background: #F7F7F7;
            text-align: center;
            position: relative;
            font-size: 14px; }
        .choose-worker-box .box-title a {
            display: block;
            position: absolute;
            top: 15px;
            right: 16px;
            width: 10px;
            height: 10px;
            background: url("shopping_cart.png") no-repeat -80px 0; }
        .choose-worker-box .box-title a:hover {
            background: url("shopping_cart.png") no-repeat -80px -22px; }
        .choose-worker-box .worker-list {
            padding-top: 30px;
            height: 134px;
            overflow-y: auto; }
        .choose-worker-box .worker-list li {
            float: left;
            width: 25%;
            text-align: center;
            margin-bottom: 30px; }
        .choose-worker-box .worker-list li p {
            margin-top: 8px; }
        .choose-worker-box .worker-list li.cur a {
            color: #f70; }
        .choose-worker-box .worker-list li.cur a img {
            border: 1px solid #f70; }
        .choose-worker-box .worker-list li a:hover {
            color: #f70; }
        .choose-worker-box .worker-list li a:hover img {
            border: 1px solid #f70; }
        .choose-worker-box .worker-list li img {
            border: 1px solid #fff;
            border-radius: 100%; }
    </style>
</head>
<body>
<div class="page-shopping-cart" id="shopping-cart">
    <h4 class="cart-title"> <div class="cart-product-title clearfix">
        <div class="td-check fl"><span class="check-span fl check-all"Word-wrap: break-word! Important; ">< span style =" box-sizing: border-box; color: RGB (74, 74, 74)"td-product fl""> <div class="td-num fl"<div class="td-price fl"<div class="td-total fl"<div class="td-do fl"</div> <div class="cart-product clearfix">
        <table>
            <tbody><tr>
                <td class="td-check"><span class="check-span"></span></td>
                <td class="td-product"><img src="testimg.jpg" width="98" height="98">
                    <div class="product-info"Word-wrap: break-word! Important; "> < p style =" max-width: 100%; |&nbsp; <p style = "box-sizing: border-box; color: RGB (74, 74, 74); &nbsp; Origin: Korea </p> <p> Specification/Purity :99.7%&nbsp; &nbsp; </p> <p> <div class="clearfix"></div>
                </td>
                <td class="td-num">
                    <div class="product-num">
                        <a href="javascript:;" class="num-reduce num-do fl"><span></span></a>
                        <input type="text" class="num-input" value="3">
                        <a href="javascript:;" class="num-add num-do fr"><span></span></a>
                    </div>
                </td>
                <td class="td-price">
                    <p class="red-text"> $< span class ="price-text">800</span>.00</p>
                </td>
                <td class="td-total">
                    <p class="red-text"> $< span class ="total-text">800</span>.00</p>
                </td>
                <td class="td-do"><a href="javascript:;" class="product-delect"</a></td> </tr> <tr> <td class="td-check"><span class="check-span check-true"></span></td>
                <td class="td-product"><img src="testimg.jpg" width="98" height="98">
                    <div class="product-info"Word-wrap: break-word! Important; "> < p style =" max-width: 100%; |&nbsp; <p style = "box-sizing: border-box; color: RGB (74, 74, 74); &nbsp; Origin: Korea </p> <p> Specification/Purity :99.7%&nbsp; &nbsp; </p> <p> <div class="clearfix"></div>
                </td>
                <td class="td-num">
                    <div class="product-num">
                        <a href="javascript:;" class="num-reduce num-do fl"><span></span></a>
                        <input type="text" class="num-input" value="1">
                        <a href="javascript:;" class="num-add num-do fr"><span></span></a>
                    </div>
                </td>
                <td class="td-price">
                    <p class="red-text"> $< span class ="price-text">800</span>.00</p>
                </td>
                <td class="td-total">
                    <p class="red-text"> $< span class ="total-text">800</span>.00</p>
                </td>
                <td class="td-do"><a href="javascript:;" class="product-delect"> delete < / a > < / td > < / tr > < / tbody > < / table > < / div > < div class ="cart-product-info">
        <a class="delect-product" href="javascript:;"><span></span> Delete selected items </a> <a class="keep-shopping" href="#""><span style =" box-sizing: border-box! Important; word-wrap: break-word! Important"btn-buy fr" href="javascript:;"</a> <p class="fr product-total"<span style = "box-sizing: border-box! Important; word-wrap: break-word! Important;"fr check-num"<span style = "box-sizing: border-box! Important; word-wrap: break-word! Important;"cart-worder clearfix">
        <a href="javascript:;" class="choose-worder fl"><span></span> <div class="worker-info fl">
        </div>
    </div>
</div>
</body>
<script src="vue.min.js"></script>
<script>
    new Vue({
        el:'#shopping-cart',
        data:{

        },
        computed: {},
        methods:{
            
        }
    })
</script>
</html>Copy the code

Then prepare the following table data according to the arrows in the table below

So you know what? The numbers down here are going to go up like this

productList:[
    {
        'pro_name': 'sven 】 【 glycerin glycerin |',// Product name'pro_brand': 'skc',// Brand name'pro_place': 'Korea', / / origin'pro_purity': '99.7%', / / specifications'pro_min': "215 kg",// MoQ'pro_depot': 'Shanghai Canghai Storage',// In the warehouse'pro_num': / / the number 3'pro_img': '.. /.. /images/ucenter/testimg.jpg',// Image links'pro_price'}]Copy the code

Prepared so many, you may think, there is still a missing, is to record whether the product is selected, but this field, although you can add there above, but not significant, such as in the normal project there! Background data will not be returned like this, the database will not have this field, this field should be added. The following code

new Vue({
    el:'#shopping-cart',
    data:{
        productList:[
            {
                'pro_name': 'sven 】 【 glycerin glycerin |',// Product name'pro_brand': 'skc',// Brand name'pro_place': 'Korea', / / origin'pro_purity': '99.7%', / / specifications'pro_min': "215 kg",// MoQ'pro_depot': 'Shanghai Canghai Storage',// In the warehouse'pro_num': / / the number 3'pro_img': '.. /.. /images/ucenter/testimg.jpg',// Image links'pro_price'Price: 800 / /}}], computed: {}, the methods: {}, mounted:function() {// Add a select (whether selected) field to productList, with an initial value oftruevar _this=this; // Add select (whether selected) field to productList, initial value istrue
        this.productList.map(function (item) {
            _this.$set(item, 'select'.true); }) // If you want to write bidirectional binding like this, it will not work. //this.productList.map(function (item) {item.select=true})}})Copy the code

Step 1

To highlight what I’ve changed, I’m only Posting the changes in the code, so you can easily see what I’ve changed by looking at the layout above! The following is also the operation!

Click the Increase and Decrease button (where the arrow points), and the amount of the owning column changes (where the red box is).

Before performing Step 1, lay out the data in the list. Use the V-for instruction. The following code

<tr v-for="item in productList">
    <td class="td-check"><span class="check-span"></span></td>
    <td class="td-product"><img :src="item.pro_img" width="98" height="98">
        <div class="product-info"> < h6 > {{item. Pro_name}} < h6 > < p > brand: {{item. Pro_brand}} & have spent &nbsp; Origin: {{item. Pro_place}} < / p > < p > specifications/purity: {{item. Pro_purity}} & have spent &nbsp; Quantitative: {{item. Pro_min}} < / p > < p > distribution warehouse: {{item. Pro_depot}} < / p > < / div > < div class ="clearfix"></div>
    </td>
    <td class="td-num">
        <div class="product-num">
            <a href="javascript:;" class="num-reduce num-do fl" @click="item.pro_num--"><span></span></a>
            <input type="text" class="num-input" v-model="item.pro_num">
            <a href="javascript:;" class="num-add num-do fr" @click="item.pro_num++"><span></span></a>
        </div>
    </td>
    <td class="td-price">
        <p class="red-text"> $< span class ="price-text">{{item.pro_price.toFixed(2)}}</span></p>
    </td>
    <td class="td-total">
        <p class="red-text"> $< span class ="total-text">{{item.pro_price*item.pro_num}}</span>.00</p>
    </td>
    <td class="td-do"><a href="javascript:;" class="product-delect"</td> </tr>Copy the code

There you have the data for the list!

You can also see that,The functions of these two buttons have been realized, and the amount of money will also change! Isn’t it a surprise! There is nothing special here, except that the input field uses the V-Model to bind the quantity (pro_num), and then each button has an event added@click="item.pro_num--"And @click="item.pro_num++". So if you start with pro_num 3, click.pro_numIt becomes a 2. Click

.pro_numIt’s going to be 4, and then the next amount is going to change because{{item.pro_price*item.pro_num}}. As soon as the value of pro_price or pro_num changes, the whole block changes, the view refreshes, and we can see the changes (this is what Vue does, that’s the beauty of MVVM, data-driven view changes).

Step 2

Click the column selection button (arrow point to the place), the total amount (red box), the number of selected product columns (blue box) and select all (yellow box) will change (if all is selected, the select All button will automatically change to select all; if not, select all button will automatically cancel the select all)!

First, select and deselect, where there are only two operations (really just one: change the select field for this record).

Then changeIf this recordselectforfalse, it shows, otherwise displays.

The following code

<td class="td-check"><span class="check-span" @click="item.select=! item.select" :class="{'check-true':item.select}"></span></td>Copy the code

It’s essentially adding@click="item.select=! item.select" :class="{'check-true':item.select}"here Click on this, this dataselectThe field is inverted (true->false or false->true). then:class="{'check-true':item.select}", will be based on this dataselectField to determine whether to addcheck-trueClass name, ifselectIf the field is true, the class name is added and displayed. Otherwise, do not add the class name

.

And then,Select all button, whether to become. I’m going to do a computed here. The following code

html

<div class="td-check fl"><span class="check-span fl check-all" :class="{'check-true':isSelectAll}"> < / span > all < / div >Copy the code

js

computed: {
    isSelectAll:function(){// if productList has length 0if(this.productList.length===0){
            return false; } // If select for each item in productList istrueTo return totrueOtherwise returnfalse;
        return this.productList.every(function (val) { returnval.select}); }}Copy the code

So the code that I’m going to explain is that in the calculation property, the isSelectAll defined depends on the productList. As soon as productList changes, the return value of isSelectAll changes, and then:class="{'check-true':isSelectAll}"Root isSelectAll returns whether the value is added'check-true'Class name, show the corresponding style!

In the end,, here the number of products and total price, is also the use of computing attributes, with the basis of the previous step, give the code, you see it!

html

<p class="fr product-total"> $< span > {{getTotal. TotalPrice}} < / span > < / p > < p class ="fr check-num"><span style = "box-sizing: border-box; color: RGB (74, 74, 74); line-height: 22px; font-size: 14px! Important; white-space: inherit! Important;"Copy the code

js

Computed: {// Whether to select all isSelectAll:function(){// if productList has length 0if(this.productList.length===0){
            return false; } // If select for each item in productList istrueTo return totrueOtherwise returnfalse;
        return this.productList.every(function (val) { returnval.select}); }, // getTotal price and total number of products getTotal:function(){// get productList where select istrueThe data. var _proList=this.productList.filter(function (val) { return val.select}),totalPrice=0;
        for(var i=0,len=_proList.length; i<len; TotalPrice +=_proList[I]. Pro_num *_proList[I]. Pro_price; } // the number of products selected is _prolist.length, and the totalPrice is totalPricereturn {totalNum:_proList.length,totalPrice:totalPrice}
    }
},Copy the code

The HTML displays the data based on the return value of getTotal. GetTotal relies on the data from productList. Whenever productList changes, the return value changes and the view changes!

Step 3

Click the select all button (arrow pointing to the part), it will automatically select all products or cancel all selection, and the total below will also change



At this point, you should know that by selecting all or not selecting all, you are changing the recordselect. But how do you know if the current list is full? This is cheap, so you don’t have to go through the operation functions (select all and unselect all), and you remember the calculation properties in step 2isSelectAll(If true, select all, otherwise not all), pass this to the operator, and the operator will decide whether to select all or not, depending on the parameter. The code is as follows!

html

<div class="td-check fl"><span class="check-span fl check-all" :class="{'check-true':isSelectAll}"@click="selectProduct(isSelectAll)"> < / span > all < / div >Copy the code

js

Methods: {// Select and cancel selectProduct:function(_isSelect){// iterate over productList and invert allfor(var i = 0, len = this.productList.length; i < len; i++) { this.productList[i].select = ! _isSelect; }}},Copy the code

Step 4

Click delete products, will delete the selected, select all button and the total below, will change! Click Delete after each record to delete the current record. The select all button and the total below will also change!

First, click Delete product to delete what has been selected. Now you know how to do this! If select is true, delete the productList. Then, click Delete after each record to delete the current record. This is when the HTML iterates through productList. Take the index as an argument and pass it into the operation function. Then delete the productList record based on the index argument. Can be realized! The code is as follows! html

<! > <tr v-for="(item,index) in productList">
    <td class="td-check"><span class="check-span" @click="item.select=! item.select" :class="{'check-true':item.select}"></span></td>
    <td class="td-product"><img :src="item.pro_img" width="98" height="98">
        <div class="product-info"> < h6 > {{item. Pro_name}} < h6 > < p > brand: {{item. Pro_brand}} & have spent &nbsp; Origin: {{item. Pro_place}} < / p > < p > specifications/purity: {{item. Pro_purity}} & have spent &nbsp; Quantitative: {{item. Pro_min}} < / p > < p > distribution warehouse: {{item. Pro_depot}} < / p > < / div > < div class ="clearfix"></div>
    </td>
    <td class="td-num">
        <div class="product-num">
            <a href="javascript:;" class="num-reduce num-do fl" @click="item.pro_num--"><span></span></a>
            <input type="text" class="num-input" v-model="item.pro_num">
            <a href="javascript:;" class="num-add num-do fr" @click="item.pro_num++"><span></span></a>
        </div>
    </td>
    <td class="td-price">
        <p class="red-text"> $< span class ="price-text">{{item.pro_price.toFixed(2)}}</span></p>
    </td>
    <td class="td-total">
        <p class="red-text"> $< span class ="total-text">{{item.pro_price*item.pro_num}}</span>.00</p>
    </td>
    <td class="td-do"><a href="javascript:;" class="product-delect" @click="deleteOneProduct(index)"</td> </tr>... <a class="delect-product" href="javascript:;" @click="deleteProduct"><span style = "box-sizing: border-box! Important; word-wrap: break-word! Important;"Copy the code

js

// Delete already selected (select=true) product of:function () {
    this.productList=this.productList.filter(function (item) {return! Select item.select})}, deleteOneProduct:function(index) {this.productList.splice(index,1); },Copy the code

The complete code

The style picture

<! DOCTYPE html> <html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .fl {
            float: left;
        }

        .fr {
            float: right;
        }

        blockquote, body, dd, div, dl, dt, fieldset, form, h1, h2, h3, h4, h5, h6, img, input, li, ol, p, table, td, textarea, th, ul {
            margin: 0;
            padding: 0;
        }

        .clearfix {
            zoom: 1;
        }

        .clearfix:after {
            clear: both;
        }

        .clearfix:after {
            content: '. ';
            display: block;
            overflow: hidden;
            visibility: hidden;
            font-size: 0;
            line-height: 0;
            width: 0;
            height: 0;
        }

        a {
            text-decoration: none;
            color: # 333;
        }

        img {
            vertical-align: middle;
        }

        .page-shopping-cart {
            width: 1200px;
            margin: 50px auto;
            font-size: 14px;
            border: 1px solid #e3e3e3;
            border-top: 2px solid #317ee7;
        }

        .page-shopping-cart .cart-title {
            color: #317ee7;
            font-size: 16px;
            text-align: left;
            padding-left: 20px;
            line-height: 68px;
        }

        .page-shopping-cart .red-text {
            color: #e94826;
        }

        .page-shopping-cart .check-span {
            display: block;
            width: 24px;
            height: 20px;
            background: url("shopping_cart.png") no-repeat 0 0;
        }

        .page-shopping-cart .check-span.check-true {
            background: url("shopping_cart.png") no-repeat 0 -22px;
        }

        .page-shopping-cart .td-check {
            width: 70px;
        }

        .page-shopping-cart .td-product {
            width: 460px;
        }

        .page-shopping-cart .td-num, .page-shopping-cart .td-price, .page-shopping-cart .td-total {
            width: 160px;
        }

        .page-shopping-cart .td-do {
            width: 150px;
        }

        .page-shopping-cart .cart-product-title {
            text-align: center;
            height: 38px;
            line-height: 38px;
            padding: 0 20px;
            background: #f7f7f7;
            border-top: 1px solid #e3e3e3;
            border-bottom: 1px solid #e3e3e3;
        }

        .page-shopping-cart .cart-product-title .td-product {
            text-align: center;
            font-size: 14px;
        }

        .page-shopping-cart .cart-product-title .td-check {
            text-align: left;
        }

        .page-shopping-cart .cart-product-title .td-check .check-span {
            margin: 9px 6px 0 0;
        }

        .page-shopping-cart .cart-product {
            padding: 0 20px;
            text-align: center;
        }

        .page-shopping-cart .cart-product table {
            width: 100%;
            text-align: center;
            font-size: 14px;
        }

        .page-shopping-cart .cart-product table td {
            padding: 20px 0;
        }

        .page-shopping-cart .cart-product table tr {
            border-bottom: 1px dashed #e3e3e3;
        }

        .page-shopping-cart .cart-product table tr:last-child {
            border-bottom: none;
        }

        .page-shopping-cart .cart-product table .product-num {
            border: 1px solid #e3e3e3;
            display: inline-block;
            text-align: center;
        }

        .page-shopping-cart .cart-product table .product-num .num-do {
            width: 24px;
            height: 28px;
            display: block;
            background: #f7f7f7;
        }

        .page-shopping-cart .cart-product table .product-num .num-reduce span {
            background: url("shopping_cart.png") no-repeat -40px -22px;
            display: block;
            width: 6px;
            height: 2px;
            margin: 13px auto 0 auto;
        }

        .page-shopping-cart .cart-product table .product-num .num-add span {
            background: url("shopping_cart.png") no-repeat -60px -22px;
            display: block;
            width: 8px;
            height: 8px;
            margin: 10px auto 0 auto;
        }

        .page-shopping-cart .cart-product table .product-num .num-input {
            width: 42px;
            height: 28px;
            line-height: 28px;
            border: none;
            text-align: center;
        }

        .page-shopping-cart .cart-product table .td-product {
            text-align: left;
            font-size: 12px;
            line-height: 20px;
        }

        .page-shopping-cart .cart-product table .td-product img {
            border: 1px solid #e3e3e3;
            margin-right: 10px;
        }

        .page-shopping-cart .cart-product table .td-product .product-info {
            display: inline-block;
            vertical-align: middle;
        }

        .page-shopping-cart .cart-product table .td-do {
            font-size: 12px;
        }

        .page-shopping-cart .cart-product-info {
            height: 50px;
            line-height: 50px;
            background: #f7f7f7;
            padding-left: 20px;
        }

        .page-shopping-cart .cart-product-info .delect-product {
            color: # 666;
        }

        .page-shopping-cart .cart-product-info .delect-product span {
            display: inline-block;
            vertical-align: top;
            margin: 18px 8px 0 0;
            width: 13px;
            height: 15px;
            background: url("shopping_cart.png") no-repeat -60px 0;
        }

        .page-shopping-cart .cart-product-info .product-total {
            font-size: 14px;
            color: #e94826;
        }

        .page-shopping-cart .cart-product-info .product-total span {
            font-size: 20px;
        }

        .page-shopping-cart .cart-product-info .check-num {
            color: # 333;
        }

        .page-shopping-cart .cart-product-info .check-num span {
            color: #e94826;
        }

        .page-shopping-cart .cart-product-info .keep-shopping {
            color: # 666;
            margin-left: 40px;
        }

        .page-shopping-cart .cart-product-info .keep-shopping span {
            display: inline-block;
            vertical-align: top;
            margin: 18px 8px 0 0;
            width: 15px;
            height: 15px;
            background: url("shopping_cart.png") no-repeat -40px 0;
        }

        .page-shopping-cart .cart-product-info .btn-buy {
            height: 50px;
            color: #fff;
            font-size: 20px;
            display: block;
            width: 110px;
            background: #ff7700;
            text-align: center;
            margin-left: 30px;
        }

        .page-shopping-cart .cart-worder {
            padding: 20px;
        }

        .page-shopping-cart .cart-worder .choose-worder {
            color: #fff;
            display: block;
            background: #39e;
            width: 140px;
            height: 40px;
            line-height: 40px;
            border-radius: 4px;
            text-align: center;
            margin-right: 20px;
        }

        .page-shopping-cart .cart-worder .choose-worder span {
            display: inline-block;
            vertical-align: top;
            margin: 9px 10px 0 0;
            width: 22px;
            height: 22px;
            background: url("shopping_cart.png") no-repeat -92px 0;
        }

        .page-shopping-cart .cart-worder .worker-info {
            color: # 666;
        }

        .page-shopping-cart .cart-worder .worker-info img {
            border-radius: 100%;
            margin-right: 10px;
        }

        .page-shopping-cart .cart-worder .worker-info span {
            color: # 000;
        }

        .choose-worker-box {
            width: 620px;
            background: #fff;
        }

        .choose-worker-box .box-title {
            height: 40px;
            line-height: 40px;
            background: #F7F7F7;
            text-align: center;
            position: relative;
            font-size: 14px;
        }

        .choose-worker-box .box-title a {
            display: block;
            position: absolute;
            top: 15px;
            right: 16px;
            width: 10px;
            height: 10px;
            background: url("shopping_cart.png") no-repeat -80px 0;
        }

        .choose-worker-box .box-title a:hover {
            background: url("shopping_cart.png") no-repeat -80px -22px;
        }

        .choose-worker-box .worker-list {
            padding-top: 30px;
            height: 134px;
            overflow-y: auto;
        }

        .choose-worker-box .worker-list li {
            float: left;
            width: 25%;
            text-align: center;
            margin-bottom: 30px;
        }

        .choose-worker-box .worker-list li p {
            margin-top: 8px;
        }

        .choose-worker-box .worker-list li.cur a {
            color: #f70;
        }

        .choose-worker-box .worker-list li.cur a img {
            border: 1px solid #f70;
        }

        .choose-worker-box .worker-list li a:hover {
            color: #f70;
        }

        .choose-worker-box .worker-list li a:hover img {
            border: 1px solid #f70;
        }

        .choose-worker-box .worker-list li img {
            border: 1px solid #fff;
            border-radius: 100%;
        }
    </style>
</head>
<body>
<div class="page-shopping-cart" id="shopping-cart">
    <h4 class="cart-title"> <div class="cart-product-title clearfix">
        <div class="td-check fl"><span class="check-span fl check-all" :class="{'check-true':isSelectAll}" @click="selectProduct(isSelectAll)"Word-wrap: break-word! Important; ">< span style =" box-sizing: border-box; color: RGB (74, 74, 74)"td-product fl""> <div class="td-num fl"<div class="td-price fl"<div class="td-total fl"<div class="td-do fl"</div> <div class="cart-product clearfix"> <table> <tbody> <! > <tr v-for="(item,index) in productList">
                <td class="td-check"><span class="check-span" @click="item.select=! item.select" :class="{'check-true':item.select}"></span></td>
                <td class="td-product"><img :src="item.pro_img" width="98" height="98">
                    <div class="product-info"> < h6 > {{item. Pro_name}} < h6 > < p > brand: {{item. Pro_brand}} & have spent &nbsp; Origin: {{item. Pro_place}} < / p > < p > specifications/purity: {{item. Pro_purity}} & have spent &nbsp; Quantitative: {{item. Pro_min}} < / p > < p > distribution warehouse: {{item. Pro_depot}} < / p > < / div > < div class ="clearfix"></div>
                </td>
                <td class="td-num">
                    <div class="product-num">
                        <a href="javascript:;" class="num-reduce num-do fl" @click="item.pro_num>0? item.pro_num--:''"><span></span></a>
                        <input type="text" class="num-input" v-model="item.pro_num">
                        <a href="javascript:;" class="num-add num-do fr" @click="item.pro_num++"><span></span></a>
                    </div>
                </td>
                <td class="td-price">
                    <p class="red-text"> $< span class ="price-text">{{item.pro_price.toFixed(2)}}</span></p>
                </td>
                <td class="td-total">
                    <p class="red-text"> $< span class ="total-text">{{item.pro_price*item.pro_num}}</span>.00</p>
                </td>
                <td class="td-do"><a href="javascript:;" class="product-delect" @click="deleteOneProduct(index)"> delete < / a > < / td > < / tr > < / tbody > < / table > < / div > < div class ="cart-product-info">
        <a class="delect-product" href="javascript:;" @click="deleteProduct"><span></span> Delete selected items </a> <a class="keep-shopping" href="#""><span style =" box-sizing: border-box! Important; word-wrap: break-word! Important"btn-buy fr" href="javascript:;"</a> <p class="fr product-total"> $< span > {{getTotal. TotalPrice}} < / span > < / p > < p class ="fr check-num"><span>{{gettotal.totalNum}}</span> </p> </div> </div> </body> <script SRC =".. /vue.min.js"></script>
<script>
    new Vue({
        el: '#shopping-cart',
        data: {
            productList: [
                {
                    'pro_name': 'sven 】 【 glycerin glycerin |',// Product name'pro_brand': 'skc',// Brand name'pro_place': 'Korea', / / origin'pro_purity': '99.7%', / / specifications'pro_min': "215 kg",// MoQ'pro_depot': 'Shanghai Canghai Storage',// In the warehouse'pro_num': / / the number 3'pro_img': '.. /.. /images/ucenter/testimg.jpg',// Image links'pro_price': 800// unit price}, {'pro_name': 'sven 】 【 glycerin glycerin |',// Product name'pro_brand': 'skc',// Brand name'pro_place': 'Korea', / / origin'pro_purity': '99.7%', / / specifications'pro_min': "215 kg",// MoQ'pro_depot': 'Shanghai Canghai Storage',// In the warehouse'pro_num': / / the number 3'pro_img': '.. /.. /images/ucenter/testimg.jpg',// Image links'pro_price': 800// unit price}, {'pro_name': 'sven 】 【 glycerin glycerin |',// Product name'pro_brand': 'skc',// Brand name'pro_place': 'Korea', / / origin'pro_purity': '99.7%', / / specifications'pro_min': "215 kg",// MoQ'pro_depot': 'Shanghai Canghai Storage',// In the warehouse'pro_num': / / the number 3'pro_img': '.. /.. /images/ucenter/testimg.jpg',// Image links'pro_price'}]}, computed: {// Whether to select all isSelectAll:function(){// If length is 0, returnfalse
                if(this.productList.length===0){
                    return false; } // If select for each item in productList istrueTo return totrueOtherwise returnfalse;
                return this.productList.every(function (val) { returnval.select}); }, // getTotal price and total number of products getTotal:function(){// get productList where select istrueThe data. var _proList=this.productList.filter(function (val) { return val.select}),totalPrice=0;
                for(var i=0,len=_proList.length; i<len; TotalPrice +=_proList[I]. Pro_num *_proList[I]. Pro_price; } // the number of products selected is _prolist.length, and the totalPrice is totalPricereturn{totalNum: _proList length, totalPrice: totalPrice}}}, the methods: {/ / selection and cancel all selectProduct:function(_isSelect){// iterate over productList and invert allfor(var i = 0, len = this.productList.length; i < len; i++) { this.productList[i].select = ! _isSelect; }}, // delete already selected (select=true) product of:function () {
                this.productList=this.productList.filter(function (item) {return! Select item.select})}, deleteOneProduct:function(index) {this.productList.splice(index,1); }, }, mounted:function() { var _this=this; // Add select (whether selected) field to productList, initial value istrue
            this.productList.map(function (item) {
                _this.$set(item, 'select'.true);
            })
        }
    })
</script>
</html>Copy the code

5.todoList

Running effect

Principle analysis and implementation

First of all, let’s write the layout, introduce vUE, and prepare the vUE instance. I won’t say much about this, the code is as follows

<! DOCTYPE html> <html> <head> <meta charset="UTF-8">
        <title></title>
        <style>
            body{font-family: Microsoft Yahei; font-size: 14px; } input{font-size: 14px; } body,ul,div,html{padding: 0; margin: 0; } .hidden{display: none; } .main{width: 800px; margin: 0 auto; } li{list-style-type: none; line-height: 40px; position: relative; border: 1px solid transparent; padding: 0 20px; } li .type-span{display: block; width: 10px; height: 10px; background:#ccc; margin: 14px 10px 0 0 ; float: left; }li .close{position: absolute; color:#f00; font-size: 20px; line-height: 40px; height: 40px; right: 20px; cursor: pointer; display: none; top: 0; }
            li:hover{border: 1px solid #09f; }li:hover .close{display: block; } li .text-keyword{height: 40px; padding-left: 10px; box-sizing: border-box; margin-left: 10px; width: 80%; display: none; } .text-keyword{box-sizing: border-box; width: 100%; height: 40px; padding-left: 10px; outline: none; } </style> </head> <body> <div id="app" class="main"> <div class="list"> <h3> Add a small target </h3> <inputtype="text" class="text-keyword" placeholder="Enter the small target and press Enter to confirm."/> <p> <p> <inputtype="radio" name="chooseType" checked="true"/><label> All targets </label> <inputtype="radio" name="chooseType"/><label> Completed target </label> <inputtype="radio" name="chooseType"/ > < label > unfinished target < / label > < / p > < / div > < ul > < li class ="li1">
                    <div>
                        <span class="type-span"></span>
                        <span>html5</span>
                        <span class="close">X</span>
                    </div>
                </li>
                <li class="li1">
                    <div>
                        <span class="type-span"></span>
                        <span>css3</span>
                        <span class="close">X</span>
                    </div>
                </li>
            </ul>
        </div>
    </body>
    <script src="Vue2.4.2. Js"></script>
    <script type="text/javascript">
    new Vue({
        el: "#app",
        data: {
        },
        computed:{
            
        },
        methods:{
            
        }
    });
    </script>
</html>Copy the code

Layout has, equivalent to a skeleton has, the following to achieve functions, one by one

Step 1

Type and press Enter, one more record. The following transcript will also change

First, to add a record to a large input field, the input field must be bound to a value and a method to add the record.

The code is as follows:

Then, the following record must also be changed, so the following record must also have a value, because there may be more than one record, this value is an array, you can also see that in addition to the name of the record, the record is completed or not, so this value must be an array of objects! The following code

Finally, take notesWant to change. This is just the length of the current record!

To highlight what I’ve changed, I’m only Posting the changes in the code, so you can easily see what I’ve changed by looking at the layout above! The following is also the operation!

The HTML code

<! -- use v-model to bind addText to input--> <inputtype="text" class="text-keyword" placeholder="Enter the small target and press Enter to confirm." @keyup.13='addList' v-model="addText"/> <p> There are {{prolist.length}} targets </p> <! <li class=. <li class="li1" v-for="list in prolist">
    <div>
        <span class="type-span"></span>
        <span>{{list.name}}</span>
        <span class="close">X</span>
    </div>
</li>
Copy the code

Js code

new Vue({
    el: "#app",
    data: {
        addText:' 'Prolist :[{name:] prolist:[{name:]"HTML5",status:false},
               {name:"CSS3",status:false},
               {name:"vue",status:false},
               {name:"react",status:false}
        ]
    },
    computed:{
        
    },
    methods:{
        addList(){// Add in the default status=falseThis.prolist. push({name: this.addtext, status:false}); // After adding, clear addText this.addText=""; }}});Copy the code

Test it. No problem

Step 2

Click toggle and the following records will change

When you look at the three options, it’s very simple, it’s just three choices, one is all of the goals, one is all of the goals that have been accomplished, and one is all of the goals that haven’t been accomplished. First of all, create a new variable (newList) to store the ProList. Instead of iterating over proList, you’re iterating over newList. Changing is also changing newList. And then, when you select all the targets, you display all the prolists, and you assign the prolist to newList. Then, when you select all the targets that have been completed, only the targets in the proList whose status is true will be displayed, and the items in the ProList whose status is true will be assigned to newList. When selecting all incomplete targets, only targets whose status is false are displayed, and items in proList whose status is false are assigned to newList.

The following code

html

 <ul>
    <li class="li1" v-for="list in newList">
        <div>
            <span class="status-span"></span>
            <span>{{list.name}}</span>
            <span class="close" @click='delectList(index)'>X</span>
        </div>
    </li>
</ul>Copy the code

js

new Vue({
    el: "#app",
    data: {
        addText:' 'Prolist :[{name:] prolist:[{name:]"HTML5",status:false},
               {name:"CSS3",status:false},
               {name:"vue",status:false},
               {name:"react",status:false}
        ],
        newList:[]
    },
    computed:{
        noend:function() {return this.prolist.filter(function(item){
                return! item.status }).length; } }, methods:{addList(){// Add in the default status=falseThis.prolist. push({name: this.addtext, status:false}); // After adding, clear addText this.addText="";
        },
        chooseList(type{/ /typeWhen =1, select all targets //typeWhen =2, select all completed targets //typeIf =3, select all unfinished target switch(type) {case 1:this.newList=this.prolist;break;
                case 2:this.newList=this.prolist.filter(function(item){return item.status});break;
                case 3:this.newList=this.prolist.filter(function(item){return! item.status});break; }}, delectList(index){this.prolist.splice(index,1); // Update newList newList may be assigned by this.prolist.filter(). In this case, removing proList does not affect newList. }},mounted(){// initialize, assigning proList to newList. By default, all targets are displayed this.newList=this.prolist; }});Copy the code

The results

Step 3

Red close logo, click will delete the record. Click the button in front to switch the completion state of the record, the color will also change, and the record text will also change

First click the red close sign, clicking will delete the record. Delete a record from the Prolist! Then click on the front button to switch the finished state of the record. Change the status field of a record in the ProList! The final change in the record text is to record how many items in the ProList have status false and how many items in the ProList have status true

The HTML code

<! <p> {{prolist. Length}} {prolist. Length}} {prolist. {{noend==0?"All done.":'Done'+(prolist.length-noend)+', and '.+noend+'Bar unfinished'}}</p>


<ul>
    <li class="li1" v-for="(list,index) in newList">
        <div>
            <span class="status-span" @click="list.status=! list.status" :class="{'status-end':list.status}"></span>
            <span>{{list.name}}</span>
            <span class="close" @click='delectList(index)'>X</span>
        </div>
    </li>
</ul>Copy the code

js

new Vue({
    el: "#app",
    data: {
        addText:' 'Prolist :[{name:] prolist:[{name:]"HTML5",status:false},
               {name:"CSS3",status:false},
               {name:"vue",status:false},
               {name:"react",status:false}], newList:[]}, computed:{// Calculates the number of objects that are not completedfalseThe number of article noend:function() {return this.prolist.filter(function(item){
                return! item.status }).length; } }, methods:{addList(){// Add in the default status=falseThis.prolist. push({name: this.addtext, status:false}); // After adding, clear addText this.addText="";
        },
        chooseList(type){
            switch(type) {case 1:this.newList=this.prolist;break;
                case 2:this.newList=this.prolist.filter(function(item){return item.status});break;
                case 3:this.newList=this.prolist.filter(function(item){return! item.status});break; }}, delectList(index){this.prolist.splice(index,1); // Update newList newList may be assigned by this.prolist.filter(). In this case, removing proList does not affect newList. }},mounted(){ this.newList=this.prolist; }});Copy the code

The results

Step 4

Double click on the text will bring up the input box, you can type the text, if enter or lose focus, change the text, if press ESC to restore the original text

First of all, double-click the text to appear the input box, that is, double-click the text, set the current Li class name (‘ eidting ‘), and then write the style. When li appears with the class name, the input box appears and everything else is hidden. Then, press enter or lose focus and change the text. This only requires one operation, which is to clear the class name (‘ eidting ‘). Then the input field will be hidden and the rest of the content will be displayed! Finally, press ESC to restore the original text, that is, when the input box appears, use a variable (‘ beforeEditText ‘) to save the current content, and then press ESC to assign the variable (‘ beforeEditText ‘) to the value of the current operation!

The code is as follows:

html

<ul>
    <li class="li1" v-for="(list,index) in newList" :class="{'eidting':curIndex===index}">
        <div>
            <span class="status-span" @click="list.status=! list.status" :class="{'status-end':list.status}"></span>
            <span @dblclick="curIndex=index">{{list.name}}</span>
            <span class="close" @click='delectList(index)'>X</span>
        </div>
        <input type="text" class="text2" v-model='list.name' @keyup.esc='cancelEdit(list)' @blur='edited' @focus='editBefore(list.name)' @keyup.enter='edited'/>
    </li>
</ul>Copy the code

CSS (plus)

li div{display: block; } li.eidting div{display: none; } li .text2{height: 40px; padding-left: 10px; box-sizing: border-box; margin-left: 10px; width: 80%; display: none; } li.eidting .text2{display: block; }Copy the code

js

methods:{
        addList(){// Add in the default status=falseThis.prolist. push({name: this.addtext, status:false}); // After adding, clear addText this.addText="";
        },
        chooseList(type{/ /typeWhen =1, select all targets //typeWhen =2, select all completed targets //typeIf =3, select all unfinished target switch(type) {case 1:this.newList=this.prolist;break;
                case 2:this.newList=this.prolist.filter(function(item){return item.status});break;
                case 3:this.newList=this.prolist.filter(function(item){return! item.status});break; }}, delectList(index){this.prolist.splice(index,1); // Update newList newList may be assigned by this.prolist.filter(). In this case, removing proList does not affect newList. }, // editBefore(name){// record the current item first (for example, {name:"HTML5",status:false/ / beforeEditText =})"HTML5"this.beforeEditText=name; }, // After the modification is completeedited(){// set curIndex=""The input field is hidden and the other elements are displayed. Because I wrote: :class= in the li element"{'eidting':curIndex===index}"When curIndex does not equal index, the eidting class name is cleared! // The input box is bound to the preceding item using v-Model (for example, {name:"HTML5",status:false}) when editing the input field, such as' HTML ', the name of the current item is actually changed to 'HTML', so this step only clears the name of the eidting class to hide the input field. For example, change this entry in newList ({name:"HTML5",status:false}), for example ({name:"HTML",status:true}). In fact, this entry in the prolist ({name:"HTML5",status:false}), will also be changed to ({name:"HTML",status:true}). Because this is an object, and a common stack! If you modify one of them, the other will be affected by this.curindex =""; }, cancelEdit(val){// The input box uses v-model to bind to the preceding item (for example, {name:"HTML5",status:false}), when the input box is edited, such as' HTML ', the name of the current item is actually changed to 'HTML', so this step is to assign the name attribute of the current item to the value saved before, to restore the original value! val.name=this.beforeEditText; this.curIndex=""; }},Copy the code

The results

There is a small detail, you may have noticed, is double click text, out of the input box, but also their own manual click, to get the focus, we want to double click, input box out, automatically get the focus, how to do? Custom instructions on the line!

computed:{... }, methods:{... },mounted() {... }, directives:{"focus":{ update(el){ el.focus(); }}}Copy the code

The HTML then calls the instruction

<input type="text" class="text2" v-model='list.name' @keyup.esc='cancelEdit(list)' @blur='edited' @focus='editBefore(list.name)' @keyup.enter='edited' v-focus/>Copy the code

The complete code

<! DOCTYPE html> <html> <head> <meta charset="UTF-8">
    <title></title>
    <style>
        body{font-family: Microsoft Yahei; font-size: 14px; } input{font-size: 14px; } body,ul,div,html{padding: 0; margin: 0; } .hidden{display: none; } .main{width: 800px; margin: 0 auto; } li{list-style-type: none; line-height: 40px; position: relative; border: 1px solid transparent; padding: 0 20px; } li .status-span{display: block; width: 10px; height: 10px; background:#ccc; margin: 14px 10px 0 0 ; float: left; }
        li .status-span.status-end{
            background: #09f;} li .close{position: absolute; color:#f00; font-size: 20px; line-height: 40px; height: 40px; right: 20px; cursor: pointer; display: none; top: 0; }
        li:hover{border: 1px solid #09f; }li:hover .close{display: block; } li div{display: block; } li.eidting div{display: none; } li .text2{height: 40px; padding-left: 10px; box-sizing: border-box; margin-left: 10px; width: 80%; display: none; } li.eidting .text2{display: block; } li .text-keyword{height: 40px; padding-left: 10px; box-sizing: border-box; margin-left: 10px; width: 80%; display: none; } .text-keyword{box-sizing: border-box; width: 100%; height: 40px; padding-left: 10px; outline: none; } </style> </head> <body> <div id="app" class="main"> <div class="list"> <h3> Add a small target </h3> <inputtype="text" class="text-keyword" placeholder="Enter the small target and press Enter to confirm." @keyup.13='addList' v-model="addText"/ > <! <p> {{prolist. Length}} {prolist. Length}} {prolist. {{noend==0?"All done.":'Done'+(prolist.length-noend)+', and '.+noend+'Bar unfinished'}}</p>
        <p>
            <input type="radio" name="chooseType" checked="true" @click='chooseList(1)'/><label> All targets </label> <inputtype="radio" name="chooseType" @click='chooseList(2)'/><label> Completed target </label> <inputtype="radio" name="chooseType" @click='chooseList(3)'/ > < label > unfinished target < / label > < / p > < / div > < ul > < li class ="li1" v-for="(list,index) in newList" :class="{'eidting':curIndex===index}">
            <div>
                <span class="status-span" @click="changeType(index)" :class="{'status-end':list.status}"></span>
                <span @dblclick="curIndex=index">{{list.name}}</span>
                <span class="close" @click='delectList(list)'>X</span>
            </div>
            <input type="text" class="text2" v-model='list.name' @keyup.esc='cancelEdit(list)' @blur='edited' @focus='editBefore(list.name)' @keyup.enter='edited' v-focus/>
        </li>
    </ul>
</div>
</body>
<script src="vue.min.js"></script>
<script type="text/javascript">
    new Vue({
        el: "#app",
        data: {
            addText:' 'Prolist :[{name:] prolist:[{name:]"HTML5",status:false},
                {name:"CSS3",status:false},
                {name:"vue",status:false},
                {name:"react",status:false}
            ],
            newList:[],
            curIndex:' ',
            beforeEditText:"", curType:0}, computed:{// Computed properties, returns the number of incomplete objects, status= in the arrayfalseThe number of article noend:function() {return this.prolist.filter(function(item){
                    return! item.status }).length; } }, methods:{addList(){// Add in the default status=falseThis.prolist. push({name: this.addtext, status:false}); // After adding, clear addText this.addText="";
            },
            chooseList(type{/ /typeWhen =1, select all targets //typeWhen =2, select all completed targets //typeWhen =3, select all unfinished targets this.curtype =type;
                switch(type) {case 1:this.newList=this.prolist;break;
                    case 2:this.newList=this.prolist.filter(function(item){return item.status});break;
                    case 3:this.newList=this.prolist.filter(function(item){return! item.status});break; }}, /* changeType(index){this.newlist [index].status=! this.newList[index].status; This.chooselist (this.curtype); }, delectList(list){ var index=this.prolist.indexOf(list); This.prolist.splice (index,1); this.prolist.splice(index,1); // newList=this.prolist; // newList=this.prolist; // newList=this.prolist; this.chooseList(this.curType); }, // editBefore(name){// record the current item first (for example, {name:"HTML5",status:false/ / beforeEditText =})"HTML5"this.beforeEditText=name; }, // After the modification is completeedited(){// set curIndex=""The input field is hidden and the other elements are displayed. Because I wrote: :class= in the li element"{'eidting':curIndex===index}"When curIndex does not equal index, the eidting class name is cleared! // The input box is bound to the preceding item using v-Model (for example, {name:"HTML5",status:false}) when editing the input field, such as' HTML ', the name of the current item is actually changed to 'HTML', so this step only clears the name of the eidting class to hide the input field. For example, change this entry in newList ({name:"HTML5",status:false}), for example ({name:"HTML",status:true}). In fact, this entry in the prolist ({name:"HTML5",status:false}), will also be changed to ({name:"HTML",status:true}). Because this is an object, and a common stack! If you modify one of them, the other will be affected by this.curindex =""; }, cancelEdit(val){// The input box uses v-model to bind to the preceding item (for example, {name:"HTML5",status:false}), when the input box is edited, such as' HTML ', the name of the current item is actually changed to 'HTML', so this step is to assign the name attribute of the current item to the value saved before, to restore the original value! val.name=this.beforeEditText; this.curIndex=""; }},mounted(){// initialize, assigning proList to newList. By default, all targets are displayed this.newList=this.prolist; }, directives:{"focus":{ update(el){ el.focus(); }}}}); </script> </html>Copy the code

6. Summary

Well, that’s all for three small examples! Don’t look at the article so long, in fact, are the basis, may be I more verbose just! If you can understand these small examples, I believe that vUE is also easy to do projects. The basic grammar is here, with the foundation, the advanced writing method will not be difficult to learn! If, in the future, I have something to share, I will keep sharing. Finally, if you think I have written something wrong or bad, please give me some advice!


— — — — — — — — — — — — — — — — — — — — — — — — — gorgeous line — — — — — — — — — — — — — — — — — — — — want to know more, pay attention to focus on my WeChat public number: waiting for book cabinet