在Svelte Custom方法中使用getter / setter

时间:2017-03-29 18:20:48

标签: javascript svelte

在自定义方法中使用get / set对时,我无法编译我的svelte组件。这不受支持吗?或者我做错了什么?

示例:

说我想要一个显示名称的组件,我想使用它来设置名称。 com.name = 'The new 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>

问题在于,当我尝试编译它时,它说有一个重复的密钥。

    Duplicate property 'displayName'

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

这是一个REPL - https://svelte.technology/repl?version=1.13.2&gist=0eeab5717526694139ba73eae766bb30

我在文档中没有看到有关此内容的任何内容。我可以不使用setter,但我希望能够。

2 个答案:

答案 0 :(得分:5)

tl;这可以使用wrapper object

这里的错误信息有点令人困惑 - 这不是重复属性是一个问题,是你不能在methods中拥有getter和setter,它们在任何情况下都与{{1}分开填充组件内部状态的对象(以及实例化时提供的数据以及可能存在的任何计算值)。我已为here打开了一个问题。

data本身也不能有getter和setter - 或者更确切地说它可以,但是它们不会被使用,因为从data函数返回的对象不同于内部状态对象(否则我们都可能遇到与变异相关的错误)。

但实际上很容易创建一个包装器对象,允许您获取和设置组件的数据:

data

如果你如此倾向,你甚至可以做function wrap (component) { var wrapper = {}; var data = component.get(); Object.keys(data).forEach(key => { Object.defineProperty(wrapper, key, { get() { return component.get()[key]; }, set(value) { component.set({ obj[key]: value }); } }) }); return wrapper; } var component = new Component({...}); var wrapper = wrap(component); wrapper.name = 'Rich'; - 那么你可以操纵component.data = wrap(component)等等。

我整理了small repo演示方法 - see it in action here

答案 1 :(得分:1)

编辑:正如Rich Harris在下面的评论中指出的那样,getter和setter在data内无法工作,因为Svelte会在内部将属性复制到普通的JS对象(因此忽略了吸气剂和制定者)。我认为你可以做的下一个最好的事情是制作一个方法name,可以像name()一样调用getter,name(value)作为setter。

苗条代码:

<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>

原帖:

您的getter和setter应该在data而不是methods,因为它们最终会创建一个属性。此属性与您在原始name方法中定义为等于'The Name'的{​​{1}}冲突。我建议使用&#34;私人&#34;财产data代替。

Svelte Code(REPL):

_name