从VueJS组件共享数据

时间:2016-04-28 10:39:17

标签: vue.js

我有一个VueJS地址查找组件。

Vue.component('address-lookup',
{
    template: '#address-lookup-template',
    data: function()
    {
        return {
            address: {'name': '', 'town:': '', 'postcode': ''},
            errors: {'name': false, 'town': false, 'postcode': false},
            states: {'busy': false, 'found': false},
            result: {}
        }
    },
    methods:
    {
        findAddress: function(event)
        {
            if( typeof event === 'object' && typeof event.target === 'object' )
            {
                event.target.blur();
            }

            $.ajax(
            {
                context: this,
                url: '/lookup',
                data:
                {
                    'name':     this.address.name,
                    'town':     this.address.town,
                    'postcode': this.address.postcode
                },
                success: function(data)
                {
                    this.states.busy = false;
                    this.states.found = true;
                    this.address.name = data.name;
                    this.result = data;
                }
            });
        },
        reset: function()
        {
            this.states.found = false;
            this.result = {};
        }
    }
});

在我的模板中,我接着将结果绑定为:

<p>{{ result.formatted_address }}</p>

结果中返回的一些额外数据(如推特句柄)不是地址查找模板的一部分,并且发生在表单的单独部分。由于与表单结构有关的原因,我不能在同一模板中包含这些输入。

我发现了一种绑定这些输入的方法,虽然它感觉有些'hacky'。

<input type="text" name="twitter" v-model="$refs.lookupResult._data.result.twitter">

一切正常。

我的问题是,表单有时会在创建新记录的上下文中包含为较大模板的一部分,有时在编辑的上下文中。编辑记录时,将删除查找组件(使用if服务器端,因此模板不再加载),当发生这种情况时,我会收到此错误。

$refs.lookupResult._data.result.twitter": TypeError: Cannot read property '_data' of undefined

这是有道理的。我在包含模板时定义了lookupResult,在编辑时我删除了这一行:

<address-lookup v-ref:lookup-result></address-lookup>

我已经通过包含一个没有v-model属性的每个额外输入的版本来解决它,再次使用服务器端if。但是有很多这些并且它变得有点混乱。

我可以使用更清洁的方法来更好地实现这一目标吗?

1 个答案:

答案 0 :(得分:1)

所以我不知道您的布局的层次结构,上面没有说明,但假设地址查找组件是您父级的子级,并且您实际上需要地址查找的结果在那个父母,例如:

<parent-component> <!-- where you need the data -->
  <address-lookup></address-lookup> <!-- where you lookup the data -->
</parent-component>

然后你可以通过定义“地址”来简单地传递数据道具,无论是自上而下(默认)还是双向传递。例如,在父母的vue数据钩子上:

// parent's data() function
data = function () { 
  return { 
    address: {} 
  }
}

// parent template, passed address with .sync modifier (to make it bi-directional)
<parent-component>
  <address-lookup :address.sync='address'></address-lookup>
</parent-component>

// have the props accepted in the address look up component
var addressComponent = Vue.extend({
  props: ['address']
})

现在在$ .ajax成功功能中,只需在this.address上设置所需的道具即可。当然,您可以使用所需的所有道具:错误,结果,状态等。更好的是,如果您可以将它们嵌套在父级的单个键上,则可以为包含所有四个元素的对象传递单个键所有四个分开。