MVVM 是 Model-View-ViewModel 的缩写。html
Model
表明数据模型,也能够在Model中定义数据修改和操做的业务逻辑。View
表明UI 组件,它负责将数据模型转化成UI 展示出来。ViewModel
监听模型数据的改变和控制视图行为、处理用户交互,简单理解就是一个同步View 和 Model的对象,链接Model和View。在MVVM架构下,View 和 Model 之间并无直接的联系,而是经过ViewModel进行交互,Model 和 ViewModel 之间的交互是双向的, 所以View 数据的变化会同步到Model中,而Model 数据的变化也会当即反应到View 上。前端
ViewModel 经过双向数据绑定把 View 层和 Model 层链接了起来,而View 和 Model 之间的同步工做彻底是自动的,无需人为干涉,所以开发者只需关注业务逻辑,不须要手动操做DOM, 不须要关注数据状态的同步问题,复杂的数据状态维护彻底由 MVVM 来统一管理。vue
注意, MVVM模型中, Model和View是不会直接链接的,而ViewModel则会以双向链接的形式链接Model和View。面试
节选自 Vue的官方文档,笔者我进行了一些梳理,想了解得具体些的话仍是猛戳连接吧。
二者具备许多的类似之处segmentfault
Vue与React的不一样之处后端
shouldComponentUpdate
来避免没必要要的子组件的重渲染,而Vue中组件的依赖是在渲染过程当中自动追踪的,因此系统能精确知晓哪一个组件确实须要被重渲染。组件做用域的CSS 在React中,CSS 做用域是经过 CSS-in-JS 的方案实现的 (好比 styled-components、glamorous 和 emotion),而Vue则有更好的解决方案,以下:浏览器
``` <style scoped> @media (min-width: 250px) { .list-container:hover { background: orange; } } </style> ```这个可选 scoped
属性会自动添加一个惟一的属性 (好比 data-v-21e5b78
) 为组件内 CSS 指定做用域,编译的时候 .list-container:hover
会被编译成相似 .list-container[data-v-21e5b78]:hover
,这样就能够控制CSS只在这个组件内生效。缓存
具体能够参照官网的这张图,左侧以红色框表示的都是阶段安全
大体过程就是网络
vue实现数据双向绑定主要是采用数据劫持结合发布者-订阅者模式的方式,经过Object.defineProperty()来劫持各个属性的setter,getter,在数据变更时发布消息给订阅者,触发相应监听回调。当把一个普通 Javascript 对象传给 Vue 实例来做为它的 data 选项时,Vue 将遍历它的属性,用 Object.defineProperty 将它们转为 getter/setter。用户看不到 getter/setter,可是在内部它们让 Vue 追踪依赖,在属性被访问和修改时通知变化。
vue的数据双向绑定 将MVVM做为数据绑定的入口,整合Observer,Compile和Watcher三者,经过Observer来监听本身的model的数据变化,经过Compile来解析编译模板指令,最终利用watcher搭起observer和Compile之间的通讯桥梁,达到数据变化 —>视图更新;视图交互变化(input)—>数据model变动双向绑定效果。
路由的实现有两种:hash和history interface来实现前端路由,
hash在浏览器中符号“#”,#以及#后面的字符称之为hash,用window.location.hash读取;特色:
(1)hash虽然在URL中,但不被包括在HTTP请求中
(2)用来指导浏览器动做,对服务端安全无用,hash不会重加载页面
history采用h5的新特性;且提供了两个新方法:pushState(),replaceState()能够对浏览器历史记录栈进行修改,以及popState事件的监听到状态变动,不过history有个问题是:若是用户直接在地址栏中输入并回车,浏览器重启或从新加载时,history模式会将url修改的和正常请求后端同样,此状况下,从新向后端发送请求,后端若是没有配置对应路由处理,则返回404,解决方法是后端配置一下。
<router-link :to="{path:'/index',params:{id:num}}"> <router-link :to="{ path:'/index' , query:{id:num}}">
而后经过$route.params来读取数据,但路由传递参数值是对象的话就不行了会报错,传递前用base64转译一下就能够了。
父组件经过标签上面定义传值
<parent> <child :child-msg="msg"></child> //这里必需要用 - 代替驼峰 </parent> data(){ return { msg: [1,2,3] }; }
子组件经过props
方法接受数据
子组件经过props来接收数据: 方式1: props: ['childMsg'] 方式2 : props: { childMsg: Array //这样能够指定传入的类型,若是类型不对,会警告 } 方式3: props: { childMsg: { type: Array, //传入的类型 default: [0,0,0] //这样能够指定默认的值 } }
子组件经过$emit
方法传递参数
<template> <div @click="testClick"></div> </template> methods: { testClick() { this.$emit('test','123'); //$emit(even,value)even 是一个函数,value 是传给父组件的值 , 触发名为test方法, '123'为向父组件传递的数据 } }
父组件经过v-on
(简写为@
)来监听DOM事件,并在触发时接收数据运行js函数。
<div> <child @test="change" :msg="msg"></child> //监听子组件触发的test事件,而后调用change方法 </div> methods: { change(val) { this.msg = val; // val: 123 } }
若是2个组件不是父子组件那么如何通讯呢?这时能够经过eventHub
来实现通讯.
所谓eventHub
就是建立一个事件中心,至关于中转站,能够用它来传递事件和接收事件.
let Hub = new Vue(); //建立事件中心
组件1触发:
<div @click="eve"></div> methods: { eve() { Hub.$emit('change','hehe'); //Hub触发事件 } }
组件2接收:
<div></div> created() { Hub.$on('change', () => { //Hub接收事件 this.msg = 'hehe'; }); }
Vue的条件渲染涉及到两个不一样的关键字 v-if
和 v-show
v-if
v-if
是真正的条件渲染,它会适当地销毁和重建DOM达到让元素显示和隐藏的效果。
(Vue 会尽量高效地渲染元素,一般会复用已有元素而不是从头开始渲染,能够看一下第二段程序)v-if
也是惰性的:若是在初始渲染时条件为假,则什么也不作——直到条件第一次变为真时,才会开始渲染条件块。
<div v-if="type === 'A'"> A </div> <div v-else-if="type === 'B'"> B </div> <div v-else-if="type === 'C'"> C </div> <div v-else> Not A/B/C </div>
Vue 为你提供了一种方式来表达“这两个元素是彻底独立的,不要复用它们”。
只需添加一个具备惟一值的 key
属性便可,没有 key
说明的话就会被复用:
<template v-if="loginType === 'username'"> <label>Username</label> <input placeholder="Enter your username" key="username-input"> </template> <template v-else> <label>Email</label> <input placeholder="Enter your email address" key="email-input"> </template>
注意,<label>
元素仍然会被高效地复用,由于它们没有添加 key
属性。
v-show
经过修改元素的display的CSS属性让其显示或者隐藏,元素始终会被渲染并保留在DOM中。
<h1 v-show="ok">Hello!</h1> //ok 在data里进行赋值为true或者false
v-if
vs v-show
通常来讲,v-if
有更高的切换开销,而 v-show
有更高的初始渲染开销。所以,若是须要很是频繁地切换,则使用 v-show
较好;若是在运行时条件不多改变,则使用 v-if
较好。
欢迎诸位同道们留言补充ヾ(◍°∇°◍)ノ゙
参考连接
Vue官方教程
MVVM - 廖雪峰的官方网站
MVC,MVP 和 MVVM 的图示 - 阮一峰的网络日志
vue.js学习笔记(一):什么是mvvm框架,vue.js的核心思想 - _林冲 - 博客园
vue父子组件通讯 - Hi-Sen - 博客园
Vue 成长之路(一) - 媛媛码农成长记 - SegmentFault 思否
来源:https://segmentfault.com/a/1190000016268245