1. Introduction

I have been working on a project with VUE for a while, and I have also written a related article about vUE and Webpack construction projects before. If you are interested, you can go to see the actual practice of Webpack + Vue project (a, build the operating environment and related configuration). But about vUE entry basic article, I have not written, so today I will write vUE entry of three small examples, these three small examples is my first contact with VUE practice works, difficulty from very simple to simple, are entry level. I hope I can help you better learn and understand VUE, but also let yourself review VUE. If you find something wrong, wrong, or have any suggestions! Welcome to give directions!

1. The VUE version used in this article is 2.4.2, we should pay attention to version problem 2. Now I also assume that you have a basic knowledge of HTML, CSS,javascript, and have read the basic introduction of the official website. You have a general understanding of vUE instructions (V-model, V-show, V-if, V-for, V-ON, V-bind, etc.). If you just touch the front end, you may look at the article will be confused, it is recommended to learn the basics, master the basic knowledge to see again! 3. The following examples suggest that you read the article while doing it! This will be very clear thinking, not easy confusion! Will not feel the article long! If you only read the article, you may not be able to finish it, because the article I spoke in detail, more long!

2. What is vUE

Vue is a popular front-end MVVM framework. It is built with data-driven and componentized ideas and is one of the top three front-end frameworks along with Angular and React. Vue is lighter, high-performance, and easier to use than Angular and React. You can also take a look at the introduction of VUE and its core functions on the official website. When developing with VUE, you manipulate data, and then VUE processes it to change the DOM in a data-driven way. Here is a simple illustration

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

chestnuts

Believe that it is easy to understand, also is the input binding message this value, and then at the time of input modification, the message is changed, because of the bidirectional binding, at the same time the HTML of the page ({{message}}) modified! Ok, let’s go to the example study!

3. The TAB

Running effect

Principle analysis and implementation

This is very simple, nothing more than a click to switch the 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!

There’s only one step, and there’s no principle. I directly in the code to type comments, read the comments, you will understand!

The complete code

<meta charset="UTF-8">
<title>Title</title>Copy the code

</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;
}Copy the code

</style>

<body>

<div id=”tab”>

<div class="tab-tit"> <! If curId = 0, the first A will add a cur, if curId = 1, the second A will add a cur, and so on. <a href="javascript:;" <a href="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 equals 0, the first div is displayed and the other three are not. If curId equals 1, the second div is displayed and the other three are not. And so on -- -- > < div v - show = "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>Copy the code

</div>

</body>

<script src=”vue.min.js”></script>

<script>

new Vue({
    el: '#tab',
    data: {
        curId: 0
    },
    computed: {},
    methods: {},
    mounted: function () {
    }
})Copy the code

</script></html>

4. Total prices

Running effect

Principle analysis and implementation

First, write the layout, and introduce the VUE, prepare the VUE instance, this is not to say, 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">购物清单</h4>
    <div class="cart-product-title clearfix">
        <div class="td-check fl"><span class="check-span fl check-all"></span>全选</div>
        <div class="td-product fl">商品</div>
        <div class="td-num fl">数量</div>
        <div class="td-price fl">单价(元)</div>
        <div class="td-total fl">金额(元)</div>
        <div class="td-do fl">操作</div>
    </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">
                        <h6>【斯文】甘油&nbsp;|&nbsp;丙三醇</h6>
                        <p>品牌:韩国skc&nbsp;&nbsp;产地:韩国</p>
                        <p>规格/纯度:99.7%&nbsp;&nbsp;起定量:215千克</p>
                        <p>配送仓储:上海仓海仓储</p>
                    </div>
                    <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">
                        <h6>【斯文】甘油&nbsp;|&nbsp;丙三醇</h6>
                        <p>品牌:韩国skc&nbsp;&nbsp;产地:韩国</p>
                        <p>规格/纯度:99.7%&nbsp;&nbsp;起定量:215千克</p>
                        <p>配送仓储:上海仓海仓储</p>
                    </div>
                    <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">删除</a></td>
            </tr>
            </tbody></table>
    </div>
    <div class="cart-product-info">
        <a class="delect-product" href="javascript:;"><span></span>删除所选商品</a>
        <a class="keep-shopping" href="#"><span></span>继续购物</a>
        <a class="btn-buy fr" href="javascript:;">去结算</a>
        <p class="fr product-total">¥<span>1600</span></p>
        <p class="fr check-num"><span>2</span>件商品总计(不含运费):</p>
    </div>
    <div class="cart-worder clearfix">
        <a href="javascript:;" class="choose-worder fl"><span></span>绑定跟单员</a>
        <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 arrow in the table below

So you know what? The bottom number is going to go something like this

ProductList: [{' pro_name ':' [gentle] glycerin glycerin | ', / / product name 'pro_brand' : 'SKC, / / brand name' pro_place ':' Korea ', / / origin 'pro_purity' : '99.7%', 'pro_min / / specification: 215 kg, the minimum quantity for / /' pro_depot ':' Shanghai CangHai warehousing, / / warehouse where 'pro_num' : 3, / / the number of 'pro_img ": '.. /.. / images/ucenter/testimg. JPG ', / / picture links' pro_price ': 800}] / / the unit priceCopy the code

Prepared so much, we may think, there is still a lack of a record of whether the product is selected, but this field, although you can add in the above, but not meaningful, such as in the ordinary project there! Background data does not return this way, and the database does not have this field, which should be added by itself. The following code

New Vue ({el: '# shopping - cart, data: {productList: [{' pro_name' : '[gentle] glycerin glycerin |', / / product name 'pro_brand' : 'SKC, / / brand name' pro_place ':' Korea ', / / origin 'pro_purity' : '99.7%', 'pro_min / / specification: 215 kg, the minimum quantity for / /' pro_depot ': 'Shanghai CangHai warehousing, / / warehouse' pro_num ': 3, / / the number of' pro_img ":".. /.. / images/ucenter/testimg. JPG ', / / image links' pro_price ': 800// Unit price}]}, computed: {}, methods:{}, mounted:function () {// Select * from productList This.productlist. map(function(item){item.select=true; console.log(item)}) } })Copy the code

Step 1

In order to highlight what I have changed, I am only Posting the changes to the code so that you can easily see what I have changed by looking at the layout above. So do the following!

Click the increase and decrease button (arrow points to the place) to change the amount of the column (red box)

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 : item. Pro_img SRC = "" width =" 98 "height =" 98 "> < div class =" product - info "> < h6 > {{item. Pro_name}} < h6 > < p > brand: {{item.pro_brand}}&nbsp; &nbsp; Origin: {{item. Pro_place}} < / p > < p > specifications/purity: {{item. Pro_purity}} & have spent &nbsp; Pro_min}}</p> <p> {{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 - the text" > {{item. Pro_price. ToFixed (2)}} < / span > < / p > < / td > < td class = "td - total" > < p Class = "red - text" > $< span class = "total - the text" > {{item. Pro_price * item. Pro_num}} < / span >. 00 < / p > < / td > < td class = "td - do" > < a href="javascript:;" Class ="product-delect"> Delete </a></td> </tr>Copy the code

There you have the data for the list!

You can also see,The function of these two buttons has been realized, the amount behind will also change! Aren’t you surprised! There is nothing special here, because the input box uses the V-Model to bind the quantity (pro_num), and each button adds the event@click="item.pro_num--"And @click="item.pro_num++". For example, if pro_num is 3 at the beginning, click.pro_numIt becomes a 2. Click

.pro_numIt’s going to be 4, and then the amount is going to change because{{item.pro_price*item.pro_num}}. Whenever the value of pro_price or pro_num changes, the whole block changes, the view is refreshed, and we can see the change (vUE does this, and this is the beauty of MVVM, data-driven view changes).

Step 2

Click the column selection button (arrow points to the place), the total amount (red box) and selected product column number (blue box) and full selection (yellow box) will change (if all selected, the full selection button will automatically become full, if not all selected, the full selection button will automatically cancel the full selection)!

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

Then changeIf this recordselectforfalse, it showsOtherwise, display.

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 reversed (true->false or false->true). then:class="{'check-true':item.select}", will be based on this dataselectField to determine whether to addcheck-trueClass name, ifselectField true, add the class name, display. Otherwise, do not add the class name and display

.

And then,Select all button, whether to change. Just use a computed property here. The following code

html

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

js

Computed: {isSelectAll:function(){// Return true if the select for each item in productList is true, otherwise return false; return this.productList.every(function (val) { return val.select}); }}Copy the code

The code, I’ll explain, is that the isSelectAll defined in the evaluated property depends on productList. As soon as productList changes, isSelectAll’s return value changes, and then:class="{'check-true':isSelectAll}"Root isSelectAll return value whether to add'check-true'Class name, display the corresponding style!

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

html

<p class="fr product-total">¥<span>{{gettotal. totalPrice}}</span></p> <p class="fr" Check -num"><span>{{gettotal. totalNum}}</span>Copy the code

js

Computed: {// Test whether to select all isSelectAll:function(){// Return true if the select for each item in productList is true, otherwise return false; return this.productList.every(function (val) { return val.select}); GetTotal :function(){// Select true from productList. 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; } / / to choose a number of the product is _proList. The length, the total price is totalPrice return {totalNum: _proList length, totalPrice: totalPrice}}},Copy the code

GetTotal depends on productList. Whenever productList changes, the return value changes and the view changes too!

Step 3

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



And if you do that, you should know that if you select all or unselect all, you change the recordselect. But how do you know if the current list is full? This is cheap and does not need to be iterated through the operand (select all and deselect all). You should remember the computed properties in step 2isSelectAll(true means all, otherwise not all), just pass this into the operation function, and then operate the function, depending on the arguments, to perform all or cancel all. 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: SelectProduct :function(_isSelect){for (var I = 0, len = this.productList.length; i < len; i++) { this.productList[i].select = ! _isSelect; }}},Copy the code

Step 4

Click delete product, will delete already selected, all select button and the following total, will change! Click delete after each record to delete the current record. Select all button and the total below, will also change!

First, click Delete product, delete is already selected. You know how to do that! The productList is iterated, and if the select value is true, delete it. Then, click delete after each record to delete the current record. This is when the HTML traverses productList. Pass the index as a parameter to the operation function, and delete the productList entry based on the index parameter. Can achieve! The code is as follows! html

<! <tr v-for="(item,index) in productList"> <td class="td-check"> @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; Pro_min}}</p> <p> {{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 - the text" > {{item. Pro_price. ToFixed (2)}} < / span > < / p > < / td > < td class = "td - total" > < p Class = "red - text" > $< span class = "total - the text" > {{item. Pro_price * item. Pro_num}} < / span >. 00 < / p > < / td > < td class = "td - do" > < a href="javascript:;" Class ="product-delect" @click="deleteOneProduct(index)"> </a></td> </tr>... <a class="delect-product" href="javascript:;" @click="deleteProduct"><span></span>Copy the code

js

Function () {this.productList=this.productList.filter(function (item) {return! Item, select})}, / / delete a single product deleteOneProduct: function (index) {/ / delete productList records in the 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">购物清单</h4>
        <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)"></span>全选</div>
            <div class="td-product fl">商品</div>
            <div class="td-num fl">数量</div>
            <div class="td-price fl">单价(元)</div>
            <div class="td-total fl">金额(元)</div>
            <div class="td-do fl">操作</div>
        </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>品牌:{{item.pro_brand}}&nbsp;&nbsp;产地:{{item.pro_place}}</p>
                            <p>规格/纯度:{{item.pro_purity}}&nbsp;&nbsp;起定量:{{item.pro_min}}</p>
                            <p>配送仓储:{{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)">删除</a></td>
                </tr>
                </tbody>
            </table>
        </div>
        <div class="cart-product-info">
            <a class="delect-product" href="javascript:;" @click="deleteProduct"><span></span>删除所选商品</a>
            <a class="keep-shopping" href="#"><span></span>继续购物</a>
            <a class="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': '【斯文】甘油 | 丙三醇',//产品名称
                        'pro_brand': 'skc',//品牌名称
                        'pro_place': '韩国',//产地
                        'pro_purity': '99.7%',//规格
                        'pro_min': "215千克",//最小起订量
                        'pro_depot': '上海仓海仓储',//所在仓库
                        'pro_num': 3,//数量
                        'pro_img': '../../images/ucenter/testimg.jpg',//图片链接
                        'pro_price': 800//单价
                    },
                    {
                        'pro_name': '【斯文】甘油 | 丙三醇',//产品名称
                        'pro_brand': 'skc',//品牌名称
                        'pro_place': '韩国',//产地
                        'pro_purity': '99.7%',//规格
                        'pro_min': "215千克",//最小起订量
                        'pro_depot': '上海仓海仓储',//所在仓库
                        'pro_num': 3,//数量
                        'pro_img': '../../images/ucenter/testimg.jpg',//图片链接
                        'pro_price': 800//单价
                    },
                    {
                        'pro_name': '【斯文】甘油 | 丙三醇',//产品名称
                        'pro_brand': 'skc',//品牌名称
                        'pro_place': '韩国',//产地
                        'pro_purity': '99.7%',//规格
                        'pro_min': "215千克",//最小起订量
                        'pro_depot': '上海仓海仓储',//所在仓库
                        'pro_num': 3,//数量
                        'pro_img': '../../images/ucenter/testimg.jpg',//图片链接
                        'pro_price': 800//单价
                    }
                ]
            },
            computed: {
                //检测是否全选
                isSelectAll:function(){
                    //如果productList中每一条数据的select都为true,返回true,否则返回false;
                    return this.productList.every(function (val) { return val.select});
                },
                //获取总价和产品总件数
                getTotal:function(){
                    //获取productList中select为true的数据。
                    var _proList=this.productList.filter(function (val) { return val.select}),totalPrice=0;
                    for(var i=0,len=_proList.length;i<len;i++){
                        //总价累加
                        totalPrice+=_proList[i].pro_num*_proList[i].pro_price;
                    }
                    //选择产品的件数就是_proList.length,总价就是totalPrice
                    return {totalNum:_proList.length,totalPrice:totalPrice}
                }
            },
            methods: {
                //全选与取消全选
                selectProduct:function(_isSelect){
                    //遍历productList,全部取反
                    for (var i = 0, len = this.productList.length; i < len; i++) {
                        this.productList[i].select = !_isSelect;
                    }
                },
                //删除已经选中(select=true)的产品
                deleteProduct:function () {
                    this.productList=this.productList.filter(function (item) {return !item.select})
                },
                //删除单条产品
                deleteOneProduct:function (index) {
                    //根据索引删除productList的记录
                    this.productList.splice(index,1);
                },
            },
            mounted: function () {
                var _this=this;
                //为productList添加select(是否选中)字段,初始值为true
                this.productList.map(function (item) {
                    _this.$set(item, 'select', true);
                })
            }
        })
    </script>
    </html>  
          Copy the code

5.todoList

Running effect

Principle analysis and implementation

First, write the layout, and introduce the VUE, prepare the VUE instance, this is not to say, the code is as follows

<! DOCTYPE HTML >< HTML >< head> <meta charset=" utF-8 "> </title> </title> 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" > < h2 > small target list < / h2 > < div class = "list" > < h3 > < / h3 > < add small target input Type ="text" class="text-keyword" placeholder=" </ >< p> <input type="radio" name="chooseType" checked="true"/><label> All objects </label> <input type="radio" Name ="chooseType"/><label> <input type="radio" name="chooseType"/><label> unfinished </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 implementation function, one by one

Step 1

Type and press Enter for one more record. The transcript below will also change

First, to add records to the large input box carriage return, the input box must bind a value and a method to add records.

The code is as follows:

Then, the record below also want to change, so, the record below also want to help a value, because this record may have more than one, this value is an array, you can also see, record in addition to the name, there are records completed state, so, the binding record of this value must be an object array! The following code

Finally, record the wordsWant to change. This is just the length of the current record.

In order to highlight what I have changed, I am only Posting the changes to the code so that you can easily see what I have changed by looking at the layout above. So do the following!

The HTML code

<! <input type="text" class="text-keyword" placeholder=" placeholder" Press enter to confirm "@ keyup. 13 = 'addList' v - model =" addText "/ > < p > there are {{prolist. Length}} a target < / p > <! <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: Prolist :[{name:"HTML5",status:false}, {name:"CSS3",status:false}, {name:"vue",status:false}, {name:"react",status:false} ] }, computed:{ }, This.prolist.push ({name: this.addtext, status:false}); // After adding, empty addText this.addText=""; }}});Copy the code

Test it out, no problem

Step 2

Click toggle and the record below will change

See three options, also very simple, nothing more than three choices, one is all the goals, one is all the goals accomplished, and one is all the goals not accomplished. First, create a new variable (newList) to store proList. Instead of going through proList, we’re going through newList. Change is also change newList. Then, when all targets are selected, display all proList and assign proList to newList. And then, when you select all the targets that have been completed, display only the targets in proList whose status is true, assign the items in ProList whose status is true to newList, and finally. When all unfinished targets are selected, only the targets with status false are displayed, and the proList items with status 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: 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(){this.prolist.push({name: this.addtext, status:false}); // After adding, empty addText this.addText=""; }, chooseList(type){// if type=1, select all targets // if type=2, select all targets // if type=3, 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 which case deleting proList does not affect newList. NewList = this.proList; },}, mounted(){// Set proList to newList. Default to display all targets this.newList=this.prolist; }});Copy the code

The results

Step 3

Red close identifier, click will delete the record. Click the front button to switch the record completion state, the color also changes, the record text also changes

First click the red close icon, click will delete the record. Delete a proList entry. The previous button click will then toggle the record completion status. Change the status field of a proList record. Finally, the change of text is recorded, which is how many prolist status is false, and how many prolist status is true

The HTML code

<! {{prolist. Length}} --> <p> {{prolist. Length}} --> <p> {{prolist. {{noend==0?" All completed ": 'completed' + (prolist. Length - noend) + ', and '+ noend + article' unfinished '}} < / p >Copy the code
<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: Prolist :[{name:"HTML5",status:false}, {name:"CSS3",status:false}, {name:"vue",status:false}, {name:"react",status:false}], newList:[]}, computed attributes, return the number of unfinished objects, Noend :function(){return this.prolist.filter(function(item){return! item.status }).length; }}, methods:{addList(){this.prolist.push({name: this.addtext, status:false}); // After adding, empty 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 which case deleting proList does not affect newList. NewList = this.proList; }, }, mounted(){ this.newList=this.prolist; }});Copy the code

The results

Step 4

Double-clicking the text will bring up the input box, you can enter the text, if enter or lose focus, change the text, if ESC to restore the original text

First, double-click the input box, double-click the text, give the current li a class name (‘ eidting ‘), and then write the style. When li appears with the class name, the input field appears and the rest of the content is hidden. And then, if you hit Enter or lose focus, you change the text and all you need to do is clear the class name (‘ eidting ‘). Then the input box will be hidden and the rest of the content will be displayed! Press ESC to restore the original text, save the current content with a variable (‘ beforeEditText ‘) when the input box appears, 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

This.prolist.push ({name: this.addtext, status:false}); // After adding, empty addText this.addText=""; }, chooseList(type){// if type=1, select all targets // if type=2, select all targets // if type=3, 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 which case deleting proList does not affect newList. NewList = this.proList; }, // editBefore(name){ {name: "it", the status: false}) / / beforeEditText = "it" is this. BeforeEditText = name; }, // Edited (){// Edited, set curIndex="", so that the input box is hidden and other elements are displayed. Class ="{'eidting':curIndex===index}" class="{'eidting':curIndex===index}" // The input box uses the V-model to bind the name of the previous item (such as this one, {name:"HTML5",status:false}). When editing the input box, such as changing it to 'HTML', the name of the current item is actually changed to 'HTML', so, {name:"HTML5",status:false}} Like this ({name:"HTML",status:true}). In fact, this item in the prolist ({name:"HTML5",status:false}) will also be changed to ({name:"HTML",status:true}). Because here's an object, and there's a common stack! If you change one of them, the other one will be affected this.curIndex=""; }, // cancelEdit(val){// The input box uses the v-model to bind the name of the previous item (e.g. {name:"HTML5",status:false}). For example, if you change it to 'HTML', the name of the current item actually becomes' HTML ', so this step is to restore the original value by assigning the previously saved beforeEditText to the name property of the current item! val.name=this.beforeEditText; this.curIndex=""; }},Copy the code

The results

There is also a small detail, you may have noticed, is double click text, when the input box, you have to manually click, in order to get the focus, we want to double click, when the input box out, automatically get the focus, how to do? Custom instructions will do!

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

The HTML then invokes 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> 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" > < h2 > small target list < / h2 > < div class = "list" > < h3 > < / h3 > < add small target input Type ="text" class="text-keyword" placeholder=" @keyup.13='addList' v-model="addText"/> <! {{prolist. Length}} --> <p> {{prolist. Length}} --> <p> {{prolist. {{noend==0?" ":' done '+(prolist.length-noend)+', </p> <p> <input type="radio" name="chooseType" checked="true" @click='chooseList(1)'/><label> </label> @click='chooseList(2)'/><label> </label> @click='chooseList(3)'/><label> </label> </p> </div> <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' v-focus/> </li> </ul> </div> </body> <script SRC ="vue2.4.2.js"></script> <script type="text/javascript"> new Vue({el: "#app", data: Prolist :[{name:"HTML5",status:false}, {name:"CSS3",status:false}, {name:"vue",status:false}, {name:"react",status:false} ], newList:[], curIndex:'', beforeEditText:"" }, Noend :function(){return this.prolist.filter(function(item){return! item.status }).length; }}, methods:{addList(){this.prolist.push({name: this.addtext, status:false}); // After adding, empty addText this.addText=""; }, chooseList(type){// if type=1, select all targets // if type=2, select all targets // if type=3, 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 which case deleting proList does not affect newList. NewList = this.proList; }, // editBefore(name){ {name: "it", the status: false}) / / beforeEditText = "it" is this. BeforeEditText = name; }, // Edited (){// Edited, set curIndex="", so that the input box is hidden and other elements are displayed. Class ="{'eidting':curIndex===index}" class="{'eidting':curIndex===index}" // The input box uses the V-model to bind the name of the previous item (such as this one, {name:"HTML5",status:false}). When editing the input box, such as changing it to 'HTML', the name of the current item is actually changed to 'HTML', so, {name:"HTML5",status:false}} Like this ({name:"HTML",status:true}). In fact, this item in the prolist ({name:"HTML5",status:false}) will also be changed to ({name:"HTML",status:true}). Because here's an object, and there's a common stack! If you change one of them, the other one will be affected this.curIndex=""; }, // cancelEdit(val){// The input box uses the v-model to bind the name of the previous item (e.g. {name:"HTML5",status:false}). For example, if you change it to 'HTML', the name of the current item actually becomes' HTML ', so this step is to restore the original value by assigning the previously saved beforeEditText to the name property of the current item! val.name=this.beforeEditText; this.curIndex=""; }}, mounted(){// ProList is assigned to newList. Default to display all targets this.newList=this.prolist; }, directives:{ "focus":{ update(el){ el.focus(); }}}}); </script> </html>Copy the code

6. Summary

Well, that’s all for the three small examples! Don’t look at the article so long, in fact, are the foundation, may be my more wordy just! If you can be familiar with these small examples, I believe that vUE is also easy to do projects. Basic grammar here, with the foundation, advanced writing will not be difficult to learn! If I have something to share in the future, I will continue to share. The last old saying, if I think where write wrong, write bad, welcome to give advice!