最近要去做一个用Jquery写的老项目,所以就在想,能不向vue一样,自己构造一个简单的状态管理器,比如对一些变量添加get
和set
方法,进行数据劫持,监听其变化(这一块我也不是特别清楚,如果可行,我还要深入研究这一块)。而jquery只做DOM和事件的绑定,已经数据的处理。
1.这样的思路是否可行?
2.大致需要如何去构想,并应用?
3.如果这样可行,是否真的有助于提高代码质量,开发效率?反过来,可能会导致什么样的问题?
最近要去做一个用Jquery写的老项目,所以就在想,能不向vue一样,自己构造一个简单的状态管理器,比如对一些变量添加get
和set
方法,进行数据劫持,监听其变化(这一块我也不是特别清楚,如果可行,我还要深入研究这一块)。而jquery只做DOM和事件的绑定,已经数据的处理。
1.这样的思路是否可行?
2.大致需要如何去构想,并应用?
3.如果这样可行,是否真的有助于提高代码质量,开发效率?反过来,可能会导致什么样的问题?
实际上是可行的,不管是 redux 还是 mobx,你都可以将其应用到 jQuery 当中,他们都是脱离 React 存在的状态管理库。
只是会有很多坑,而且写到最后你会发现这么折腾,为什么不直接用 Vue/React 呢?
比如在 mobx 中,正常情况下我们会和 React 结合使用,会使用 mobx-react
这个库:
// Provider 注入 store
import { Provider } from 'mobx-react';
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById("app")
)
// App.jsx
import { observer, inject } from 'mobx-react';
@inject('appStore')
@observer
class App extends React.Component {}
你也可以根据 mobx-react
来写一个绑定 jQuery 的库,比如我自己写的一个 mobx-jquery
。你可以这样来使用:
import { provider } from 'mobx-jquery';
const inject = provider(store);
const renderHeader = (props) => {
const Header = `<header>${props.name}</header>`
$("#header").html(Header);
}
inject((store) => {
return {
name: store.name
}
})(renderHeader)
这样只要 store 中的 name 属性被修改了,就会自动通知 renderHeader
执行,这样就做到了重新渲染 header。
即使不用 React 的这些状态管理库,你也可以参考 Backbone 这类 MVC 框架来设计 Model 和 View 层。
Backbone 当中的状态是放到 Model 和 Collection 中管理的,你可以理解为 MVC 中的 M。而 Backbone 中的 View 会依赖 Model 中的数据,View 层通过 listenTo 方法来订阅 Model 层的变化,一旦 Model 发生某种变化,就通知 View 层进行重新渲染。
// todomvc 例子
app.AppView = Backbone.View.extend({
el: '.todoapp',
initialize: function () {
this.allCheckbox = this.$('.toggle-all')[0];
this.$input = this.$('.new-todo');
this.$footer = this.$('.footer');
this.$main = this.$('.main');
this.$list = $('.todo-list');
this.listenTo(app.todos, 'add', this.addOne);
this.listenTo(app.todos, 'reset', this.addAll);
this.listenTo(app.todos, 'change:completed', this.filterOne);
this.listenTo(app.todos, 'filter', this.filterAll);
this.listenTo(app.todos, 'all', _.debounce(this.render, 0));
app.todos.fetch({reset: true});
},
render: function () {
var completed = app.todos.completed().length;
var remaining = app.todos.remaining().length;
if (app.todos.length) {
this.$main.show();
this.$footer.show();
this.$footer.html(this.statsTemplate({
completed: completed,
remaining: remaining
}));
this.$('.filters li a')
.removeClass('selected')
.filter('[href="#/' + (app.TodoFilter || '') + '"]')
.addClass('selected');
} else {
this.$main.hide();
this.$footer.hide();
}
this.allCheckbox.checked = !remaining;
},
addOne: function (todo) {
var view = new app.TodoView({ model: todo });
this.$list.append(view.render().el);
},
// Add all items in the **Todos** collection at once.
addAll: function () {
this.$list.html('');
app.todos.each(this.addOne, this);
},
filterOne: function (todo) {
todo.trigger('visible');
},
filterAll: function () {
app.todos.each(this.filterOne, this);
},
// Generate the attributes for a new Todo item.
newAttributes: function () {
return {
title: this.$input.val().trim(),
order: app.todos.nextOrder(),
completed: false
};
}
})
10 回答11.3k 阅读
5 回答4.9k 阅读✓ 已解决
4 回答3.2k 阅读✓ 已解决
2 回答2.8k 阅读✓ 已解决
2 回答4.8k 阅读✓ 已解决
4 回答4.4k 阅读✓ 已解决
4 回答1.9k 阅读✓ 已解决
不比那么麻烦,jquery自带了事件发布订阅系统,用这个也可以做的很优雅