Web前端三大框架_vue源码笔记
1.1 MVVM
VUE也是基于MVVM模式实现的。特点就是数据双向绑定
在MVVM模式中,分成三个部分:
M 模型 model
V 视图 view
VM 视图-模型 view-model
前端的本质是,
将人眼可读性强的数据,转换成机器可读性强的数据
将机器可读性强的数据,转换成人眼可读性强的数据
数据双向绑定
数据模型(机器可读性强的数据)的改变,会通过视图模型,同步给视图
通过数据绑定实现的
视图(人眼可读性强的数据)的改变,会通过视图模型,同步给数据模型
通过事件监听实现的
早期,js的为实现页面中的一些简单交互而设计的,因此非常简单,后来浏览器多了,很多浏览器的实现与标准不符,所以如何解决浏览器兼容问题,成了首要的问题,因此jquery就出现了,解决了浏览器兼容问题,随着技术的发展,富客户端,SPA等技术出现了,所以前端的首要问题是如何管理,维护这些代码,但是jquery没有对业务逻辑分层,因此MVC模式就出现了,对业务逻辑分成视图,模型,和控制器,代表框架就是backbone。但是在MVC中,我们还需要手动的更新视图,手动的存储视图更新的数据,所以MVVM模式就出现了,实现了数据双向绑定,可以加快我们的开发效率。
1.2介绍vue
vue是由华人开发的,因此有中文文档
vue是基于ES5语法实现的框架,因此只支持高级浏览器,所以更多时候适用于移动端
1.2.1 github
http://github.com/vuejs/vue
1.2.2官网
https://vuejs.org/
1.2.3中文网站
https://cn.vuejs.org/
1.2.4获取vue
为ES5开发,获取vue.js
bower install vue
bower是一个代码库管理工具,可以通过这个指令,获取所有常见的库,
bower也是一个npm包,所以通过npm安装,由于bower提供了bower指令,所以要全局安装
npm install -g bower
安装完成通过bower -v查看版本号
手动安装
将指令文件bower以及bower.cmd放在全局指令目录下
C:\Users\think\AppData\Roaming\npm
将模块文件夹bower放在全局模块目录下
C:\Users\think\AppData\Roaming\npm\node_modules
我们ES6语法讲解,所以要通过npm来安装vue
npm install vue
1.3体验vue
vue也是基于MVVM模式实现的
M就是数据模型,就是js中的数据(数组,对象,数字,字符串,布尔等)
V就是视图,就是用户看到的页面
VM就是视图模型,就是vue实例化对象
通过el属性,绑定视图容器(绑定视图)
是css选择器,常见css选择器都支持
通过data属性,绑定数据模型
此时模型中的数据,就与视图中的数据同步了
1.3.1vue实例化对象
我们实例化vue后,得到vue实例化对象
$el 就是获取的视图容器元素
绑定data数据中的所有属性,都添加给vue实例化对象自身了,并且设置了特性
并且在_data以及$data中对数据做了备份
在vue中,数据绑定的实现是通过ES5中对象属性的特性实现的
当我们修改数据属性的时候,视图更新
1 <body> 2 <!-- 定义视图容器 V --> 3 <div id="app"> 4 <input type="text" v-model="title"> 5 <h1>{{title}}</h1> 6 </div> 7 <!-- 引入vue --> 8 <script type="text/javascript" src="vue.js"></script> 9 <script type="text/javascript"> 10 // 定义模型 M 11 var data = { 12 title: '爱创课堂' 13 } 14 // 定义视图模型vue实例化对象,VM 15 var app = new Vue({ 16 // 绑定视图 17 el: '#app', 18 // 绑定模型 19 data: data 20 }) 21 </script> 22 </body> |
1.4 webpack编译
我们开发基于ES6语法,因此我们需要编译
ES module规范
通过import引入模块
通过export暴露接口
export暴露的接口通过import引入模块的时候,要解构,或者通过* as引入所有
export default 暴露的接口通过import直接引入
1 // 基于commonjs规范 2 module.exports = { 3 // 配置vue入口文件 4 resolve: { 5 // 别名 6 alias: { 7 'vue$': 'vue/dist/vue.js' 8 } 9 }, 10 // 入口文件 11 entry: { 12 '03': './es/03.es', 13 '04': './es/04.es', 14 }, 15 // 发布文件 16 output: { 17 // 文件名称 18 filename: './dist/[name].js' 19 }, 20 // 配置样式 21 module: { 22 // 加载机 23 rules: [ 24 // es6 25 { 26 test: /\.es$/, 27 // loader: 'babel-loader?presets[]=es2015', 28 loader: 'babel-loader', 29 query: { 30 presets: ['es2015'] 31 }, 32 // 避免编译node_modules 33 // exclude: './node_modules/' 34 }, 35 // 样式 36 { 37 test: /\.css$/, 38 loader: 'style-loader!css-loader' 39 }, 40 // less 41 { 42 test: /\.less$/, 43 loader: 'style-loader!css-loader!less-loader' 44 }, 45 // sass 46 // { 47 // test: /\.scss$/, 48 // loader: 'style-loader!css-loader!sass-loader' 49 // } 50 ] 51 } 52 } |
1.5数据丢失
数据丢失不是好的特性,是框架的bug
vue实现了数据双向绑定,当我们修改模型中的数据的时候,视图会自动更新。
数据的绑定是通过ES5中属性的特性实现的,我们修改属性的时候,被特性方法监听到,发布消息更新视图。
如果属性没有设置特性,就不能监听属性的改变,就不能通知视图去更新
当我们修改数据的时候,视图并没有更新,那么我们说该数据就丢失了
常见的数据丢失有四种情况
第一种情况是数组中的值类型(数字,字符串,布尔值等),
当我们修改数组中的值类型数据时候,此时模型中的数据更新了,视图未更新,会丢失数据
解决:用新数组,更新原来的数组
第二种情况是数字中新增的成员
当我们为数组添加成员的时候,数据就丢失了
解决:用添加新成员的新数组,更新原来的数组
第三种情况是引用类型(对象)数据,添加新属性
当我们为对象添加新属性的时候,数据就丢失了
解决;用新对象更新原有的对象
第四种情况是为vue实例化对象添加新属性
当我们为vue实例化对象添加新属性的时候,数据丢失了
解决:将新属性,在vue实例化对象中预定义出来
通用方案,为了解决数据丢失问题,作者提供了$set方法。
第一个参数表示修改的目标对象(可以是vue实例化对象,也可以是vue实例化对象中的某个属性对象)
第二个参数表示修改的属性名称
第三个参数表示修改的属性值
1 // 通用解决方案 2 // 可以修改vue实例化对象 3 app.$set(app, 'color', ['red', 'green']) 4 // 可以是vue实例化对象的某个属性对象 5 app.$set(app.color, '1', 'gold'); 6 7 // 修改vue实例化对象中的数据 8 app.msg = '爱创课堂' 9 // 1 修改数组中的值类型,数据丢失 10 app.color[1] = 'pink' 11 // 用新数组覆盖 12 app.color = ['red', 'pink'] 13 // 2 新增成员 14 app.color[5] = { 15 width: 100 16 } 17 // 用新数组覆盖 18 var arr = app.color.slice(0) 19 arr[5] = { width: 200 } 20 // 更新数组 21 app.color = arr; 22 // 3 新属性 23 app.obj.width = 500; 24 // 用新对象覆盖 25 var obj = Object.assign({}, app.obj); 26 // // 添加属性 27 obj.width = 600; 28 // // 更新对象 29 app.obj = obj; 30 // 4 新增成员 31 app.title = 'hello'; |
1.6插值
小程序中,我们使用{{}}语法插值,是一个伪js环境
vue也支持插值,语法是{{}},是一个真正的js环境,因此我们可以使用js中所有表达式,如运行,方法等等
小程序中,可以使用属性插值,vue1.0可以,2.0不允许
我们可以通过v-bind指令,实现对属性的插值(动态属性设置(绑定))
语法 v-bind:key=”value”
此时属性值不再是字符串了,而是js环境,我们可以使用js中所有表达式,并且字符串要加引号
vue为了简化我们对v-bind指令的使用,提供了:语法糖
所以我们可以使用:对v-bind指令简化
语法 :key=”value”
语法糖:就是对某个复杂操作的简化,来提高我们的开发效率
指令:指令就是对DOM元素的拓展,使其具有一定的行为特征
1 <div id="app"> 2 <!-- 运算 --> 3 <h1>{{msg + '-专业前端培训学校'}}</h1> 4 <h1 title="info">{{info}}</h1> 5 <!-- js表达式 --> 6 <!-- v-bind指令让属性值变成js环境,可以使用js表达式 --> 7 <h1 v-bind:title="info">{{info.toUpperCase()}}</h1> 8 <h1 v-bind:title="info.toUpperCase() + ' 爱创课堂'">{{info.toUpperCase()}}</h1> 9 <!-- 使用:语法糖,对v-bind指令简化 --> 10 <h1 :title="info.toUpperCase() + ' 爱创课堂'">{{info.toUpperCase()}}</h1> 11 </div> |
1.7插值过滤器
在插值语法中,或者v-bind指令中,我们可以使用js表达式来实现一定的功能。每次使用的时候,表达式都要写一次,无法复用表达式,维护成本高,所以为了复用表达式的功能,vue提供了插值过滤器技术
注意:1.0内置了大量过滤器,2.0移除了(弱化过滤器了)
语法
1.0: {{ data | 过滤器名称 参数1 参数2 | 过滤器2 }}
2.0: {{ data | 过滤器名称(参数1, 参数2) | 过滤器2 }}
当使用多个过滤器的时候,前一个过滤器的输出将作为后一个过滤器的输入
2.0没有内置过滤器,所以使用什么过滤器,我们要自定义什么过滤器
通过Vue.fitler方法自定义
第一个参数表示过滤器名称
第二个参数表示过滤器函数
第一个参数就是处理的数据
从第二个参数开始,表示传递的参数
返回值就是得到的结果
注意:fitler方法,不能被解构
1 // 计算数据属性|动态数据绑定 2 computed: { 3 // es6中,属性方法省略: function 4 msgUpper(v) { 5 console.log(this, arguments) 6 // 参数和作用域都是vue实例化对象, 7 // 返回值就是获取的数据 8 return v.msg.toUpperCase(); 9 return this.msg.toUpperCase(); 10 }, 11 // h-e-l-l-o 12 dealMsg(v) { 13 // 切割成数组, 14 return v.msg.split('') 15 // 拼接成字符串 16 .join('-') 17 } 18 } |
1.8数据动态绑定
又叫计算数据属性
我们想视图渲染数据,在渲染过程中,有两个时间点可以修改这些数据
一个是插值的时候,我们渲染视图,可以通过插值表达式或者插值过滤器,修改数据
一个是获取数据的时候,通过动态绑定数据的方式,在获取数据之前,修改数据
正是因为我们可以通过插值表达式以及动态数据绑定的方式修改数据,所以vue建议我们用动态数据绑定的语法代替插值过滤器
动态数据绑定与静态数据绑定相对比:
静态数据绑定(通过data属性定义的数据),获取数据的时候无法改变,只能在插值语法中,通过插值表达式以及插值过滤器修改
属性值就是数据
动态数据绑定(通过computed属性定义的数据),获取数据的时候,就可以改变数据了。
computed属性
属性值是对象
key表示数据名称
value是一个函数,获取数据的函数
参数以及this都是当前vue实例化对象,因此可以通过参数以及this获取vue实例化对象上的其他数据
返回值就是得到的结果
1.9数据双向绑定
MVVM模式的特征就是数据双向绑定
数据由模型进入视图 => (通过数据绑定实现的)
数据由视图进入模型 => (通过事件监听实现的)
vue为了简化数据双向绑定的操作,提供了v-model指令
我们可以通过v-model指令绑定数据
在vue中,指令的属性值都是js环境
v-model指令绑定的数据不能使用js表达式,并且只能定义在data属性中
1.9.1 v-cloak指令
用来实现隐藏插值符号的,分成两步使用
第一步 在html中,通过v-cloak属性选择器,设置display:none;
第二步 为需要隐藏的元素添加v-cloak指令
隐藏的元素必须在vue容器元素内(包括容器元素自身)
1 <style type="text/css"> 2 [v-cloak] { 3 display: none; 4 } 5 </style> 6 <div id="app" v-cloak> 7 <input type="text" v-model="msg"> 8 <!-- 第二步 添加v-cloak指令 --> 9 <h1>{{msg}}</h1> 10 <hr> 11 <input type="text" v-model="title"> 12 <!-- <h1 v-cloak>{{title}}</h1> --> 13 <h1>{{title}}</h1> 14 </div> |
1.10事件
vue中我们可以为元素绑定事件,
语法 v-on:click=”fn()”
v-on指令跟v-bind指令一样,也有语法糖,叫@
还可以写成 @click=”fn()”
事件回调函数我们要定义在vue实例化对象的methods属性中
methods跟data,computed,el等是一样的,只不过methods是专门用来定义方法的
key表示方法名称
value是方法函数
作用域this指向vue实例化对象,因此可以通过this访问vue中任何数据
注意:methods中定义的方法,不仅仅可以应用在事件中,跟data属性,computed属性一样,vue实例化后会直接添加在vue实例化对象自身,因此可以通过vue实例化对象访问其他方法
为元素绑定事件的时候,事件回调函数参数集合是可有可无的
如果没有参数集合
此时事件回调函数的方法中,有默认参数,就是事件对象
是源生的事件对象
如果添加了参数集合
此时事件回调函数的方法中,默认没有任何参数,此时想使用什么参数,我们可以在参数集合中,传递什么参数,
使用事件对象,传递$event
vue没有实现事件委托,所有没有事件委托三个优势:减少事件数量,语言未来元素,避免内存外泄
1.10.1事件修饰符
当我们绑定键盘事件的时候,常常要判断点击的按键,为了捕获点击的某个键,我们常常判断e.keyCode键盘,来判断按下的键
vue为了简化这个过程,提供了键盘修饰符,我们可以快速的为该键绑定事件
内置了9个按键:esc, tab, space, enter, delete, up, down, left, right
语法
v-on:keyup.修饰符=“fn()”
@keyup.修饰符=“fn()”
注意:新版本中,字母已经内置了
1 <div id="app"> 2 <!-- 绑定事件 --> 3 <h1 v-on:click="clickH1">爱创课堂</h1> 4 <!-- 添加参数集合 --> 5 <h1 @click="clickH1(100, 200, true, $event)">爱创课堂</h1> 6 <h1>爱创课堂</h1> 7 <input type="text" @keyup="demo"> 8 <!-- 事件修饰符 --> 9 <input type="text" @keyup.enter="clickEnter"> 10 <input type="text" @keyup.s="clickEnter"> 11 </div> |
1.11类的绑定
v-bind指令可以动态绑定元素属性数据,所以也可以通过v-bind指令动态绑定类属性
v-bind:class=”” 或者 :class=””
绑定类有三种赋值语法
1、绑定数组 :class=”[]”
每个成员代表一组类(可以出现空格的)
2、绑定对象 :class=”{}”
key表示一组类的名称
如果属性名称出现空格,横线等非法字符,key要添加引号
value表示是否保留这组类
3、绑定字符串 :class=”str”
代表一组类的名称
v-bind指令让属性值变成js环境,因此字符串要加引号
1 <!-- 新浪博客 --> 2 <div @mouseenter="showList" @mouseleave="hideList"> 3 <span>博客</span> 4 <!-- <ul :class="[cls]"> --> 5 <!-- <ul :class="{ 6 hide: isHide 7 }"> --> 8 <ul :class="cls"> 9 <li>博客评论</li> 10 <li>未读提醒</li> 11 </ul> 12 </div> |
1.12样式绑定
跟类的绑定一样,通过v-bind指令可以动态绑定样式,也有三种方式
1 绑定对象 :style=”{}”
key 表示样式名称
css中样式出现横线的名称要转换成驼峰式命名(也可以添加引号,但是不推荐)
value 表示样式值
2 绑定数组 :style=”[]”
每一个成员是一个对象,代表一组样式
key样式名称
value 样式值
3 绑定字符串 :style=”str”
str就是样式字符串,变量不带引号,字符串添加引号
Web前端三大框架_vue源码笔记的更多相关文章
- 构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(2)-easyui构建前端页面框架[附源码]
原文:构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(2)-easyui构建前端页面框架[附源码] 开始,我们有了一系列的解决方案,我们将动手搭建新系统吧. 用 ...
- WEB前端开发学习:源码canvas 雪
WEB前端开发学习:源码canvas 雪 双旦节要到了,程序员们为了响应气氛,特别用代码制作了动态雪花,WEB前端开发学习的初学者们一起跟着案例做一遍吧! <!DOCTYPE html> ...
- Web前端三大框架_angular.js 6.0(二)
Web前端三大框架_angular.js 6.0(一) 需要视频教程,看头像昵称处 一.Angular 6.0 1.1样式 html中引入样式:内嵌式,外链式,行内式. ng6中组件引入样式的方式也 ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(2)-easyui构建前端页面框架[附源码]
系列目录 前言 为了符合后面更新后的重构系统,本文于2016-10-31日修正一些截图,文字 我们有了一系列的解决方案,我们将动手搭建新系统吧. 后台系统没有多大的UI视觉,这次我们采用的是标准的左右 ...
- 轻量级前端MVVM框架avalon源码分析-总结
距avalon0.7版本发布有一段时间,由于之前的稳定性,就停止一段时间更新,期间研究了下Knockout源码,也尝试写了一个小型的mvvm的实现模型,仅仅只是仿造ko的核心实现,把无关的东西给剥离掉 ...
- 从原生web组件到框架组件源码(二)
innerHTML outerHTML textContent innerText 区别 <div id="test"> <span>sdsdsdsd &l ...
- 从原生web组件到框架组件源码(三)
快乐的时光都是这么短暂,转眼间,web原生组件的知识点已经学完了,这个虽然暂时不一定有用,但是随着时间的积累,一步一个脚印的积累,你会有相应的收获,希望能变得更强,比如两年前我也会想有现成的东西不用, ...
- WEB前端--返回顶部特效源码
<!DOCTYPE html><html> <head> <meta charset="utf-8" /> <title> ...
- 从原生web组件到框架组件源码(一)
温馨提醒,当你觉得看我写的很乱的时候,就对了,那是因为我查阅了大量的资料提取出来的,因为有点东西不太理解,所以你会感觉有的部分重复了,也不是重复,只是后面对前面的内容进行梳理了一些,需要耐心的看到最后 ...
随机推荐
- MIPS虚拟机代码
http://download.eeworld.com.cn/download/mamselc/472333http://download.eeworld.com.cn/detail/lamas/36 ...
- C++ 标准库概览(一分钟就看完了)
C++ 标准库以若干头文件的方式提供. 下面简单介绍一个各头文件的内容. 第一部分 容器 Containers <array> C++11 新增.提供了容器类模板 std::array,固 ...
- Docker笔记03-docker 网络模式
docker网络模式分为5种 Nat (Network Address Translation) Host other container none overlay 第一种 Nat模式 docker的 ...
- 跨越DLL边界传递CRT对象潜在的错误
跨越DLL边界传递CRT对象潜在的错误 翻译:magictong(童磊)2013年5月 版权:microsoft 原文地址:http://msdn.microsoft.com/en-us/librar ...
- Oracle高级查询、事物、过程及函数
一.SQL函数 1.分类:单行函数(日期.数值.转换.字符等),多行函数,也称为分组函数(max.min.avg.sum.row_number.rank等). 2.数值函数 abs(n):求数字n的绝 ...
- python合并多个文件
import os filelist=os.listdir('/root/Music') for item in filelist: print item newfile=open('/root/Mu ...
- RocketMQ(2)---Docker集群部署RocketMQ
RocketMQ(2)-Docker集群部署RocketMQ =前言= 1.因为自己只买了一台阿里云服务器,所以RocketMQ集群都部署在单台服务器上只是端口不同,如果实际开发,可以分别部署在多台服 ...
- hgoi#20190513
T1-Felicity is Coming! 神奇宝贝的进化方案是一个全排列,假设有三种宝可梦,那么对应就可以有: (1,2,3)(1,3,2)(2,1,3)(2,3,1)(3,1,2)(3,2,1) ...
- JVM底层实现与总结
一.类加载器 1.BootstrapClassLoader(启动类加载器) 它主要负责加载%JAVA_HOME%/jre/lib,-Xbootclasspath参数指定的路径以及%JAVA_HOME% ...
- 智能小程序关于Filter过滤器的简单使用
<filter module="swan"> export default { imgurl: (imgUrl) => { var imgurlprefix = ...