用vue開(kāi)發(fā)了一段時(shí)間炬守,針對(duì)團(tuán)隊(duì)中出現(xiàn)的問(wèn)題做一下記錄。文字表達(dá)能力不太好剂跟,大家將就看下减途,問(wèn)題大概如下:
- v-cloak屬性
- 數(shù)組更新問(wèn)題
- 對(duì)象更新問(wèn)題
- render函數(shù)使用
1. v-cloak
屬性
vue的模板建議都加上v-cloak
屬性,網(wǎng)頁(yè)加載的時(shí)候曹洽,先加載html鳍置,再加載js,網(wǎng)絡(luò)不太好的情況下送淆,頁(yè)面會(huì)看到?jīng)]有渲染的模板税产,不太美觀。
假如用戶的網(wǎng)絡(luò)不太好,2s才把js文件下載下來(lái)砖第,這里用setTimeout來(lái)模擬
下面是加了`v-cloak`的代碼撤卢,在模板元素上加`v-cloak`屬性,同時(shí)加一個(gè)樣式梧兼,
[v-cloak]{
display:none;
}
沒(méi)有渲染的模板直接不顯示給用戶放吩,當(dāng)模板渲染后,vue會(huì)把v-cloak屬性刪除羽杰,所以下面代碼運(yùn)行效果是渡紫,前2s頁(yè)面是空白的,2s后才顯示渲染后的內(nèi)容
2.數(shù)組更新問(wèn)題
代碼
<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)擊按鈕的時(shí)候惕澎,發(fā)現(xiàn)數(shù)據(jù)并沒(méi)有更新,其它vue文檔里面有說(shuō)明颜骤,哪些操作數(shù)組是可以檢測(cè)到更新(文檔鏈接)和注意事項(xiàng)(文檔鏈接)唧喉,用索引直接改變數(shù)組的值vue是不能檢測(cè)到變動(dòng)的,但是有提供解決方法忍抽,用$set
方法
items[1] = 'new2'
改成
vm.$set(vm.items, 1, 'new2')
3.對(duì)象檢測(cè)更新
<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)擊隱藏
的時(shí)候想隱藏當(dāng)前數(shù)據(jù)八孝,隱藏是用對(duì)象的isHide
屬性控制的,點(diǎn)擊的時(shí)候鸠项,我們給當(dāng)前對(duì)象添加一個(gè)isHide
屬性干跛,值為true
,但是并沒(méi)有實(shí)現(xiàn)我們需要的效果祟绊。為什么呢楼入,因?yàn)閂ue 不能檢測(cè)對(duì)象屬性的添加或刪除,那怎么整牧抽?
解決方法有兩種:
- 遍歷數(shù)據(jù)前嘉熊,給所有對(duì)象加上isHide這個(gè)屬性
- 用
$set
函數(shù)
遍歷數(shù)據(jù)前,給所有對(duì)象加上isHide這個(gè)屬性
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)
}
}
})
留個(gè)問(wèn)題給大家阎姥,代碼如下记舆,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ù)來(lái)源比較多,所以數(shù)據(jù)格式多種多樣御蒲,但題目的類型是相對(duì)固定的衣赶,基本是選擇題(單選題,多選題)厚满,判斷題府瞄,排序題,連線題等,所以我們針對(duì)這些題目做了相應(yīng)的組件遵馆,每種組件的需要的數(shù)據(jù)格式我們定義一種通用的格式鲸郊,把各種不同的數(shù)據(jù)格式轉(zhuǎn)成通用格式組件就可以復(fù)用了。那么問(wèn)題來(lái)了货邓,程序傳一組數(shù)據(jù)(試卷)進(jìn)來(lái)秆撮,我們?cè)趺锤鶕?jù)題類型的去調(diào)用相應(yīng)的組件渲染呢?用v-if换况?
題目基本類型
- 選擇題
- 排序題
題目數(shù)據(jù)中有個(gè)type
字段來(lái)用標(biāo)識(shí)題目類型
- 1 表示單選題
- 2 表示多選題
- 3 表示排序題
定義組件
選擇題
數(shù)據(jù)格式
{
title:'dan xuan ti',//標(biāo)題
type:1,//題目類型
options:['danxuan1','danxuan2','danxuan3','danxuan4'] //題目選項(xiàng)
}
單選題和多選題目其實(shí)可以用一個(gè)組件职辨,只是標(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']
})
很簡(jiǎn)單戈二,只是遍歷下數(shù)據(jù)
現(xiàn)在給了一張?jiān)嚲頂?shù)據(jù)舒裤, 怎么根據(jù)題目類型調(diào)用相應(yīng)的組件把這些數(shù)據(jù)渲染出來(lái)呢
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ù)來(lái)解決我們的問(wèn)題
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
}
}))
}
})
最后打個(gè)廣告
招前端開(kāi)發(fā)绢彤,簡(jiǎn)歷投遞:liubin#readboy.com宴卖,#替換成@假消,簡(jiǎn)歷標(biāo)注:簡(jiǎn)書(shū)