Skip to content
This repository was archived by the owner on Jun 10, 2018. It is now read-only.

Commit 15a5ec5

Browse files
committed
initial commit
1 parent 111bacb commit 15a5ec5

17 files changed

+7586
-1
lines changed

.babelrc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"presets": [
3+
["env", { "modules": false }]
4+
],
5+
"env": {
6+
"test": {
7+
"presets": [
8+
["env", { "targets": { "node": "current" }}]
9+
]
10+
}
11+
}
12+
}

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
node_modules
2+
coverage/

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2018 方剑成
3+
Copyright (c) 2018 fjc0k <[email protected]>
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

README.md

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# vue-better-sync
2+
3+
Make it easier for props to enable two-way binding by `v-model` or `.sync`.
4+
5+
## Install
6+
7+
```shell
8+
yarn add vue-better-sync
9+
```
10+
CDN:
11+
[UNPKG](https://unpkg.com/vue-better-sync/)
12+
|
13+
[jsDelivr](https://cdn.jsdelivr.net/npm/vue-better-sync/)
14+
(available as `window.VueBetterSync`)
15+
16+
17+
## Usage
18+
19+
`prompt.vue`:
20+
```html
21+
<template>
22+
<div
23+
v-show="actualVisible"
24+
@click.self="syncVisible(!actualVisible)">
25+
<input v-model="actualValue"></input>
26+
</div>
27+
</template>
28+
29+
<script>
30+
import VueBetterSync from 'vue-better-sync'
31+
export default {
32+
name: 'prompt',
33+
mixins: [
34+
VueBetterSync({
35+
prop: 'text', // model prop, default: value
36+
event: 'change' // model event, default: input
37+
})
38+
],
39+
props: {
40+
text: String,
41+
visible: {
42+
type: Boolean,
43+
sync: true // an .sync prop?
44+
}
45+
}
46+
}
47+
</script>
48+
```
49+
50+
`main.vue`:
51+
```html
52+
<template>
53+
<div>
54+
{{ text }} | {{ visible }}<hr />
55+
<prompt
56+
v-model="text"
57+
:visible.sync="visible"
58+
></prompt>
59+
</div>
60+
</template>
61+
62+
<script>
63+
import prompt from './prompt.vue'
64+
export default {
65+
name: 'main',
66+
components: { prompt },
67+
data: () => ({
68+
text: 'hello',
69+
visible: true
70+
})
71+
}
72+
</script>
73+
```

dist/vue-better-sync.cjs.js

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
/*!
2+
* vue-better-sync v1.0.1
3+
* (c) 2018-present fjc0k <[email protected]>
4+
* Released under the MIT License.
5+
*/
6+
'use strict';
7+
8+
var cache = Object.create(null);
9+
var camelCase = (function (word) {
10+
if (!cache[word]) {
11+
cache[word] = word.replace(/-([a-z])/g, function (_, char) { return char.toUpperCase(); });
12+
}
13+
14+
return cache[word];
15+
});
16+
17+
var X_DATA_PROPS = '_DATA_PROPS_';
18+
var X_PROP_CHANGED_BY_PARENT = 1;
19+
var X_PROP_CHANGED_BY_PROXY = 2;
20+
var index = (function (ref) {
21+
if ( ref === void 0 ) ref = {};
22+
var prop = ref.prop; if ( prop === void 0 ) prop = 'value';
23+
var event = ref.event; if ( event === void 0 ) event = 'input';
24+
25+
return ({
26+
model: {
27+
prop: prop,
28+
event: event
29+
},
30+
31+
data: function data() {
32+
var this$1 = this;
33+
34+
var props = this.$options[X_DATA_PROPS] || {};
35+
return Object.keys(props).reduce(function (data, proxy) {
36+
data[proxy] = this$1[props[proxy]];
37+
return data;
38+
}, {});
39+
},
40+
41+
beforeCreate: function beforeCreate() {
42+
var ctx = this.$options;
43+
if (!ctx.props) { return; }
44+
ctx[X_DATA_PROPS] = {};
45+
ctx.methods = ctx.methods || {};
46+
ctx.watch = ctx.watch || {};
47+
Object.keys(ctx.props).forEach(function (propName) {
48+
var ref = ctx.props[propName];
49+
var isSync = ref.sync;
50+
var isModel = prop === propName;
51+
if (!isModel && !isSync) { return; }
52+
var PropName = camelCase(("-" + propName));
53+
var proxy = "actual" + PropName;
54+
var syncMethod = "sync" + PropName;
55+
var directSyncMethod = "sync" + PropName + "Directly";
56+
ctx[X_DATA_PROPS][proxy] = propName;
57+
58+
ctx.methods[directSyncMethod] = function (newValue, oldValue, propChangedBy) {
59+
if (oldValue !== newValue) {
60+
if (propChangedBy !== X_PROP_CHANGED_BY_PROXY) {
61+
this[proxy] = newValue;
62+
}
63+
64+
if (propChangedBy !== X_PROP_CHANGED_BY_PARENT) {
65+
if (isModel) {
66+
this.$emit(event, newValue, oldValue);
67+
}
68+
69+
if (isSync) {
70+
this.$emit(("update:" + propName), newValue, oldValue);
71+
}
72+
}
73+
}
74+
};
75+
76+
ctx.methods[syncMethod] = function (newValue) {
77+
this[proxy] = newValue;
78+
};
79+
80+
ctx.watch[propName] = function (newValue, oldValue) {
81+
if (newValue !== oldValue) {
82+
this[directSyncMethod](newValue, oldValue, X_PROP_CHANGED_BY_PARENT);
83+
}
84+
};
85+
86+
ctx.watch[proxy] = function (newValue, oldValue) {
87+
// now: this[proxy] === newValue
88+
if (newValue !== oldValue) {
89+
// so: `this[proxy] = newValue` will not trigger watcher
90+
this[directSyncMethod](newValue, oldValue, X_PROP_CHANGED_BY_PROXY);
91+
}
92+
};
93+
});
94+
}
95+
96+
});
97+
});
98+
99+
module.exports = index;

dist/vue-better-sync.es.js

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/*!
2+
* vue-better-sync v1.0.1
3+
* (c) 2018-present fjc0k <[email protected]>
4+
* Released under the MIT License.
5+
*/
6+
var cache = Object.create(null);
7+
var camelCase = (function (word) {
8+
if (!cache[word]) {
9+
cache[word] = word.replace(/-([a-z])/g, function (_, char) { return char.toUpperCase(); });
10+
}
11+
12+
return cache[word];
13+
});
14+
15+
var X_DATA_PROPS = '_DATA_PROPS_';
16+
var X_PROP_CHANGED_BY_PARENT = 1;
17+
var X_PROP_CHANGED_BY_PROXY = 2;
18+
var index = (function (ref) {
19+
if ( ref === void 0 ) ref = {};
20+
var prop = ref.prop; if ( prop === void 0 ) prop = 'value';
21+
var event = ref.event; if ( event === void 0 ) event = 'input';
22+
23+
return ({
24+
model: {
25+
prop: prop,
26+
event: event
27+
},
28+
29+
data: function data() {
30+
var this$1 = this;
31+
32+
var props = this.$options[X_DATA_PROPS] || {};
33+
return Object.keys(props).reduce(function (data, proxy) {
34+
data[proxy] = this$1[props[proxy]];
35+
return data;
36+
}, {});
37+
},
38+
39+
beforeCreate: function beforeCreate() {
40+
var ctx = this.$options;
41+
if (!ctx.props) { return; }
42+
ctx[X_DATA_PROPS] = {};
43+
ctx.methods = ctx.methods || {};
44+
ctx.watch = ctx.watch || {};
45+
Object.keys(ctx.props).forEach(function (propName) {
46+
var ref = ctx.props[propName];
47+
var isSync = ref.sync;
48+
var isModel = prop === propName;
49+
if (!isModel && !isSync) { return; }
50+
var PropName = camelCase(("-" + propName));
51+
var proxy = "actual" + PropName;
52+
var syncMethod = "sync" + PropName;
53+
var directSyncMethod = "sync" + PropName + "Directly";
54+
ctx[X_DATA_PROPS][proxy] = propName;
55+
56+
ctx.methods[directSyncMethod] = function (newValue, oldValue, propChangedBy) {
57+
if (oldValue !== newValue) {
58+
if (propChangedBy !== X_PROP_CHANGED_BY_PROXY) {
59+
this[proxy] = newValue;
60+
}
61+
62+
if (propChangedBy !== X_PROP_CHANGED_BY_PARENT) {
63+
if (isModel) {
64+
this.$emit(event, newValue, oldValue);
65+
}
66+
67+
if (isSync) {
68+
this.$emit(("update:" + propName), newValue, oldValue);
69+
}
70+
}
71+
}
72+
};
73+
74+
ctx.methods[syncMethod] = function (newValue) {
75+
this[proxy] = newValue;
76+
};
77+
78+
ctx.watch[propName] = function (newValue, oldValue) {
79+
if (newValue !== oldValue) {
80+
this[directSyncMethod](newValue, oldValue, X_PROP_CHANGED_BY_PARENT);
81+
}
82+
};
83+
84+
ctx.watch[proxy] = function (newValue, oldValue) {
85+
// now: this[proxy] === newValue
86+
if (newValue !== oldValue) {
87+
// so: `this[proxy] = newValue` will not trigger watcher
88+
this[directSyncMethod](newValue, oldValue, X_PROP_CHANGED_BY_PROXY);
89+
}
90+
};
91+
});
92+
}
93+
94+
});
95+
});
96+
97+
export default index;

0 commit comments

Comments
 (0)