8000 feat: updated list-view to use the new v-template · tMathaiou/nativescript-vue@5a9e377 · GitHub
[go: up one dir, main page]

Skip to content 8000

Commit 5a9e377

Browse files
committed
feat: updated list-view to use the new v-template
1 parent 51d2ca4 commit 5a9e377

File tree

4 files changed

+125
-182
lines changed

4 files changed

+125
-182
lines changed

platform/nativescript/compiler/modules/scopedSlots.js

Lines changed: 3 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,6 @@
1-
import { normalizeElementName } from '../../element-registry'
2-
3-
function preTransformNode(el, options) {
4-
if (el.tag === 'template') {
5-
let name = el.attrsMap.name
6-
7-
if (name) {
8-
el.attrsMap['slot'] = name
9-
el.attrsList.push({
10-
name: 'slot',
11-
value: name
12-
})
13-
}
14-
15-
let isListView = normalizeElementName(el.parent.tag) === 'listview'
16-
let scope = el.attrsMap.scope
17-
if (scope && isListView) {
18-
delete el.attrsMap.scope
19-
el.attrsList = el.attrsList.filter(attr => attr.name !== 'scope')
20-
21-
el.attrsMap['slot-scope'] = scope
22-
el.attrsList.push({
23-
name: 'slot-scope',
24-
value: scope
25-
})
26-
}
1+
function preTransformNode(el) {
2+
if (el.parent && el.parent.tag === 'v-template') {
3+
el.slotScope = 'item'
274
}
285
}
296

platform/nativescript/runtime/components/list-view.js

Lines changed: 43 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,40 @@
1-
const VUE_VIEW = '__vueVNodeRef__'
1+
import { VUE_VIEW } from './v-template'
22

33
export default {
44
name: 'list-view',
5-
6-
template: `<native-list-view
7-
ref="listView"
8-
@itemLoading="onItemLoading"
9-
@itemTap="onItemTap"
10-
@loaded="onLoaded"
11-
@unloaded="onUnloaded"
12-
@loadMoreItems="onLoadMoreItems">
13-
</native-list-view>`,
14-
155
props: {
166
items: {
177
type: Array,
188
required: true
199
},
20-
templateSelector: {
21-
type: Function,
22-
default: () => 'default'
23-
},
2410
separatorColor: {
2511
type: String
2612
}
2713
},
2814

29-
created() {
30-
this._templateMap = new Map()
31-
},
32-
33-
mounted() {
34-
this.setupTemplates()
35-
36-
this.$refs.listView.setAttribute('items', this.items)
37-
38-
if (this.separatorColor) {
39-
this.$refs.listView.setAttribute('separatorColor', this.separatorColor)
40-
}
15+
render(h) {
16+
return h(
17+
'native-list-view',
18+
{
19+
ref: 'listView',
20+
on: {
21+
itemLoading: this.onItemLoading,
22+
itemTap: args =>
23+
this.$emit(
24+
'itemTap',
25+
Object.assign({ item: this.items[args.index] }, args)
26+
),
27+
loaded: args => this.$emit('loaded', args),
28+
unloaded: args => this.$emit('unloaded', args),
29+
loadMoreItems: args => this.$emit('loadMoreItems', args)
30+
},
31+
domProps: {
32+
items: this.items,
33+
separatorColor: this.separatorColor
34+
}
35+
},
36+
this.$slots.default
37+
)
4138
},
4239

4340
watch: {
@@ -50,99 +47,35 @@ export default {
5047
}
5148
},
5249

53-
methods: {
54-
onItemTap(args) {
55-
this.$emit(
56-
'itemTap',
57-
Object.assign({ item: this.items[args.index] }, args)
58-
)
59-
},
60-
61-
onLoaded(args) {
62-
this.$emit('loaded', args)
63-
},
64-
65-
onUnloaded(args) {
66-
this.$emit('unloaded', args)
67-
},
68-
69-
onLoadMoreItems(args) {
70-
this.$emit('loadMoreItems', args)
71-
},
72-
73-
setupTemplates() {
74-
const self = this
75-
const slots = Object.keys(this.$scopedSlots)
76-
77-
slots.forEach(slotName => {
78-
const keyedTemplate = {
79-
key: slotName,
80-
createView() {
81-
let vnode = self.getItemTemplate('', 0)
82-
vnode.elm.nativeView[VUE_VIEW] = vnode
83-
return vnode.elm.nativeView
84-
}
85-
}
86-
this._templateMap.set(slotName, keyedTemplate)
87-
})
88-
89-
this.setItemTemplates()
90-
},
91-
92-
setItemTemplates() {
93-
const templates = []
94-
this._templateMap.forEach(value => {
95-
templates.push(value)
96-
})
97-
98-
this.$refs.listView.setAttribute('_itemTemplatesInternal', templates)
99-
100-
if (typeof this.templateSelector === 'function') {
101-
this.$refs.listView.setAttribute(
102-
'_itemTemplateSelector',
103-
(item, index, items) => {
104-
return this.templateSelector(new ItemContext(item, index))
105-
}
106-
)
107-
}
108-
},
50+
mounted() {
51+
this.$refs.listView.setAttribute('items', this.items)
52+
this.$refs.listView.setAttribute(
53+
'_itemTemplatesInternal',
54+
this.$templates.getKeyedTemplates()
55+
)
56+
this.$refs.listView.setAttribute('_itemTemplateSelector', (
57+
item,
58+
index /*,items*/
59+
) => {
60+
return this.$templates.selectorFn(new ItemContext(item, index))
61+
})
62+
},
10963

64+
methods: {
11065
onItemLoading(args) {
11166
const index = args.index
11267
const items = args.object.items
68+
11369
const currentItem =
11470
typeof items.getItem === 'function'
11571
? items.getItem(index)
11672
: items[index]
11773

118-
let vnode
119-
if (args.view) {
120-
vnode = args.view[VUE_VIEW]
121-
122-
if (!vnode) {
123-
console.log('Cant reuse view...')
124-
}
125-
}
126-
127-
vnode = this.getItemTemplate(currentItem, index, vnode)
128-
args.view = vnode.elm.nativeView
129-
args.view[VUE_VIEW] = vnode
130-
},
131-
132-
getItemTemplate(item, index, oldVnode) {
133-
let context = new ItemContext(item, index)
134-
let template = 'default'
135-
if (typeof this.templateSelector === 'function') {
136-
template = this.templateSelector(context)
137-
}
138-
//
139-
// let slot = this.$scopedSlots[template] ? this.$scopedSlots[template] : this.$scopedSlots.default
140-
// let vnode = slot(context)[0]
141-
// this.__patch__(oldVnode, vnode)
142-
//
143-
// return vnode
74+
const context = new ItemContext(currentItem, index)
75+
const name = args.object._itemTemplateSelector(context, index, items)
14476

145-
return this.$renderTemplate(template, context, oldVnode)
77+
let oldVnode = args.view && args.view[VUE_VIEW]
78+
args.view = this.$templates.patchTemplate(name, context, oldVnode)
14679
}
14780
}
14881
}

platform/nativescript/runtime/components/v-template.js

Lines changed: 43 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
import { cloneVNode } from 'core/vdom/vnode'
21
import { patch } from '../patch'
32

3+
export const VUE_VIEW = '__vueVNodeRef__'
4+
45
export default {
56
name: 'v-template',
67

@@ -15,16 +16,16 @@ export default {
1516
}
1617
},
1718

18-
created() {
19-
if (!this.$slots.default) {
19+
mounted() {
20+
if (!this.$scopedSlots.default) {
2021
return
2122
}
2223

2324
this.$parent.$templates = this.$parent.$templates || new TemplateBag()
2425
this.$parent.$templates.registerTemplate(
2526
this.$props.name,
2627
this.$props.if,
27-
this.$slots.default[0]
28+
this.$scopedSlots.default
2829
)
2930
},
3031

@@ -36,12 +37,12 @@ export class TemplateBag {
3637
this._templateMap = new Map()
3738
}
3839

39-
registerTemplate(name, condition, vnode) {
40+
registerTemplate(name, condition, scopedFn) {
4041
this._templateMap.set(name, {
4142
condition,
4243
conditionFn: this.getConditionFn(condition),
43-
vnode,
44-
keyedTemplate: new VueKeyedTemplate(name, vnode)
44+
scopedFn,
45+
keyedTemplate: new VueKeyedTemplate(name, scopedFn)
4546
})
4647
}
4748

@@ -68,19 +69,51 @@ export class TemplateBag {
6869
const { keyedTemplate } = this._templateMap.get(name)
6970
return keyedTemplate
7071
}
72+
73+
patchTemplate(name, context, oldVnode) {
74+
const { scopedFn } = this._templateMap.get(name)
75+
76+
return patch(oldVnode, scopedFn(context)).nativeView
77+
}
78+
79+
getAvailable() {
80+
return Array.from(this._templateMap.keys())
81+
}
82+
83+
getKeyedTemplates() {
84+
return Array.from(this._templateMap.values()).map(
85+
({ keyedTemplate }) => keyedTemplate
86+
)
87+
}
7188
}
7289

7390
export class VueKeyedTemplate /* implements KeyedTemplate */ {
74-
constructor(key, vnode) {
91+
constructor(key, scopedFn) {
7592
this._key = key
76-
this._vnode = vnode
93+
this._scopedFn = scopedFn
7794
}
7895

7996
get key() {
8097
return this._key
8198
}
8299

83100
createView() {
84-
return patch(null, cloneVNode(this._vnode)).nativeView
101+
const vnode = this._scopedFn(deepProxy({}))
102+
const nativeView = patch(null, vnode).nativeView
103+
nativeView[VUE_VIEW] = vnode
104+
105+
console.log('CREATE_NEW_VIEW')
106+
return nativeView
85107
}
86108
}
109+
110+
function deepProxy(object, depth = 0) {
111+
return new Proxy(object, {
112+
get() {
113+
if (depth > 10) {
114+
throw new Error('deep proxy over 10 deep.')
115+
}
116+
return deepProxy({}, depth + 1)
117+
}
118+
})
119+
}

0 commit comments

Comments
 (0)
0