用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`屬性,同時加一個樣式,
[v-cloak]{
display:none;
}
沒有渲染的模板直接不顯示給用戶,當(dāng)模板渲染后,vue會把v-cloak屬性刪除,所以下面代碼運(yùn)行效果是,前2s頁面是空白的,2s后才顯示渲染后的內(nèi)容

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
}
}))
}
})

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