Home  >  Q&A  >  body text

javascript - Vue newbie asking for help. v-for and v-if render multiple elements at the same level. How to change the display/hide of one of the elements individually?

I am practicing by making a todolist that can be added, deleted, and modified, imitating www.todolist.cn, and got stuck when re-editing the todo content. The official solution has not been summarized, so I am here to ask for help. the following.

Clicking on the text changes to input modification, but the effect is like this
Because my v-if is bound to the same variable, it will definitely be changed globally, but for vue My understanding is too shallow and I can’t think of effective methods.
Code: `<!DOCTYPE html>
<html lang="en">
<head>

<meta charset="UTF-8">
<title>NBtodoList</title>
<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.bootcss.com/vue/2.3.3/vue.min.js"></script>
<style>
    body{
        background: #CDCDCD;
    }
    header{
        height: 50px;
        line-height: 50px;
        background: #323232;
    }
    .headerForm label{
        color: #DDDDDD;
        font-size: 20px;
        cursor: pointer;;
    }
    .headerForm input{
        margin-top: 8px;
    }
    .h2{
        font-weight: bold;
        margin: 20px 0;
    }
    section{
    }
    li,ul,ol{
        list-style: none;
    }
    .oLi{
        height: 40px;
        background: #fff;
        border-radius: 5px;
        line-height: 40px;
        border-left: 5px solid #629A9C;
        margin-bottom: 10px;
    }
    .oLi .check{
        width: 22px;
        height: 22px;
        margin: 9px;
    }
    .oLi p{
        height: 40px;
    }
    .oLi *{
        padding: 0;
    }
    .oLi i{
        text-align: center;
        line-height: 40px;
        font-size: 18px;
    }
    .oLi span{
        cursor: pointer;
    }
    .oLi .txt{
        line-height: 50px;
        display: inline-block;
        padding-left: 5px;
    }
    ul{
        padding-left: 0;
    }
</style>

</head>
<body>

<p id="app">
    <header class="container-fluid">
        <p class="container">
            <p class="headerForm form-group center-block clearfix">
                <label for="todocontent" class="pull-left col-xs-3">ToDoList</label>
                <p class="col-xs-9 pull-right">
                    <input autofocus type="text" id="todocontent" class="form-control" v-model='todoText' v-on:keyup.enter='addTodo' placeholder="添加ToDo">
                </p>
            </p>
        </p>
    </header>
    <section class="container">
        <p class="center-block" style="padding: 0 15px">
            <my-h2 v-bind:num='noNum' status='正在进行'></my-h2>
            <ul>
                <my-li v-for='(todo,index) in todoList' v-bind:to='todo' v-on:deltodo='deltodos(index)' v-on:todook='dotoDown(index)' v-on:childrevamp="revamp" v-bind:childisrevamp="isRevamp"></my-li>
            </ul>
            <my-h2 v-bind:num='okNum' status='已经完成'></my-h2>
            <ul>
                <my-li style="opacity: .5" v-for='(oktodo,index) in oktodoList' v-bind:childchecked="checked" v-bind:okto='oktodo' v-on:deltodo='deloktodos(index)' v-on:todook='dotoUp(index)' childisrevamp="ture"></my-li>
            </ul>
        </p>
    </section>
</p>

</body>
<script>

Vue.component('my-li',{
    props:['to','okto','childchecked','childisrevamp'],
    template: '<li class="oLi"><input type="checkbox" v-model="childchecked"  v-on:change="todook" class="check col-xs-1"/><p class="pull-left col-xs-10"><span v-on:click="childrevamp" v-if="childisrevamp">{{to}}{{okto}}</span><input v-on:blur="childrevamp"  v-if="!childisrevamp" class="txt form-control"></input></p><i href="#" v-on:click="deltodo" class="pull-right col-xs-1 glyphicon glyphicon-remove"></i></li>',
    methods: {
        childAddTodo: function(){
            this.$emit('childAddTodo')
        },
        deltodo: function(){
            this.$emit('deltodo');
        },
        todook: function(){
            this.$emit('todook');
        },
        childrevamp: function(){
            this.$emit('childrevamp');
        }
    }
})
Vue.component('my-h2',{
    props: ['num','status'],
    template: '<h2 class="h2">{{status}}<span class="pull-right badge" style="margin-top: 8px;">{{num}}</span></h2>'
})
new Vue({
    el: '#app',
    data: {
        todoText: '',
        todoList: [],
        okTodoText: '',
        oktodoList: [],
        noNum: 0,
        okNum: 0,
        checked: true,
        isRevamp: true
    },
    methods: {
        addTodo: function(){
            this.todoText.trim() ? this.todoList.push((this.todoText).trim()) : alert('你输嘞不对~');
            localStorage.notodo = JSON.stringify(this.todoList);
            this.noNum = this.todoList.length;
            this.todoText = '';
        },
        deltodos: function(index){
            this.todoList.splice(index,1);
            localStorage.notodo = JSON.stringify(this.todoList);
            this.noNum = this.todoList.length;
        },
        deloktodos: function(index){
            this.oktodoList.splice(index,1);
            localStorage.oktodo = JSON.stringify(this.oktodoList);
            this.okNum = this.oktodoList.length;
        },
        dotoDown: function(index){
            this.oktodoList.push(this.todoList[index]);
            localStorage.oktodo = JSON.stringify(this.oktodoList);
            this.deltodos(index);
            this.okNum = this.oktodoList.length;
        },
        dotoUp: function(index){
            this.todoList.push(this.oktodoList[index]);
            localStorage.notodo = JSON.stringify(this.todoList);
            this.deloktodos(index);
            localStorage.oktodo = JSON.stringify(this.oktodoList);
            this.noNum = this.todoList.length;
        },
        revamp: function(){
            this.isRevamp = !this.isRevamp;
        }
    },
    created:function(){
        this.todoList = localStorage.notodo ? JSON.parse(localStorage.notodo) : [];
        this.oktodoList = localStorage.oktodo ? JSON.parse(localStorage.oktodo) : [];
        this.noNum = this.todoList.length;
        this.okNum = this.oktodoList.length;
    }
})

</script>
</html>`
Is there any way to hide only the current span and display the input after the revamp event is triggered? Ask the experts for advice!

淡淡烟草味淡淡烟草味2687 days ago1084

reply all(2)I'll reply

  • 扔个三星炸死你

    扔个三星炸死你2017-06-12 09:29:36

    this.isRevamp = !this.isRevamp;
    

    This method will show or hide all todos together,

    To target only a certain todo, you can add an isRevamp to each todo, and then it becomes:

    todo.isRevamp = !todo.isRevamp;
    

    But this requires that every todo in your data contains isRevamp at the beginning. If you want to add it dynamically, it will be more troublesome. Please see the "Responsive Principle" section in the document: https://cn.vuejs. org/v2/guide...

    But there is a simple way to deal with it: add an index variable to the data,
    roughly like this:

    <li v-for="(v,i) in list" v-show="i==index" @click="show(i)">{{v}}</li>
    
    show:function(i){
    this.index=i;
    }
    

    reply
    0
  • 高洛峰

    高洛峰2017-06-12 09:29:36

    It’s very simple, just bind a state variable to each element.

    reply
    0
  • Cancelreply