当您使用 1st level的 s-property 时,它直接通过-brackets$data
访问对象$data
[]
但是您想将selected
嵌套对象的路径传递给 -directive,因此您应该执行以下操作:
// source: https://stackoverflow.com/a/6842900/8311719
function deepSet(obj, value, path) {
var i;
path = path.split('.');
for (i = 0; i < path.length - 1; i++)
obj = obj[path[i]];
obj[path[i]] = value;
}
Vue.directive('selected', {
bind: function (el, binding, vnode) {
var select = $(el);
select.select2();
deepSet(vnode.context.$data, select.val(), binding.expression);
select.on('change', function () {
deepSet(vnode.context.$data, select.val(), binding.expression);
});
},
update: function (el, binding, newVnode, oldVnode) {
var select = $(el);
select.val(binding.value).trigger('change');
}
});
<select v-selected="userEditor.Id">
<option v-for="user in users" v-bind:value="user.id" >
{{ user.fullName}}
</option>
</select>
描述:
假设我们有两个$data
的 props:valOrObjectWithoutNesting
和objLvl1
:
data: function(){
return{
valOrObjectWithoutNesting: 'let it be some string',
objLvl1:{
objLvl2:{
objLvl3:{
objField: 'primitive string'
}
}
}
}
}
具有第一级 $data's-property 的变体:
<select v-selected="valOrObjectWithoutNesting">
// Now this code:
vnode.context.$data[binding.expression] = select.val();
// Equals to:
vnode.context.$data['valOrObjectWithoutNesting'] = select.val();
具有第 4 级 $data's-property 的变体:
<select v-selected="objLvl1.objLvl2.objLvl3.objField">
// Now this code:
vnode.context.$data[binding.expression] = select.val();
// Equals to:
vnode.context.$data['objLvl1.objLvl2.objLvl3.objField'] = select.val(); // error here
所以deepSet
我上面代码中的函数“转换”$data['objLvl1.objLvl2.objLvl3.objField']
为$data['objLvl1']['objLvl2']['objLvl3']['objField']
.
如您所见,正如我在对您的问题的评论中提到的,当您想让 select2-wrapper 更可定制时,指令方式比单独的组件方式复杂得多。在组件中,您可以根据需要传递尽可能多的配置道具和事件订阅,您将避免像这样的侧面突变,vnode.context.$data[binding.expression]
并且您的代码将变得更易于理解和更简单以获得进一步的支持。