【发布时间】:2019-09-09 01:39:47
【问题描述】:
我想将我组织的应用程序从 Knockout 切换到 Vue,但缺少一些概念或者我误解了 vueJs 的理念。所以我无法重现相同的行为。
根据我的阅读,VueJs 真正专注于组件。
每个组件管理都是自己的 DOM。
https://fr.vuejs.org/v2/guide/reactivity.html
https://fr.vuejs.org/v2/guide/list.html
...(我在开始输入键盘之前阅读了本指南页面的大部分内容:p)
这种行为对于需要共享的简单组件来说很好,但就我而言,这有点令人沮丧,因为我需要链接一些模块(请参阅最后关于上下文的问题)
我读过另一篇很棒的文章 (https://jes.al/2017/05/migrating-from-knockoutjs-to-vuejs/) 关于“淘汰到 Vuejs 的过渡”,但它缺乏如此具体的细节。
例如:它解释了“subscribe”(在 KO 中)可以被“watch”(在 Vue 中)替换,但没有解释“何时”我们可以应用这些观察者(请参阅最后的问题)
这是一个非常小的代码提取,可以总结我的大部分特定需求。
HTML
<div id="app">
<div data-bind="text: title"></div>
<i data-bind="visible: changeTracker.hasChanges">save your change dude !!</i>
<div data-bind="with: model">
<!-- the binging "with" allow us to move context to model for the current node and prevent typing "model." each time (ex: model.prop1, modeld.pro2,) -->
<label data-bind="text: name"></label>
<input type="text" data-bind="value: firstName"/>
<span data-bind="text: $parent.nameAndFirstName">
<!-- "$parent" allow us to access vm context itself -->
<input type="text" data-bind="value: city"/>
</div>
<div>
<button data-bind="click: changeTracker.undo, enabled: changeTracker.hasChanges"></button>
<button data-bind="click: saveData, enabled: changeTracker.hasChanges"></button>
</div>
</div>
Javascript
var changeTrackerVM_Factory = function(){
var self = {};
self.initialState = null; // no need to be ko.observable since it's used for internal manipulation only
// flag that will tell the UI that modification exist
self.hasChanges = ko.observable(false);
self.init = function(modelToTrack){
// some piece of code .... subscribe ... and so on
}
self.undo = function(){
// some piece of code that revrt the object to it's initial state
};
return self;
};
var userVM_Factory = function(){
var self = {};
// data from-to database
self.model = {
id: "", //-- don't need to be observable since it's not rendered and not modifiable
name: ko.observable(""),
firstName: ko.observable(""),
city: ko.observable("")
};
self.nameAndFirstName = ko.computed(function(){
return self.model.name() + "-" + self.model.firstname();
});
// build the custom tracker module
self.changeTracker = changeTrackerVM_Factory();
self.init = function(){
//some ajaxRequest
$.ajax(....).then(function(data){
// map recieved datas
self.model.name(data.name);
......
// apply custom observation AFTER data mapping
self.model.city.subscribe(function(newvalue){
alert("yeaah !! YOU changed the city value");
});
// apply the "custom tracking module" used to show the state in the UI
self.changeTracker.init(self.model);
});
}
self.save = function(){
// some piece of code to send to DATABASE
}
return self;
};
// initialise the relation between the UI and the VM
var userVM = userVM_Factory();
ko.applybinding(userVM , "#app");
如果我想将此代码转换为 vueJS 并且我有相同的行为,我需要回答:
我怎样才能只跟踪“模型”的几个属性(我相信这是可能的,因为这样一个使用过的库会受到性能优化的影响)
我如何才能在第一次初始化后才启动“监视”(并防止在开始时弹出“警报”)
如您所见,我没有“他的 DOM 块的一个模块”例如:changeTracker.hasChanges 用于 DOM 的顶部和底部
如果我使用组件仅通过它自己的 DOM 来管理“模型”.. 我如何在里面使用 $parent ???
【问题讨论】:
-
在 Vue 中有一些组件,它们“管理它们的 DOM 部分”(无论是小块还是大块)。组件是可重复使用的 - 在同一页面上多次使用。但是,如果您希望一个组件在您的应用中代表相同的状态(例如,显示相同的值,管理相同的底层实体,无论您将其放置在模板中多少次以及放置在何处),那么您需要使用状态管理。如果您的应用程序不是那么复杂,那么事件总线就可以了,但我建议阅读 Vuex - Vue 的事实上的状态管理器。
-
好的,我会更多地研究 Vuex ......所以我希望完成与我在 Knockout 中所做的相同的工作,我必须使用额外的库(vue + vuex)......我有兴趣学习新事物,但我必须先评估过渡的成本。
-
您的简化示例不需要状态管理,但我想您的整个应用程序(更多视图/页面、功能和组件)需要一个状态管理工具。当你需要 Vuex 时就是这种情况。在开发过程中,您不会觉得它是一个单独的工具。
-
在我的简化示例中,模块“changeTracker”比较对象的初始状态和“仅跟踪的属性”发生变化时,然后确定我们是否应该绘制“保存按钮”。 . 你是说我可以在没有 Vuex 的情况下实现同样的目标 .. 对吗?如果是这样,我将不得不确定如何构建依赖于另一个模块(模型)的模块(changeTracker),它只跟踪很少的属性(不需要跟踪“Id”,因为它不会改变)
标签: vue.js knockout.js