Vue開發(fā)問題總結(jié)

用vue開發(fā)了一段時間,針對團(tuán)隊(duì)中出現(xiàn)的問題做一下記錄。文字表達(dá)能力不太好,大家將就看下,問題大概如下:

  • v-cloak屬性
  • 數(shù)組更新問題
  • 對象更新問題
  • render函數(shù)使用

1. v-cloak 屬性

vue的模板建議都加上v-cloak屬性,網(wǎng)頁加載的時候,先加載html,再加載js,網(wǎng)絡(luò)不太好的情況下,頁面會看到?jīng)]有渲染的模板,不太美觀。

假如用戶的網(wǎng)絡(luò)不太好,2s才把js文件下載下來,這里用setTimeout來模擬
沒加v-cloak屬性的代碼
沒加v-cloak屬性的代碼運(yùn)行效果
下面是加了`v-cloak`的代碼,在模板元素上加`v-cloak`屬性,同時加一個樣式,
[v-cloak]{
    display:none;
}
沒有渲染的模板直接不顯示給用戶,當(dāng)模板渲染后,vue會把v-cloak屬性刪除,所以下面代碼運(yùn)行效果是,前2s頁面是空白的,2s后才顯示渲染后的內(nèi)容
加了v-cloak的代碼

2.數(shù)組更新問題

代碼

<body>
    <style type="text/css">
        [v-cloak]{
            display: none;
        }
    </style>
    <div id="app" v-cloak>
        <div v-for="item in items">
            {{item}}
        </div>
    </div>
    <button onclick="update()">更新2為new2</button>
    <script type="text/javascript" src="vue.js"></script>
    <script type="text/javascript">
        var items = [1,2,3,4,5]
        var vm = new Vue({
            el: '#app',
            data:{
                items: items
            }
        })
        function update(){
            items[1] = 'new2'
        }
    </script>
</body>

我想更新items第2項(xiàng)的值為new2,點(diǎn)擊按鈕的時候,發(fā)現(xiàn)數(shù)據(jù)并沒有更新,其它vue文檔里面有說明,哪些操作數(shù)組是可以檢測到更新(文檔鏈接)和注意事項(xiàng)(文檔鏈接),用索引直接改變數(shù)組的值vue是不能檢測到變動的,但是有提供解決方法,用$set方法

items[1] = 'new2'
改成
vm.$set(vm.items, 1, 'new2')

3.對象檢測更新

<body>
    <style type="text/css">
        [v-cloak]{
            display: none;
        }
    </style>
    <div id="app" v-cloak>
        <div v-for="(item, index) in items">
            <div v-show="!item.isHide">
                title:{{item.title}} <br/>
                content:{{item.content}}<br/>
                <button @click="hide(item)">隱藏</button>
            </div>
            <hr>
        </div>
    </div>
    <script type="text/javascript" src="vue.js"></script>
    <script type="text/javascript">
        var items = [
            {
                title:'title1',
                content:'content1'
            },{
                title:'title2',
                content:'content2'
            }
        ]
        new Vue({
            el: '#app',
            data:{
                items:items
            },
            methods:{
                hide:function(item){
                    item.isHide = true
                }
            }
        })
    </script>
</body>

點(diǎn)擊隱藏的時候想隱藏當(dāng)前數(shù)據(jù),隱藏是用對象的isHide屬性控制的,點(diǎn)擊的時候,我們給當(dāng)前對象添加一個isHide屬性,值為true,但是并沒有實(shí)現(xiàn)我們需要的效果。為什么呢,因?yàn)閂ue 不能檢測對象屬性的添加或刪除,那怎么整?
解決方法有兩種:

  • 遍歷數(shù)據(jù)前,給所有對象加上isHide這個屬性
  • $set函數(shù)

遍歷數(shù)據(jù)前,給所有對象加上isHide這個屬性

var items = [
            {
                title:'title1',
                content:'content1'
            },{
                title:'title2',
                content:'content2'
            }
        ]

        items.forEach(v=>{
            v.isHide = false
        })
        
        new Vue({
            el: '#app',
            data:{
                items:items
            },
            methods:{
                hide:function(item){
                    item.isHide = true
                }
            }
        })

$set函數(shù)

new Vue({
            el: '#app',
            data:{
                items:items
            },
            methods:{
                hide:function(item){
                    this.$set(item, 'isHide', true)
                }
            }
        })

留個問題給大家,代碼如下,1s后我用索引改變數(shù)組第2項(xiàng)的content屬性的值,能否生效

<body>
    <style type="text/css">
        [v-cloak]{
            display: none;
        }
    </style>
    <div id="app" v-cloak>
        <div v-for="(item, index) in items">
            title:{{item.title}} <br/>
            content:{{item.content}}<br/>
            <hr>
        </div>
    </div>
    <script type="text/javascript" src="vue.js"></script>
    <script type="text/javascript">
        var items = [
            {
                title:'title1',
                content:'content1'
            },{
                title:'title2',
                content:'content2'
            }
        ]
        new Vue({
            el: '#app',
            data:{
                items:items
            }
        })
        setTimeout(function(){
            items[1].content = 'newcontent'
        },1000)
    </script>
</body>

4.render函數(shù)

我們的項(xiàng)目的數(shù)據(jù)基本都是題目數(shù)據(jù),數(shù)據(jù)來源比較多,所以數(shù)據(jù)格式多種多樣,但題目的類型是相對固定的,基本是選擇題(單選題,多選題),判斷題,排序題,連線題等,所以我們針對這些題目做了相應(yīng)的組件,每種組件的需要的數(shù)據(jù)格式我們定義一種通用的格式,把各種不同的數(shù)據(jù)格式轉(zhuǎn)成通用格式組件就可以復(fù)用了。那么問題來了,程序傳一組數(shù)據(jù)(試卷)進(jìn)來,我們怎么根據(jù)題類型的去調(diào)用相應(yīng)的組件渲染呢?用v-if?


題目基本類型

  • 選擇題
  • 排序題

題目數(shù)據(jù)中有個type字段來用標(biāo)識題目類型

  • 1 表示單選題
  • 2 表示多選題
  • 3 表示排序題

定義組件

選擇題

數(shù)據(jù)格式

       {
            title:'dan xuan ti',//標(biāo)題
            type:1,//題目類型
            options:['danxuan1','danxuan2','danxuan3','danxuan4'] //題目選項(xiàng)
        }

單選題和多選題目其實(shí)可以用一個組件,只是標(biāo)題有和input的type有些不一樣

選擇題組件代碼
Vue.component('e-choice',{      
        template:`
            <div>
                <div>題目類型:{{typeName}}</div>
                <div>{{index}}. {{topic.title}}</div>
                <div v-for="(option,key) in topic.options">
                    <input :type="inputType" :name="index" />{{choiceOption(key)}}: {{option}}
                </div>
            </div>
        `,
        methods:{
            choiceOption:function(index){
                return String.fromCharCode(65+index)
            }
        },
        computed:{
            typeName:function(){
                return this.topic.type === 1? '單選題':'多選題'
            },
            inputType:function(){
                return this.topic.type === 1? 'radio':'checkbox'
            }
        },
        props:['index','topic']
    })

index 是題目在這張?jiān)嚲碇械捻樞颍?br> topic 是題目數(shù)據(jù)
單選題用radio,多選題用checkbox

單選題渲染效果
單選題渲染效果
多選題渲染效果
多選題渲染效果

排序題

數(shù)據(jù)格式

       {
            title:'pai xu ti',
            type:3,
            options:['pai xu 3','pai xu 2','pai xu 1','pai xu 4',]
        }
排序題組件代碼
Vue.component('e-sort',{
        template:`<div>
                        <div>題目類型:排序題</div>
                        <div>{{index}}. {{topic.title}}</div>
                        <blockquote>
                            <div v-for="(option,key) in topic.options">
                            {{key+1}}: {{option}}
                        </div>
                        </blockquote>
                    </div>`,
        props: ['index','topic']
    })

很簡單,只是遍歷下數(shù)據(jù)

渲染效果

現(xiàn)在給了一張?jiān)嚲頂?shù)據(jù), 怎么根據(jù)題目類型調(diào)用相應(yīng)的組件把這些數(shù)據(jù)渲染出來呢

var data = [
        {
            title:'dan xuan ti',
            type:1,
            options:['danxuan1','danxuan2','danxuan3','danxuan4']
        },
        {
            title:'pai xu ti',
            type:3,
            options:['pai xu 3','pai xu 2','pai xu 1','pai xu 4',]
        },

        {
            title:'duo xuan ti',
            type:2,
            options:['duoxuan1','duoxuan2','duoxuan3','duoxuan4']
        },
        {
            title:'pai xu ti',
            type:3,
            options:['pai xu 3','pai xu 2','pai xu 1','pai xu 4',]
        },{
            title:'dan xuan ti',
            type:1,
            options:['danxuan1','danxuan2','danxuan3','danxuan4']
        },
        {
            title:'pai xu ti',
            type:3,
            options:['pai xu 3','pai xu 2','pai xu 1','pai xu 4',]
        },
        
        {
            title:'duo xuan ti',
            type:2,
            options:['duoxuan1','duoxuan2','duoxuan3','duoxuan4']
        },
        {
            title:'pai xu ti',
            type:3,
            options:['pai xu 3','pai xu 2','pai xu 1','pai xu 4',]
        }
    ]

這里我們就可以用render函數(shù)來解決我們的問題

new Vue({
        el:'#app',
        data:{
            topics:data
        },
        render:function(createElement){
            return createElement('div', this.topics.map((v,index)=>{
                switch(v.type){
                    case 1://單選題
                    case 2://多選題
                        return createElement('e-choice',{
                                        props:{
                                            index:index + 1,
                                            topic:v
                                        }
                                    })
                        break
                    case 3://排序題
                        return createElement('e-sort',{
                                        props:{
                                            index:index + 1,
                                            topic:v
                                        }
                                    })
                        break
                    default:
                        console.error('type not implement')
                        break
                }
            }))
        }
    })
QQ20180420-125421@2x.png

最后打個廣告

招前端開發(fā),簡歷投遞:liubin#readboy.com,#替換成@,簡歷標(biāo)注:簡書

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容