资讯专栏INFORMATION COLUMN

关于框架

Richard_Gao / 1435人阅读

摘要:事件订阅发布者模式什么是读音类似于是一套构建用户界面的渐进式框架。与其他重量级框架不同的是,采用自底向上增量开发的设计。

MVC && MVVM
前端框架前端 MV*框架的意义
被误解的MVC和被神化的MVVM
Vue.js新手入门指南
单页应用SPA的路由
单页面应用的路由问题

本文是在自己总结时,看了许多篇文章有了些体会,然后把我认为有意义的摘抄下来,文中很大部分摘录以上参考的文章,再结合一点点自己的观点,总的来说这篇文章是一个汇总文。

MV框架又是为什么兴起的呢?

在前端搞 MV有什么意义?也有人提出这样的疑问:以 AngularJS,Knockout,BackBone 为代表的 MV*框架,它跟 jQuery 这样的框架有什么区别?我 jQuery 用得好好的,有什么必要再引入这种框架?

库和框架是有一些区别的:库是一种工具,我提供了,你可以不用,即使你用了,也没影响你自 己的代码结构。框架则是面向一个领域,提供一套解决方案,如果你用我,就得按照我的方式办事。

jQuery 的思维方式是:以 DOM 操作为中心
MV*框架的思维方式是:以模型为中心,DOM 操作只是附加

由于前端功能的增强、代码的膨胀,导致不得不做“前端的架构”这个事情了。

为什么需要MV*框架

所以回到那个问题上,jQuery 满足了你的业务需要,你还有什么必要引入 MV*框架?
这个是要看产品类型的,如果是页面型产品,多数确实不太需要它,因为页面中的 JavaScript 代码,处理交互的绝对远远超过处理模型的,但是如果是应用软件类产品,这就太需要了。

MV框架的理念是把前端按照职责分层,每一层都相对比较独立,有自己的价值,也有各自发挥的余地。

这种逻辑的好处在于,业务逻辑与用户界面分离之后,后期对于界面的改版以及对于用户交互的处理变化,仅仅需要改动View层即可,不在需要对业务逻辑层进行多大的改动。后期的维护成本会减少很多。

将开发重心从DOM操作,转移到数据操作,将DOM操作与程序逻辑解耦。
期望提升开发效率、单位时间产出、后期代码扩展性,降低维护成本

MVC
Model 数据模型
View 用户界面
Controller 业务逻辑

不同的框架对Model、View的数据同步有不同的处理

MVC开发模式的原则:我们来看看 MVC 这种架构的特点。其实设计模式很多时候是为了 Don"t repeat yourself 原则来做的,该原则要求能够复用的代码要尽量复用,来保证重用。在 MVC 这种设计模式中,我们发现 View 和 Model 都是符合这种原则的。在Controller层尽量写不能够复用的。

什么是MVVM

开发人员只要考虑和处理Model(数据模型)的变化即可,不用考虑Model和View之间的数据绑定同步,更不用花精力用大量的代码获取DOM元素改变DOM元素的值来完成界面数据的变化。所有工作交给VM(View-Model)来处理。

MVVM并没有业务逻辑的控制器,它通过数据双向绑定,实时更新View和Model层,当数据模型发生变化的时候,用户界面(DOM)的内容会即时更新。反之如果用户操作导致某些DOM内容变化(如input),ViewModel也会即时的将Model数据模型更新。

数据双向绑定,开发人员不用再把精力放在DOM的修改和更新,只要通过模板引擎将数据模型和用户界面绑定,框架会实时同步双方数据的变化。减轻了开发人员的负担,也减少了DOM操作逻辑导致业务逻辑混乱的可能性。

backbonejs

调用 Backbone.history.start() 开始监控 hashchange 事件并分配路由
View:视图
Model:数据
Router:路由,由于Controller层主要负责了路由,而业务逻辑都在View中写了。
backbone事件:订阅发布者模式

vue.js 什么是vue

Vue.js(读音 /vjuː/, 类似于 view) 是一套构建用户界面的 渐进式框架。与其他重量级框架不同的是,Vue 采用自底向上增量开发的设计。Vue 的核心库只关注视图层,并且非常容易学习,非常容易与其它库或已有项目整合。另一方面,Vue 完全有能力驱动采用单文件组件和 Vue 生态系统支持的库开发的复杂单页应用。

Vue.js 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。

Vue.js就是一个用于搭建类似于网页版知乎这种表单项繁多,且内容需要根据用户的操作进行修改的网页版应用。

vue支持

vue 不支持IE8以下浏览器的原因?因为 Vue.js 使用了 IE8 不能模拟的 ECMAScript 5 特性

Virtual DOM(这个也没有写好)

通过js对象。。。。。。。。。

生命周期

beforeCreate

observe Data / init Events

组件实例被创建,组件属性计算之前

应用:beforeCreate 给个loading加载界面

created

1.组件实例创建完成,属性已经绑定,但DOM还未生成,$el属性还不存在

2.在实例创建之后同步调用。此时实例已经结束解析选项,这意味着已建立:数据绑定,计算属性,方法,watcher/事件回调。

3.但是还没有开始 DOM 编译,$el 还不存在,但是实例存在,即this.a存在,可打印出来 。

应用:created阶段做一些初始化,实现函数自执行,例如:created撤销loading

el / template

beforeMounted

模板编译、挂载之前

replace el

mounted

1.模板编译、挂载之后不保证组件已在document中

2.在编译结束后调用。此时所有的指令已生效,因而数据的变化将触发 DOM 更新。但是不担保 $el 已插入文档。

应用:mounted阶段做ajax,或者配合路由钩子做一些事情;此时DOM已经获取到,可以对DOM进行操作

data changed

beforeUpdated

1.数据更新时调用,发生在虚拟 DOM 重新渲染和打补丁之前。

2.你可以在这个钩子中进一步地更改状态,这不会触发附加的重渲染过程。

3.该钩子在服务器端渲染期间不被调用。

virtual dom re-render / patch

updated

由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。

然而在大多数情况下,你应该避免在此期间更改状态,因为这可能会导致更新无限循环。

vm.$destroyed

beforeDestroy

dsetroyed

vue模块化(自己没有还没有写好) 双向绑定的实现

还好发布检查了一次,发现自己把自己乱七八糟说的都写进来了。

剖析Vue实现原理 - 如何实现双向绑定mvvm

这篇文章我觉还不错,跟着自己写一遍,就会比较了解了。所有才有我的乱七八糟之说。自己理解最重要。

1.实例MVVM对象时,会生成观察者observe去观察实例中的data的每一个属性。

2.observe对象会遍历每一个key、value。如果value也是对象,也会通过observe来观察其中的key、value。

3.在每个observe对象中会创建一个订阅者,然后再设置属性的内置get、set函数。

4.通过内置get函数:在里面会给data的属性添加订阅者。

5.通过内置set函数:会将value值更改,并且如果新的value值是object,那么则创建一个observe观察者观察它。最后会通知订阅者。

6.compile主要做的事情是解析模板指令,将模板中的变量替换成数据,然后初始化渲染页面视图,并将每个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据有变动,收到通知,更新视图。

7.观察者Watcher是observe与compile的桥梁,在解析vue的自定义指令时,会为每一个指令创建一个Watcher观察者对象。watcher会将每个指令的当前状态设定,并添加到每个data的订阅者数组中,当data的数值发生改变时,会通知其绑定的订阅者,触发每一个订阅者更新函数。

vue的缺点

第一点:数据绑定使得 Bug 很难被调试。你看到界面异常了,有可能是你 View 的代码有 Bug,也可能是 Model 的代码有问题。数据绑定使得一个位置的 Bug 被快速传递到别的位置,要定位原始出问题的地方就变得不那么容易了。

第二点:对于过大的项目,数据绑定需要花费更多的内存。

vue的计算属性-computed

我们可以将同一函数定义为一个 method 而不是一个计算属性。对于最终的结果,两种方式确实是相同的。然而,不同的是计算属性是基于它们的依赖进行缓存的。计算属性只有在它的相关依赖发生改变时才会重新求值。这就意味着只要 message 还没有发生改变,多次访问 reversedMessage 计算属性会立即返回之前的计算结果,而不必再次执行函数。

watch

仅是观察变量的变化可以不用watch,直接用计算属性
但是,当在数据发生变化时,你希望执行开销较大的操作时,用watch比较有用。
watch可以限制我们执行的频率,在最终结果前,可以设置中间状态。计算属性无法做到。

vuex

state:驱动应用的数据源

view:以声明方式将state映射到视图

action:响应在view上的用户输入导致的状态变化。

当我们的应用遇到多个组件共享状态时,单向数据流的简洁性很容易被破坏:

多个视图依赖于同一状态。

来自不同视图的行为需要变更同一状态。

对于问题一,传参的方法对于多层嵌套的组件将会非常繁琐,并且对于兄弟组件间的状态传递无能为力。对于问题二,我们经常会采用父子组件直接引用或者通过事件来变更和同步状态的多份拷贝。以上的这些模式非常脆弱,通常会导致无法维护的代码。
把组件的共享状态抽取出来,以一个全局单例模式管理。

Vuex 是一个专为Vue.js应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

由于 Vuex 的状态存储是响应式的,从 store 实例中读取状态最简单的方法就是在计算属性中返回某个状态

State:状态

Getters:从State中派生出来的一些状态

Mutations:更改 Vuex 的 store 中的状态的唯一方法是提交 mutation,不能直接调用,需要触发store.commit(type,[payload])。mutation必须时同步函数。异步函数不能捕捉到改变的状态

Actions:

Action 提交的是 mutation,而不是直接变更状态

Action 可以包含任意异步操作。

Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象。

Action 通过 store.dispatch 方法触发:store.dispatch("increment")

store.dispatch 可以处理被触发的action的回调函数返回的Promise,并且store.dispatch仍旧返回Promise

Modules

由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。

为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割

SPA

单页面应用(Single Page Application)简称SPA,使用SPA构建的应用优点有用户体验好、速度快,内容的改变不需要重新加载整个页面,避免了不必要的跳转和重复渲染,从而相对减轻了服务器压力,SPA在WEB移动端应用非常广泛。

单页应用路由
HTML5在History里增加了pushState方法,这个方法会将当前的url添加到历史记录中,然后修改当前url为新url。当然这个方法只会修改地址栏的Url显示,但并不会发出任何请求。因此我们可以利用这个方法结合ajax实现单页面应用SPA,就是PushState+Ajax,人称Pjax。

location.hash更改了,页面也不会变化 hashchange hash值的改变也会加入历史记录中
总的来说,基于Hash的路由,兼容性更好;基于History API的路由,更加直观和正式。但是,有一点很大的区别是,基于Hash的路由不需要对服务器做改动,基于History API的路由需要对服务器做一些改造。

pushstate的使用方法:

history.pushState(state, title, url)

state: 可以放任意你想放的数据,它将附加到新url上,作为该页面信息的一个补充。 该对象可在onpopstate事件中获取,也可在history对象中获取。
title: 顾名思义,就是document.title。
url: 新url,也就是你要显示在地址栏上的url。

history.replaceState(state, title, url)

replaceState方法与pushState大同小异,区别只在于pushState会将当前url添加到历史记录,之后再修改url,而replaceState只是修改url,不添加历史记录。

window.onpopstate

一般来说,每当url变动时,popstate事件都会被触发。因此,我们可以把它用作浏览器的前进后退事件。该事件有一个参数,就是上文pushState方法的第一个参数state。

Pjax能做什么
Pjax是一个优秀的解决方案,它可以做:

可以在页面切换间平滑过渡,增加Loading动画。
可以在各个页面间传递数据,不依赖URL。
可以选择性的保留状态,如音乐网站,切换页面时不会停止播放歌曲。
所有的标签都可以用来跳转,不仅仅是a标签。
避免了公共JS的反复执行,减少了请求体积,节省流量,加快页面响应速度。
对SEO也不会有影响,对于不支持HTML5的浏览器以及搜索引擎爬虫,则可以跳转真实的页面。
支持浏览器前进和后退按钮。

Pjax
ajax请求,通过html5pushState来修改历史记录,如果不支持html5则
重写url
每次修改location的属性(hash除外),页面都会以新URL重新加载

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/84599.html

相关文章

  • 关于HTML框架(frameset)的一些基本用法

    摘要:为不显示边框,为显示边框。设置框架与框架间保留的空白距离。设置框架的颜色。注意事项不能将标签和标签同时使用,否则标签会失效。标签用于当浏览器不支持框架时使用,一般都会添加。frameset 定义 W3C是这样定义frameset框架的,通过使用框架,你可以在同一个浏览器窗口中显示不止一个页面。每份HTML文档称为一个框架,并且每个框架都独立于其他的框架。注意,这是HTML框架,不是前端框架,...

    xzavier 评论0 收藏0
  • 关于BOOTSTRAP的整理和理解

    摘要:规范名称定义,便于维护。譬如关于的定义在格式化的中会声明为,而在基本样式的中又可能会声明所以在中会出现多次定义。尽量减少连接数和的大小。基于版本的使用目前使用较广的是版本和,其中的最新版本是的最新版本。 随着CSS3和HTML5的流行,我们的WEB页面不仅需要更人性化的设计理念,而且需要更酷的页面特效和用户体验。作为开发者,我们需要了解一些宝贵的CSS UI开源框架资源,它们可以帮助我...

    amc 评论0 收藏0
  • 关于BOOTSTRAP的整理和理解

    摘要:规范名称定义,便于维护。譬如关于的定义在格式化的中会声明为,而在基本样式的中又可能会声明所以在中会出现多次定义。尽量减少连接数和的大小。基于版本的使用目前使用较广的是版本和,其中的最新版本是的最新版本。 随着CSS3和HTML5的流行,我们的WEB页面不仅需要更人性化的设计理念,而且需要更酷的页面特效和用户体验。作为开发者,我们需要了解一些宝贵的CSS UI开源框架资源,它们可以帮助我...

    Tony_Zby 评论0 收藏0
  • 关于BOOTSTRAP的整理和理解

    摘要:规范名称定义,便于维护。譬如关于的定义在格式化的中会声明为,而在基本样式的中又可能会声明所以在中会出现多次定义。尽量减少连接数和的大小。基于版本的使用目前使用较广的是版本和,其中的最新版本是的最新版本。 随着CSS3和HTML5的流行,我们的WEB页面不仅需要更人性化的设计理念,而且需要更酷的页面特效和用户体验。作为开发者,我们需要了解一些宝贵的CSS UI开源框架资源,它们可以帮助我...

    zeyu 评论0 收藏0
  • Java 初学者做的第一个微信小程序总结--关于Java基础

    摘要:官方资料微信公众平台注册小程序。官网开发文档社区开发工具部署微信小程序微信小程序本身不需要部署,在微信开发工具中直接上传代码就行。 为什么 学习 Java 三年,目前已经工作了2年,因为自学,基础差,所以打算年末总结一下常见的基础知识和面试点; 也可以通过独立做一个项目整合自己工作期间学习的知识,加深印象。 但是想着回家或是平时手机用的多,做一款APP和小程序很方便查看。 项目展示 本...

    mudiyouyou 评论0 收藏0
  • 关于分布式框架DUBBO的学习:安装部署(一)

    摘要:框架的组成五部分运行框架的容器。服务的提供者注册中心服务的消费者统一的监控中心如何安装部署框架网址截图同时下载地址截图打包和前提是先进行和的安装部署,然后解压进入相应的目录由于是编写而成,所以的安装前先要进行的安装配置。 什么是DUBBO?它是阿里开发的高性能服务框架,使得应用能够通过高性能的RPC实现服务的输入和输出,可以和Spring无缝进行集成。 什么是RPC?英文Remot...

    Rindia 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<