ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Vue.js] 2021-07-12
    Web/Vue.js 2021. 7. 12. 12:33



    OrderList1.vue

    <template>
        <div>
            <table class="table">
                <tr v-for="(item, idx) in items" v-bind:key="item.no">
                    <td>
                        <div class="form-check">
                            <input class="form-check-input" type="checkbox" v-bind:value="idx" id="flexCheckDefault" v-model="chks">
                            <label class="form-check-label" for="flexCheckDefault">{{item.no}}</label>
                        </div>
                        <div class="form-check">
                            <input class="form-check-input" type="checkbox" v-bind:value="idx" id="flexCheckDefault1" v-model="chks1[idx]">
                            <label class="form-check-label" for="flexCheckDefault1">{{item.no}}</label>
                        </div>
                    </td>
                    <td>{{item.name}}</td>
                    <td>{{item.price}}</td>
                    <td>{{item.cnt}}</td>
                    <td>{{item.sum}}</td>
                </tr>
                <tr>
                    <td>합계</td>
                    <td></td>
                    <td>{{addPrice}}</td>
                    <td>{{addCnt()}}</td>
                </tr>
            </table>    
        </div>
    </template>
    
    <script>
        export default {
            name: 'OrderList1',
            watch:{
                chks: {
                    handler(){
                        for(let item of this.items){
                            item['sum'] = 0;
                        }
                        for(let idx of this.chks){
                            this.items[idx].sum = this.items[idx].price * this.items[idx].cnt;
                        }
                    }
                },
                chks1: {
                    deep: true, //깊이있는 변화 감지
                    handler(){
                        console.log(this.chks1);
                        for(let i = 0; i < this.chks1.length; i++){
                            if(this.chks1[i] === true){
                                this.items[i]['sum'] = this.items[i].price * this.items[i].cnt;
                            }else{
                                this.items[i]['sum'] = 0;
                            }
                        }
                    }
                }
            },
            computed: {
                addPrice(){
                    console.log('computed');
                    let sum = 0;
                    for(let tmp of this.items){
                        sum += tmp.price;
                    }
                    return sum;
                }
            },
            methods: {
                addCnt(){
                    console.log('methods');
                    let sum = 0;
                    for(let tmp of this.items){
                        sum += tmp.cnt;
                    }
                    return sum;
                }
            },
            created() {
                console.log('created');
                const result = [
                    {no:1, name:'a', price:1230, cnt:2},
                    {no:2, name:'b', price:1240, cnt:3},
                    {no:3, name:'c', price:1250, cnt:4}
                ];
                this.items = result;
    
                for(let i = 0; i < this.items.length; i++){
                    this.items[i]['sum'] = 0;
                    this.chks1[i] = false;
                }
    
            },
            mounted() {
                console.log('mounted');
            },        
            data() { //state 변수 설정
                console.log('data');
                return{
                    items: [],
                    chks: [],
                    chks1: []
                }
            },
        }
    </script>
    
    <style scoped>
    
    </style>
    • watch의 경우 onchange와 마찬가지로 객체의 상태 변화가 일어날 때 자동으로 호출이 된다. 위 예제는 체크박스에 체크가 되면 아이템의 가격과 수량을 곱하여 테이블에 출력한다.
    • chks와 chks1은 차이가 있다. 그 차이는 가변길이의 리스트와 정해진 길이의 리스트이다. chks1의 경우 item의 갯수만큼 false로 초기화를 하는 반면에 chks는 체크가 될 경우 리스트에 값이 들어오게 된다.
    • chks의 경우 체크가 된 순서대로 리스트에 들어오게 되고 이는 순서를 보장할 수 없게 된다.
    • 위의 문제를 해결하기 위해 chks1에는 false값을 저장하고 체크가 된 인덱스에 true값을 저장했는데 이렇게 할 경우 메모리 낭비가 발생할 수 있다는 것을 확인했다.

     

    OrderList2.vue

    <template>
        <div class="container">
            <table class="table">
                <tr v-for="(item) in items" v-bind:key="item.no">
                    <td>{{item.no}}</td>
                    <td>{{item.name}}</td>
                    <td>{{item.price}}</td>
                    <td>
                        <select v-model.number="item.opt">
                            <option v-for="num in item.cnt" v-bind:key="num" >{{num}}</option>
                        </select>
                    </td>
                    <td>{{item.sum}}</td>
                </tr>
            </table>    
        </div>
    </template>
    
    <script>
        export default {
            name: 'OrderList2',
            data(){
                return{
                    items : [],
                }
    
            },
            created(){
                const result = [
                    {no:1, name:'a', price:1230, cnt:10},
                    {no:2, name:'b', price:1240, cnt:10},
                    {no:3, name:'c', price:1250, cnt:10}
                ];
                this.items = result;
    
                for(let i = 0; i < this.items.length; i++){
                    this.items[i]['opt'] = 1;
                    this.items[i]['sum'] = this.items[i]['price'] * this.items[i]['opt'];
                }
            },
            mounted(){
                
            },
            watch : {
                items:{
                    deep:true,
                    handler(){
                        for(let i in this.items){
                            this.items[i]['sum'] = this.items[i]['price'] * this.items[i]['opt'];
                        }
                    }
                }
            },
            methods : {
    
            }
        }
    </script>
    
    <style scoped>
    
    </style>
    • 위 예제는 아이템의 갯수를 가격에 곱하여 화면에 출력하는것으로 동작방식은 동일하다.

    'Web > Vue.js' 카테고리의 다른 글

    [Vue.js] 2021-07-07  (0) 2021.07.07
    [Vue.js] 2021-07-05  (0) 2021.07.05

    댓글

[Everything's gonna be fine]