鍍金池/ 問答/HTML/ vue 更改data值的時候,不知為何會其他元素會重新渲染

vue 更改data值的時候,不知為何會其他元素會重新渲染

<script type="text/x-template" id="modeProgram">

    <div>

        <div class="calendar">

            <ul class="day header">
                <li class="dayList" v-for="(m, index) in 7" v-bind:key="m.index" v-text="getWeekdayText(m)"></li>
            </ul>
            <div class="day content">
                <router-link tag="div" to="" class="dayList" v-bind:class=" m == 12 ? 'g' : null || m == 28 ? 'r' : null " v-for="(m, index) in 42" v-bind:key="index">

                    <transition name="opacity" mode="out-in">
                        <div class="text" v-if=" generateCalendar({method:'query',index:m}) ">
                            <p v-for="l in 3">21391232103809f9dsiljlaksdjlkkl</p>
                        </div>
                    </transition>
                    <transition name="opacity" mode="out-in">
                        <div class="num" v-text=" generateCalendar({method:'get',index:m}) "></div>
                    </transition>

                </router-link>
            </div>

        </div>

        <div class="snyc">

            <div class="title" v-on:click="miao = !miao">
                <span>同步與記錄</span>
                <span class="icon-more" v-bind:class="{av:miao}">
                    <span></span>
                    <span></span>
                </span>
            </div>

            <transition name="opacity" mode="out-in">
                <div v-if="miao">

                    <div class="herader">
                        <div class="tap">設備</div>
                        <div class="tap">歷史記錄</div>
                    </div>
                    <ul class="list">

                        <li class="content">

                            <div class="select">
                                <input />
                            </div>
                            <div class="images">圖片</div>
                            <div class="name">名字</div>
                            <div class="downloading">下載</div>
                            <div class="fn">操作</div>

                        </li>

                        <li class="content">

                            <div class="select">
                                <input />
                            </div>
                            <div class="images">

                            </div>
                            <div class="name"></div>
                            <div class="downloading"></div>
                            <div class="fn">
                                <button>刪除</button>
                            </div>

                        </li>

                        <li class="content">

                            <div class="select"></div>
                            <div class="images"></div>
                            <div class="name"></div>
                            <div class="downloading"></div>
                            <div class="fn">
                                <button>添加</button>
                            </div>

                        </li>

                    </ul>

                </div>
            </transition>

        </div>

    </div>

</script>
<script>

    Vue.component('mode-program', {

        template:'#modeProgram',
        data (){
            return{
                Date:{
                    year:null,
                    month:null
                },
                miao:true
            }
        },
        computed:{
            details () {
                return store.state.details.data
            },
            nowYear(){
                return this.Date.year
            },
            nowMonth(){
                return this.Date.month+1
            }
        },
        watch:{
            'Date.year':function () {
                window.dayNum = 0
            },
            'Date.month':function () {
                window.dayNum = 0
            }
        },
        created (){
            window.dayNum = 0
            this.setDate();
        },
        mounted (){
        },
        methods:{
            setDate(){

                let time = new Date()
                this.Date.year = time.getFullYear()
                this.Date.month = time.getMonth()

            },
            lastMonth:function () {

                if ( this.Date.month <= 0 ){
                    this.Date.month = 11;
                    this.lastYear();
                }else {
                    --this.Date.month;
                }

            },
            nextMonth:function () {

                if ( this.Date.month >= 11 ){
                    this.Date.month = 0;
                    this.nextYear();
                }else {
                    ++this.Date.month;
                }

            },
            lastYear:function () {
                this.Date.year <= 1970 ? this.Date.year = 1970 : --this.Date.year
            },
            nextYear:function () {
                ++this.Date.year
            },
            getWeekdayText:function(m) {

                let text
                if (m == 1){ text = '一' }
                if (m == 2){ text = '二' }
                if (m == 3){ text = '三' }
                if (m == 4){ text = '四' }
                if (m == 5){ text = '五' }
                if (m == 6){ text = '六' }
                if (m == 7){ text = '日' }

                return text

            },
            generateCalendar:function(s) {

                let method = s.method

                let time = new Date().setFullYear(this.Date.year != null ? this.Date.year : '',this.Date.month != null ? this.Date.month : '',1)

                let day = new Date( time ).getDate()

                let month = this.Date.month != null ? new Date( time ).getMonth() : new Date().getMonth()

                let year = this.Date.year != null ? new Date( time ).getFullYear() : new Date().getFullYear()

                let weekDay = this.Date.year != null ? new Date( time ).getDay() : new Date().getDay()

                weekDay == 0 ? weekDay = 7 : weekDay

                let index = s.index ? s.index : 0
                let isLeapYear = year % 4 == 0 ? [31,29,31,30,31,30,31,31,30,31,30,31] : [31,28,31,30,31,30,31,31,30,31,30,31]
                let e = {
                    1:[3,5,1,10,17,21],
                    2:[7,11,16],
                    3:[9,22,30]
                }


                if ( s.index >= weekDay && window.dayNum < isLeapYear[month] ){

                    if ( method === 'query' ){
                        return true
                    }
                    if ( method === 'get' ){
                        window.dayNum = ++window.dayNum
                        return window.dayNum
                    }



                }

            }
        }

    })

</script>

當我更改里面的miao的時候,calendar里面的getWeekdayText()和generateCalendar()會被重新調(diào)用,為什么會這樣?


經(jīng)實驗,v-if和v-show都有影響


https://jsfiddle.net/d4ffo06k/1/

在開關下面同步與記錄的時候下面日期的東西就會消失

回答
編輯回答
淺時光

個人意見:這里使用的是v-if,v-if會根據(jù)miao的值來重新渲染加載,是所有該div下的數(shù)據(jù)和視圖重新渲染,所以會再次調(diào)用方法,如果不想這樣,可以使用v-show來試試。

2017年6月23日 15:33
編輯回答
失魂人

經(jīng)過幾個小時的整理,終于找到了問題所在,雖然為什么更改那個狀態(tài)會觸發(fā)那個函數(shù)還未琢磨透,不過暫時這個方法是可行的,鏈接地址:https://jsfiddle.net/luozz/d4...

注意那個generateCalendar函數(shù)的后幾行便可,其它的你可以參考,就稍微優(yōu)化了一下,沒有具體去修改其它代碼,只是為了找到問題所在而進行的各種嘗試。

問題出現(xiàn)在了window.dayNum未在函數(shù)執(zhí)行完成之后進行置0,導致下一次觸發(fā)函數(shù)保存的數(shù)值是上一次執(zhí)行函數(shù)的最終值

希望我的回答能幫助你找到問題所在! ^_^

2017年8月30日 06:16
編輯回答
遺莣

謝邀,這很正常,你這是“一個”組件,這個組件依賴 miao ,所以 miao 變了整個組件必然跑一遍更新周期。不希望被調(diào)用就需要提示 vue 這里不需要更新,

  • template 用 computed 轉換好的數(shù)據(jù);
  • 或者劃分子組件;
  • 或者用 v-once。
2018年9月15日 02:16