技术文章 | Technical articles

Web前端三大框架_vue源码笔记

一、VUE

1.1 MVVM

VUE也是基于MVVM模式实现的。特点就是数据双向绑定

MVVM模式中,分成三个部分:

M 模型 model

V 视图 view

VM 视图-模型 view-model

前端的本质是,

将人眼可读性强的数据,转换成机器可读性强的数据

将机器可读性强的数据,转换成人眼可读性强的数据

数据双向绑定

数据模型(机器可读性强的数据)的改变,会通过视图模型,同步给视图

通过数据绑定实现的

视图(人眼可读性强的数据)的改变,会通过视图模型,同步给数据模型

通过事件监听实现的

 

图片1.png 

早期,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中对数据做了备份

图片2.png 

vue中,数据绑定的实现是通过ES5中对象属性的特性实现的

当我们修改数据属性的时候,视图更新

 

<body>

<!-- 定义视图容器 V -->

<div id="app">

 <input type="text" v-model="title">

 <h1>{{title}}</h1>

</div>

<!-- 引入vue -->

<script type="text/javascript" src="vue.js"></script>

<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直接引入

// 基于commonjs规范

module.exports = {

// 配置vue入口文件

resolve: {

 // 别名

 alias: {

  'vue$': 'vue/dist/vue.js'

 }

},

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实例化对象中的某个属性对象)

第二个参数表示修改的属性名称

第三个参数表示修改的属性值

// 通用解决方案

// 可以修改vue实例化对象

app.$set(app, 'color', ['red', 'green'])

// 可以是vue实例化对象的某个属性对象

app.$set(app.color, '1', 'gold');

// 修改vue实例化对象中的数据

app.msg = '爱创课堂'

// 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元素的拓展,使其具有一定的行为特征

<div id="app">

<!-- 运算 -->

<h1>{{msg + '-专业前端培训学校'}}</h1>

<h1 title="info">{{info}}</h1>

<!-- js表达式 -->

<!-- v-bind指令让属性值变成js环境,可以使用js表达式 -->

<h1 v-bind:title="info">{{info.toUpperCase()}}</h1>

<h1 v-bind:title="info.toUpperCase() + ' 爱创课堂'">{{info.toUpperCase()}}</h1>

<!-- 使用:语法糖,对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方法,不能被解构

// 计算数据属性|动态数据绑定

computed: {

// es6中,属性方法省略: function

msgUpper(v) {

 console.log(this, arguments)

 // 参数和作用域都是vue实例化对象,

 // 返回值就是获取的数据

 return v.msg.toUpperCase();

 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容器元素内(包括容器元素自身)

<style type="text/css">

[v-cloak] {

display: none;

}

</style>

<div id="app" v-cloak>

<input type="text" v-model="msg">

<!-- 第二步 添加v-cloak指令 -->

<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属性中

methodsdatacomputedel等是一样的,只不过methods是专门用来定义方法的

key表示方法名称

value是方法函数

作用域this指向vue实例化对象,因此可以通过this访问vue中任何数据

注意:methods中定义的方法,不仅仅可以应用在事件中,跟data属性,computed属性一样,vue实例化后会直接添加在vue实例化对象自身,因此可以通过vue实例化对象访问其他方法

为元素绑定事件的时候,事件回调函数参数集合是可有可无的

如果没有参数集合
 此时事件回调函数的方法中,有默认参数,就是事件对象

是源生的事件对象

如果添加了参数集合

此时事件回调函数的方法中,默认没有任何参数,此时想使用什么参数,我们可以在参数集合中,传递什么参数,

使用事件对象,传递$event

vue没有实现事件委托,所有没有事件委托三个优势:减少事件数量,语言未来元素,避免内存外泄

1.10.1事件修饰符

当我们绑定键盘事件的时候,常常要判断点击的按键,为了捕获点击的某个键,我们常常判断e.keyCode键盘,来判断按下的键

vue为了简化这个过程,提供了键盘修饰符,我们可以快速的为该键绑定事件

内置了9个按键:esctabspaceenterdeleteupdownleftright

语法

v-on:keyup.修饰符=fn()

@keyup.修饰符=fn()

注意:新版本中,字母已经内置了

<div id="app">

<!-- 绑定事件 -->

<h1 v-on:click="clickH1">爱创课堂</h1>

<!-- 添加参数集合 -->

<h1 @click="clickH1(100, 200, true, $event)">爱创课堂</h1>

<h1>爱创课堂</h1>

<input type="text" @keyup="demo">

<!-- 事件修饰符 -->

<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环境,因此字符串要加引号

 

<!-- 新浪博客 -->

<div @mouseenter="showList" @mouseleave="hideList">

<span>博客</span>

<!-- <ul :class="[cls]"> -->

<!-- <ul :class="{

 hide: isHide

}"> -->

<ul :class="cls">

 <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就是样式字符串,变量不带引号,字符串添加引号


关注微信公众号“icketang”,获取最新前端资讯,学习资料

B站搜索“爱创课堂专业前端培训” 免费观看前端视频以及项目实战

学习咨询、更多前端学习资料 请添加微信“haomei0452”


QQ图片20190401143635.jpg

上一篇文章: 微信小程序开发实战教程
下一篇文章: Html5web全栈前端开发_react.js框架(一)

最新发布 | 这里有最新的文章查看更多>>

爱创推荐 | 这里有推荐的文章查看更多>>