Skip to content

Commit

Permalink
Fixed array and object type default props
Browse files Browse the repository at this point in the history
  • Loading branch information
itsfrank committed Jul 13, 2016
1 parent 6fc0283 commit 8b05a42
Show file tree
Hide file tree
Showing 11 changed files with 84 additions and 14 deletions.
11 changes: 10 additions & 1 deletion README.md
Expand Up @@ -52,7 +52,7 @@ There are 2 ways to call it:

     options - the same object as the one you would use defining a prop

By default, the prop will behave equivalently to having  `myProp: null`   in the props object. However, if you give a value to a value to a variable decorated by prop (see example below), the default property of the prop object will be set to this value.
By default, the prop will behave equivalently to having  `myProp: null`   in the props object. However, if you give a value to a value to a variable decorated by prop (see example below), the default property of the prop object will be set to this value. If the value if of type array or object, don't worry about wrapping it in a function like you would do in standard vue, to provide maximum type checking and intelisense, vue-typescript clones and wraps it into a function for you.

##### @Watch
It can be applied to either a function or a variable, and for each application, there are 2 ways to call it:
Expand Down Expand Up @@ -86,6 +86,8 @@ class MyComponent {
})
someDefaultProp:string = 'some default value';

@Prop someObjProp:{default:string} = {default: 'value'}; //vue-typescript makes sure to deep clone default values for array and object types

someVar:string = 'Hello!';

doStuff() {
Expand All @@ -102,6 +104,13 @@ Vue.component('my-component', {
someDefaultProp : {
type: String,
default: 'some default value'
},
someObjProp: {
default: function(){
return {
default: 'value'
}
}
}
},
data: function(){
Expand Down
15 changes: 12 additions & 3 deletions lib/vuecomponent.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion lib/vuecomponent.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion package.json
Expand Up @@ -39,5 +39,8 @@
"peerDependencies": {
"vue": "^1.0.26"
},
"typings": "lib/index"
"typings": "lib/index",
"dependencies": {
"clone": "^1.0.2"
}
}
14 changes: 12 additions & 2 deletions src/vuecomponent.ts
@@ -1,4 +1,5 @@
import * as Vue from 'vue';
import * as clone from 'clone'

import Config from './config'
import { DeveloperUtils } from './utils'
Expand Down Expand Up @@ -94,9 +95,18 @@ function createDecorator(name?:string, options?:vuejs.ComponentOption){
}

for (key in options.props) {
if (options.data[key] != null && options.data[key] != undefined) {
var default_val:any = options.data[key];
if (default_val != null && default_val != undefined) {
if (!options.props[key]) options.props[key] = {};
options.props[key].default = options.data[key];
if (typeof default_val == 'object'){
var copy = clone(default_val, false);
default_val = function(){return clone(copy, false)}
} else if (typeof default_val == 'array'){
var copy = clone(default_val, false);
default_val = function(){return clone(copy, false)}
}

options.props[key].default = default_val;
delete options.data[key];
}
}
Expand Down
22 changes: 16 additions & 6 deletions test/prop.test.ts
Expand Up @@ -8,14 +8,16 @@ import { VueComponent } from '../src/vuecomponent'

describe('Prop', function(){

@VueComponent({
el: 'element',
@VueComponent(<any>{
template: '<p>hello</p>'
})
class PropTest {
class PropTest extends Vue{
@Prop
simple_prop:string = 'default val';


@Prop
object_prop:any = {im: 'an object'};

@Prop({
default: 'default',
type: String,
Expand All @@ -25,14 +27,22 @@ describe('Prop', function(){
}

it('should have a simple prop', function(){
var component = Utils.component('prop-test');
expect(component.$options.props).to.have.property('simple_prop').that.has.property('default').that.equals('default val');
var component = new PropTest();
expect(component.$options['props']).to.have.property('simple_prop').that.has.property('default').that.equals('default val');
})

it('should have an option prop', function(){
var component = Utils.component('prop-test');
expect(component.$options.props).to.have.property('option_prop').to.have.property('default').to.equal('default');
expect(component.$options.data()).to.not.haveOwnProperty('option_prop');
})

it('should clone objects', function(){
var component = Utils.component('prop-test');
var o1 = component.$options.props.object_prop.default;
component = Utils.component('prop-test');
var o2 = component.$options.props.object_prop.default;
expect(o1()).to.not.equal(o2());
})

})
1 change: 1 addition & 0 deletions typings.json
Expand Up @@ -2,6 +2,7 @@
"name": "vue-typescript",
"dependencies": {},
"globalDependencies": {
"clone": "registry:dt/clone#0.1.11+20160317120654",
"vue": "registry:dt/vue#1.0.21+20160423143248"
},
"globalDevDependencies": {
Expand Down
19 changes: 19 additions & 0 deletions typings/globals/clone/index.d.ts
@@ -0,0 +1,19 @@
// Generated by typings
// Source: https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/7de6c3dd94feaeb21f20054b9f30d5dabc5efabd/clone/clone.d.ts
declare module "clone" {
/**
* @param val the value that you want to clone, any type allowed
* @param circular Call clone with circular set to false if you are certain that obj contains no circular references. This will give better performance if needed. There is no error if undefined or null is passed as obj.
* @param depth to wich the object is to be cloned (optional, defaults to infinity)
*/
function clone<T>(val: T, circular?: boolean, depth?: number): T;

namespace clone {
/**
* @param obj the object that you want to clone
*/
function clonePrototype<T>(obj: T): T;
}

export = clone
}
8 changes: 8 additions & 0 deletions typings/globals/clone/typings.json
@@ -0,0 +1,8 @@
{
"resolution": "main",
"tree": {
"src": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/7de6c3dd94feaeb21f20054b9f30d5dabc5efabd/clone/clone.d.ts",
"raw": "registry:dt/clone#0.1.11+20160317120654",
"typings": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/7de6c3dd94feaeb21f20054b9f30d5dabc5efabd/clone/clone.d.ts"
}
}
1 change: 1 addition & 0 deletions typings/index.d.ts
@@ -1,4 +1,5 @@
/// <reference path="globals/chai/index.d.ts" />
/// <reference path="globals/clone/index.d.ts" />
/// <reference path="globals/mocha/index.d.ts" />
/// <reference path="globals/node/index.d.ts" />
/// <reference path="globals/vue/index.d.ts" />
Binary file removed vue-typescript-0.4.0.tgz
Binary file not shown.

0 comments on commit 8b05a42

Please sign in to comment.