最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Use getterssetters in Svelte Custom methods - Stack Overflow

programmeradmin2浏览0评论

I am not able to pile my svelte ponent when using a get/set pair in custom methods. Is this not supported? Or am I doing something wrong?

Example:

Say I wanted to have a ponent that displays a name and I want to set the name using. .name = 'The new name';

However I only want the ponent to use the name if it has no spaces in the name.

<h1>Hello {{name}}!</h1>

<script>
    export default {
        data () {
            return {
                name: 'The Name',
            }
        },
        methods: {
            get displayName() {
                return this.get('name'); 
            },
            set displayName(val) {
                if (val.indexOf(' ') < 0) {
                    this.set('name', val);
                }
            }
        }
    }
</script>

The Issue is that when I try to pile this, it says there is a duplicate key.

    Duplicate property 'displayName'

    49:             return this.get('name');
    50:         },
    51:         set displayName(val) {

Here is a REPL - /repl?version=1.13.2&gist=0eeab5717526694139ba73eae766bb30

I don't see anything in the documentation about this. I can just not use setters, but I would like to be able to.

I am not able to pile my svelte ponent when using a get/set pair in custom methods. Is this not supported? Or am I doing something wrong?

Example:

Say I wanted to have a ponent that displays a name and I want to set the name using. .name = 'The new name';

However I only want the ponent to use the name if it has no spaces in the name.

<h1>Hello {{name}}!</h1>

<script>
    export default {
        data () {
            return {
                name: 'The Name',
            }
        },
        methods: {
            get displayName() {
                return this.get('name'); 
            },
            set displayName(val) {
                if (val.indexOf(' ') < 0) {
                    this.set('name', val);
                }
            }
        }
    }
</script>

The Issue is that when I try to pile this, it says there is a duplicate key.

    Duplicate property 'displayName'

    49:             return this.get('name');
    50:         },
    51:         set displayName(val) {

Here is a REPL - https://svelte.technology/repl?version=1.13.2&gist=0eeab5717526694139ba73eae766bb30

I don't see anything in the documentation about this. I can just not use setters, but I would like to be able to.

Share Improve this question edited Mar 29, 2017 at 18:35 Zac asked Mar 29, 2017 at 18:20 ZacZac 2,21124 silver badges49 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 7

tl;dr this is possible with a wrapper object

The error message here is a bit confusing — it's not the duplicate property that's a problem, is that you can't have getters and setters in methods, which in any case is separate from the data object that populates a ponent's internal state (along with data supplied at instantiation and any puted values there might be). I've opened an issue for that here.

The data itself also can't have getters and setters — or rather it can, but they won't be used, because the object returned from your data function isn't the same as the internal state object (otherwise we'd all probably run into mutation-related bugs).

But it's actually fairly easy to create a wrapper object that allows you to get and set a ponent's data:

function wrap (ponent) {
  var wrapper = {};
  var data = ponent.get();

  Object.keys(data).forEach(key => {
    Object.defineProperty(wrapper, key, {
      get() {
        return ponent.get()[key];
      },
      set(value) {
        ponent.set({ obj[key]: value });
      }
    })
  });

  return wrapper;
}

var ponent = new Component({...});
var wrapper = wrap(ponent);

wrapper.name = 'Rich';

You could even do ponent.data = wrap(ponent) if you were so inclined — then you could manipulate ponent.data.name and so on.

I've put together a small repo demoing that approach — see it in action here.

Edit: As Rich Harris pointed out in the ments below, getters and setters won't work within data because Svelte copies the properties to a plain JS object internally (thus ignoring getters and setters). I think the next best thing you can do is make a method name that can be called like name() as a getter, and name(value) as a setter.

Svelte Code:

<h1>Hello {{_name}}!</h1>

<script>
  export default {
    data() {
      return {
        _name: 'The Name'
      }
    },
    methods: {
      name(value) {
        if (value === void 0) return this.get('_name')
        this.set('_name', value)
      }
    }
  }
</script>

Original Post:

Your getter and setter should be in your data rather than your methods, because they create a property in the end. This property conflicts with the name you defined as equal to 'The Name' inside your original data method. I would suggest using a "private" property _name instead.

Svelte Code (REPL):

<h1>Hello {{name}}!</h1>

<script>
  export default {
    data() {
      return {
        _name: 'The Name',
        get name() {
          return this._name
        },
        set name(value) {
          / /.test(this._name) || (this._name = value)
        }
      }
    }
  }
</script>
发布评论

评论列表(0)

  1. 暂无评论