Model:负责数据存储
View:负责页面展示
View Model:负责业务逻辑处理(比如Ajax请求等),对数据进行加工后交给视图展示
模板渲染:基于 html 的模板语法,学习成本低。
响应式的更新机制:数据改变之后,视图会自动刷新。【重要】
渐进式框架
组件化/模块化
轻量:开启 gzip压缩后,可以达到 20kb 大小。(React 达到 35kb,AngularJS 达到60kb)。
Webpack:代码模块化构建打包工具。
Gulp:基于流的自动化构建工具。
Babel:使用最新的 规范来编写 js。
Vue:构建数据驱动的Web界面的渐进式框架
Express:基于 Node.js 平台,快速、开放、极简的 Web 开发框架。
v-on
提供了很多事件修饰符来辅助实现一些功能。事件修饰符有如下:
.stop
阻止冒泡。本质是调用 event.stopPropagation()。
.prevent
阻止默认事件(默认行为)。本质是调用 event.preventDefault()。
.capture
添加事件监听器时,使用捕获的方式(也就是说,事件采用捕获的方式,而不是采用冒泡的方式)。
.self
只有当事件在该元素本身(比如不是子元素)触发时,才会触发回调。
.once
事件只触发一次。
.{keyCode | keyAlias}
只当事件是从侦听器绑定的元素本身触发时,才触发回调。
.native
监听组件根元素的原生事件。
PS:一个事件,允许同时使用多个事件修饰符。
// Vue.filter 中的第一个参数是过滤器的名称,第二个参数是具体的过滤器函数
// 定义一个 Vue 全局的过滤器,名字叫做 msgFormat
Vue.filter('msgFormat', function (myMsg, arg1) { // function 的第一个参数指的是管道符前面的 msg
// 字符串的 replace 方法,第一个参数,除了可写一个 字符串之外,还可以定义一个正则
return myMsg.replace(/单纯/g, '邪恶')
})
{{ msg | msgFormat(arg1) }}
//自定义全局按键修饰符
Vue.config.keyCodes.f2 = 113;
//自定义全局指令 v-color:设置DOM元素的color属性
Vue.directive('color', {
// 样式,只要通过指令绑定给了元素,不管这个元素有没有被插入到页面中去,这个元素肯定有了一个内联的样式
// 将来元素肯定会显示到页面中,这时候,浏览器的渲染引擎必然会解析样式,应用给这个元素
// 意思是说,我们可以把样式的代码写到bind中去(即使这个时候,dom元素还没有被创建)
bind: function (el, binding) { // 每当指令绑定到元素上的时候,会立即执行这个 bind 函数,【只执行一次】
console.log(binding.name); //打印结果:color
console.log(binding.value); //打印结果:green
console.log(binding.expression); //'green'
el.style.color = binding.value// 通过bining拿到v-color中传递过来的值
},
inserted: function (el) { // inserted 表示元素 插入到DOM中的时候,会执行 inserted 函数【触发1次】
// 和JS行为有关的操作,最好在 inserted 中去执行,防止 JS行为不生效
//el.focus()
},
updated: function (el) { // 当VNode更新的时候,会执行 updated, 【可能会触发多次】
}
})
(1)在子组件的props
属性中声明父亲传递过来的数据
(2)定义子组件的模板时,使用props中的属性
(3)父组件在引用子组件时,进行属性绑定。
子组件中,data中的数据和props中的数据的区别:
子组件中的 data 数据,并不是通过 父组件传递过来的,而是子组件自身私有的,比如: 子组件通过 Ajax ,请求回来的数据,都可以放到 data 身上。props 中的数据,都是通过 父组件 传递给子组件的。
data中的数据是可读可写的;props中的属性只是可读的,无法重新赋值,重新赋值会报错(也就是说,子组件不要直接去修改父组件中的数据)。
父组件:
子组件:this.$emit('change', 'msg');
(1)第一步:在标签中给 DOM 元素设置 ref 属性。
今天天气太好了
(2)第二步:通过 this.$refs.xxx 获取 DOM 元素
console.log(this.$refs.myTitle.innerText)
对于单页面应用程序来说,主要通过URL中的hash
(url地址中的#号)来实现不同页面之间的切换。
同时,hash有一个特点:HTTP请求中不会包含hash相关的内容。所以,单页面程序中的页面跳转主要用hash实现。
总结:在单页应用程序中,这种通过hash
改变来切换页面的方式,称作前端路由(区别于后端路由)。
Facebook 开源的一个JS库。
一个用于动态构建用户界面的JS库。
虚拟(virtual)DOM,不总是直接操作DOM
高效的DOM Diff算法,最小化页面重绘(即“局部渲染”)。
虚拟DOM指的是:在真实DOM的上一层映射一层虚拟DOM。我们操作的是映射关系,而不是真实的DOM。假设页面的样式做了修改(比如新增了一个标签),此时修改的是虚拟DOM的样式,真实的DOM并未发生变化。那什么时候,真实的DOM会发生变化呢? 当我把所有的内容操作完之后,转化为真实的DOM,此时要打包统一的渲染页面,于是真实的DOM发生变化,然后渲染一次。 这样做的话,可以减少页面的渲染次数。
传统的web开发,是利用 jQuery操作DOM,这是非常耗资源的。
我们可以在 JS 的内存里构建类似于DOM的对象,去拼装数据,拼装完整后,把数据整体解析,一次性插入到html里去。这就形成了虚拟 DOM。
步骤一:用JS对象模拟DOM树
步骤二:比较两棵虚拟DOM树的差异
步骤三:把差异应用到真正的DOM树上
总结:
虚拟DOM的本质:使用 JS 对象模拟DOM树。
虚拟DOM的目的:为了实现 DOM 节点的高效更新。
JSX:JavaScript XML,一种类似于XML的JS扩展语法。也可以理解成:符合 XML 规范的 JS 语法。
需要注意的是,哪怕你在 JS 中写的是 JSX 语法(即JSX这样的标签),但是,JSX内部在运行的时候,并不是直接把 我们的 HTML 标签渲染到页面上;而是先把 类似于HTML 这样的标签代码,转换成 React.createElement 这样的JS代码,再渲染到页面中。
从这一点我们可以看出,JSX是一个对程序员友好的语法糖。
JSX语法的本质:以 React.createElement 的形式来实现的,并没有直接把 用户写的 HTML代码,渲染到页面上。
方式一:通过 function构造函数 创建组件。内部没有 state 私有数据,只有 一个 props 来接收外界传递过来的数据。
方式二:通过 class 创建子组件。内部除了有 this.props 这个只读属性之外,还有一个专门用于 存放自己私有数据的 this.state 属性,这个 state 是可读可写的。
基于上面的区别,我们可以为这两种创建组件的方式下定义: 使用 function 创建的组件,叫做【无状态组件】;使用 class 创建的组件,叫做【有状态组件】。
父组件向子组件传值
父组件:
子组件:this.props.arr
子组件向父组件传值
父组件:
子组件:this.props.func(msg);
利用虚拟DOM实现快速渲染
轻量级
响应式组件,数据驱动视图
支持服务器端渲染
易于集成路由工具、打包工具以及状态管理工具
都有支持native的方案,React的React native,Vue的weex
1.React严格上只针对MVC的view层,Vue则是MVVM模式
2.virtual DOM不一样,vue会跟踪每一个组件的依赖关系,不需要重新渲染整个组件树.而对于React
而言,每当应用的状态被改变时,全部组件都会重新渲染,所以react中会需shouldComponentUpdate
这个生命周期函数方法来进行控制
3.组件写法不一样, React推荐的做法是 JSX + inline style, 也就是把HTML和CSS全都写进
JavaScript了,即'all in js';Vue推荐的做法是webpack+vue-loader的单文件组件格式,即html,css,jd
写在同一个文件;
4.数据绑定: vue实现了数据的双向绑定,react数据流动是单向的
5.state对象在react应用中不可变的,需要使用setState方法更新状态; 在vue中,state对象不是必须
的,数据由data属性在vue对象中管理;相对来说,使用Vue轻量级来进行移动端app比较合适,开
发中大型PC端项目使用React更好。
Vue生态:Vue + Vue-Router + Vuex + Axios + Babel + Webpack
React生态:React + React-Router + Redux + Axios + Babel + Webpack