Skip to content

Commit aba6fb8

Browse files
committed
+ Update directive handler.
1 parent 6115559 commit aba6fb8

File tree

9 files changed

+255
-65
lines changed

9 files changed

+255
-65
lines changed

README.md

Lines changed: 107 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -78,21 +78,66 @@ Please read the section below.
7878

7979
### Passing Value
8080

81+
#### Setup
82+
8183
```tsx
82-
// In setup.
83-
<button disabled={isDisabledRef.value}>Wow such a button</button>
84+
defineComponent({
85+
setup () {
86+
const isDisabledRef = ref(false)
87+
return () => (
88+
<button disabled={isDisabledRef.value}>Wow such a button</button>
89+
)
90+
}
91+
})
92+
```
93+
94+
#### Render function
95+
96+
```tsx
97+
Vue.extend({
98+
data () {
99+
return {
100+
isDisabled: false
101+
}
102+
},
103+
render () {
104+
return (
105+
<button disabled={this.isDisabled}>Very button</button>
106+
)
107+
}
108+
})
84109

85-
// In render function.
86-
<button disabled={this.isDisable}>Very button</button>
87110
```
88111

89112
### On
90113

114+
#### Setup
115+
116+
```tsx
117+
setup () {
118+
const onClick = () => {}
119+
return () => (
120+
<button onClick={onClick}>Click me</button>
121+
)
122+
}
123+
```
124+
125+
#### Render function
126+
91127
```tsx
92-
<button onClick={onClick}>Click me</button>
93-
<MyComponent onTrigger={onTrigger} />
128+
Vue.extend({
129+
methods: {
130+
onClick () {}
131+
},
132+
render () {
133+
return <button onClick={this.onClick}>Click me</button>
134+
}
135+
})
136+
```
137+
138+
#### Using "on" object to assign multiple events for once
94139

95-
// Using "on" to assign multiple events for once.
140+
```tsx
96141
<div on={{
97142
click: onClick,
98143
focus: onFocus,
@@ -108,10 +153,16 @@ Please read the section below.
108153

109154
Native is only available for Vue components.
110155

111-
### Rendering HTML
156+
### Rendering HTML or text
112157

113158
```tsx
114-
<div innerHTML={'<h1>Title</h1>'}></div>
159+
// Setting HTML.
160+
<div v-html={htmlStrRef.value}></div> // Using Vue directive.
161+
<div innerHTML='<h1>Title</h1>'></div> // Using dom prop.
162+
163+
// Setting text.
164+
<div v-text={this.displayText}></div> // Using Vue directive.
165+
<div textContent={'Very Vue'}></div> // Using dom prop.
115166
```
116167

117168
### HTML / Component ref
@@ -226,6 +277,51 @@ Output:
226277
</div>
227278
```
228279

280+
### Built-in directives
281+
282+
#### Setup
283+
284+
```tsx
285+
defineComponent({
286+
setup () {
287+
const isDisplayRef = ref(false)
288+
const textContentRef = ref('John Smith')
289+
const htmlContentRef = ref('<h1>John Smith</h1>')
290+
291+
return () => (
292+
<div>
293+
<div v-show={isDisabledRef.value}>Page content</div>
294+
<div v-text={textContentRef.value}></div>
295+
<div v-html={htmlContentRef.value}></div>
296+
</div>
297+
)
298+
}
299+
})
300+
```
301+
302+
#### Render function
303+
304+
```tsx
305+
Vue.extend({
306+
data () {
307+
return {
308+
isDisplay: false,
309+
textContent: 'John Smith',
310+
htmlContent: '<h1>John Smith</h1>'
311+
}
312+
},
313+
render () {
314+
return (
315+
<div>
316+
<div v-show={this.isDisplay}>Page content</div>
317+
<div v-text={this.textContent}></div>
318+
<div v-html={this.htmlContent}></div>
319+
</div>
320+
)
321+
}
322+
})
323+
```
324+
229325
### v-model
230326

231327
It only supports using `v-model` on **HTML elements**, for now you cannot use v-model on Vue component. So please use `value` and `onUpdate` separately.
@@ -236,9 +332,9 @@ It only supports using `v-model` on **HTML elements**, for now you cannot use v-
236332
import ref from '@vue/composition-api'
237333
import Vue from 'vue'
238334

239-
// In composition API
335+
// Setup.
240336
const Example = defineComponent({
241-
setup (_, { refs }) {
337+
setup () {
242338
const nameRef = ref('')
243339
return () => (
244340
<div>
Lines changed: 39 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,24 @@ import type { Ref } from '@vue/composition-api'
33
import { paramCase } from 'change-case'
44
import { checkIsRefObj, isBoolean, isNumber, isString } from '../utils'
55
import { getCurrentInstance } from '../runtime'
6+
import { dealWithVModel } from './v-model'
7+
import { TagType } from '../type'
8+
import { dealWithVText } from './v-text'
9+
import { dealWithVHTML } from './v-html'
610

7-
// v-xxx-xxx:a.b.c => {
8-
// name: 'xxx-xxx',
9-
// argument: 'a',
10-
// modifiers: { a: true, b: true, c: true }
11-
// }
11+
const checkIsVModel = (key: string): key is 'v-model' | 'vModel' => /^v(-m|M)odel$/.test(key)
12+
const checkIsVText = (key: string): key is 'v-text' | 'vText' => /^v(-t|T)ext$/.test(key)
13+
const checkIsVHTML = (key: string): key is 'v-html' | 'vHtml' => /^v(-h|H)tml$/.test(key)
14+
15+
/**
16+
* v-show:a.b.c => {
17+
* name: 'show',
18+
* argument: 'a',
19+
* modifiers: { a: true, b: true, c: true }
20+
* }
21+
*
22+
* @param key
23+
*/
1224
const getDirectiveInfo = (key: string) => {
1325
key = key.replace(/^v-?/, '') // xxx-xxx, xxxXxx:a.b.c
1426
const [name, args] = key.split(':') // ['xxx-xxx', 'a.b.c']
@@ -35,46 +47,42 @@ const getDirectiveInfo = (key: string) => {
3547
}
3648
}
3749

38-
const getDirValue = (directiveRawValue: string | Ref<string>) => {
39-
if (checkIsRefObj(directiveRawValue)) {
40-
return directiveRawValue.value
41-
}
42-
43-
if (isBoolean(directiveRawValue) || isNumber(directiveRawValue)) {
44-
return directiveRawValue
45-
}
46-
47-
const isVariableName = /^[a-zA-Z_$]([\d\w$]+)?$/.test(directiveRawValue)
48-
if (isVariableName) {
49-
const vm = getCurrentInstance()
50-
return vm[directiveRawValue]
51-
}
52-
53-
const floatValue = parseFloat(directiveRawValue)
54-
if (!isNaN(floatValue)) {
55-
return floatValue
56-
}
57-
58-
// Array, function, object, null, undefined, ect.
59-
return directiveRawValue
60-
}
61-
6250
const dealWithDirective = (
51+
tag: TagType,
6352
key: string, // v-xxx-xxx, vXxxXxx:a.b.c
6453
vNodeData: VNodeData,
6554
config: {
6655
children?: VNodeChildren
6756
[props: string]: any
68-
} = {}
57+
} = {},
58+
isHTMLElement: boolean
6959
) => {
7060
vNodeData.directives = vNodeData.directives || []
7161

62+
// v-model.
63+
if (checkIsVModel(key)) {
64+
dealWithVModel(tag, config[key], config, vNodeData, isHTMLElement)
65+
return
66+
}
67+
68+
// v-text.
69+
if (checkIsVText(key)) {
70+
dealWithVText(vNodeData, config[key])
71+
return
72+
}
73+
74+
// v-html.
75+
if (checkIsVHTML(key)) {
76+
dealWithVHTML(vNodeData, config[key])
77+
return
78+
}
79+
7280
const directiveInfo = getDirectiveInfo(key)
7381
const directiveRawValue = config[key] as string | Ref<string>
7482

7583
const directive: VNodeDirective = {
7684
name: directiveInfo.name,
77-
value: getDirValue(directiveRawValue),
85+
value: directiveRawValue,
7886
expression: isString(directiveRawValue) ? directiveRawValue : undefined,
7987
arg: directiveInfo.argument,
8088
modifiers: directiveInfo.modifiers

lib/directives/v-html.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { VNodeData } from 'vue'
2+
3+
const dealWithVHTML = (
4+
vNodeData: VNodeData,
5+
bindingValue: unknown
6+
) => {
7+
vNodeData.domProps.innerHTML = bindingValue
8+
}
9+
10+
export {
11+
dealWithVHTML
12+
}
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,11 @@ type vModelBinding = string |
1414

1515
const dealWithVModel = (
1616
tag: TagType,
17-
key: 'v-model' | 'vModel',
17+
bindingExpression: vModelBinding,
1818
config: ConfigType,
1919
vNodeData: VNodeData,
2020
isHTMLElement: boolean
2121
) => {
22-
const bindingExpression = config[key] as vModelBinding
2322
let bindingTarget: string | Ref<unknown>
2423
// let argument: string | undefined
2524
let modifiers: string[] = []

lib/directives/v-text.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { VNodeData } from 'vue'
2+
3+
const dealWithVText = (
4+
vNodeData: VNodeData,
5+
bindingValue: unknown
6+
) => {
7+
vNodeData.domProps.textContent = bindingValue
8+
}
9+
10+
export {
11+
dealWithVText
12+
}

lib/jsx.ts

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,12 @@ import {
1212
checkKeyIsScopedSlots,
1313
checkKeyIsSlot,
1414
checkKeyIsStyle,
15-
checkKeyIsVModel,
1615
isArray,
1716
isUndefined,
1817
removeNativeOn,
1918
removeOn, checkKeyIsRef
2019
} from './utils'
21-
import { dealWithVModel } from './modules/v-model'
22-
import { dealWithDirective } from './modules/directive'
20+
import { dealWithDirective } from './directives'
2321
import { ConfigType, TagType } from './type'
2422
import { getCurrentInstance } from './runtime'
2523

@@ -105,21 +103,15 @@ const jsx = function (
105103
continue
106104
}
107105

108-
// v-model, vModel.
109-
if (checkKeyIsVModel(key)) {
110-
dealWithVModel(tag, key, config, vNodeData, isHTMLElement)
111-
continue
112-
}
113-
114106
// ref.
115107
if (checkKeyIsRef(key)) {
116108
vNodeData.ref = value
117109
continue
118110
}
119111

120-
// v-dir, vDir
112+
// v-xxx, vXxx
121113
if (checkKeyIsVueDirective(key)) {
122-
dealWithDirective(key, vNodeData, config)
114+
dealWithDirective(tag, key, vNodeData, config, isHTMLElement)
123115
continue
124116
}
125117

@@ -139,15 +131,17 @@ const jsx = function (
139131
}
140132
}
141133

134+
const children = isArray(config.children) ? config.children : [config.children]
135+
142136
// Check if it is JSXS function.
143137
const isJsxsFunc = typeof tag === 'function' && isUndefined((tag as any).cid)
144138
if (isJsxsFunc) {
145139
return h({
146140
render: tag as any
147-
})
141+
}, vNodeData, children)
148142
}
149143

150-
return h(tag, vNodeData, isArray(config.children) ? config.children : [config.children])
144+
return h(tag, vNodeData, children)
151145
}
152146

153147
export {

lib/utils.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ const checkKeyIsSlot = (key: string) => key === 'slot'
4444
const checkKeyIsScopedSlots = (key: string) => key === 'scopedSlots'
4545
const checkKeyIsKey = (key: string) => key === 'key'
4646
const checkKeyIsNativeOn = (key: string) => NATIVE_ON_REGEXP.test(key)
47-
const checkKeyIsVModel = (key: string): key is 'v-model' | 'vModel' => /^v(-m|M)odel$/.test(key)
4847
const checkKeyIsVueDirective = (key: string) => /^v(-|[A-Z])/.test(key)
4948
const checkKeyIsRef = (key: string) => key === 'ref'
5049
const checkIsInputOrTextarea = (target: unknown): target is 'input' | 'textarea' => target === 'input' || target === 'textarea'
@@ -87,7 +86,6 @@ export {
8786
checkKeyIsRef,
8887
checkIsRefObj,
8988

90-
checkKeyIsVModel,
9189
checkKeyIsVueDirective,
9290
checkIsInputOrTextarea,
9391

0 commit comments

Comments
 (0)