vue_2.0_fyf

vue2.0 学习笔记

vue框架的两大核心:

一、前端开发历史

1994年可以看做前端历史的起点(但是没有前端的叫法)
1995年网景推出了JavaScript
1996年微软推出了iframe标签, 实现了异步的局部加载
1999年W3C发布第四代HTML标准,微软推出用于异步数据传输的 ActiveX(ActiveXObject),各大浏览器厂商模仿实现了 XMLHttpRequest(这是前端的真正的起始)
2006年,XMLHttpRequest被W3C正式纳入标准(这是前端正式的起始)
2006年, 发布了jQuery
2008年问世的谷歌V8引擎,发布H5的草案
2009年发布了第五代JavaScript
2009年 AngularJS 诞生

2010年 backbone.js 诞生
2011年React和Ember诞生
2014年Vue.js诞生
2014年,第五代HTML标准发布
2014年左右,4G时代到来,混合开发(js, android, ios混合开发)
2016年 微信小程序诞生
2017年 微信小程序正式投入运营
2017年底年 微信小游戏
以前的三大框架: angular, react, vue,现在: react, vue, 小程序(微信、支付宝、百度、头条)
以后: js ----- ts (typescript)

二、MV*模式

库 VS 框架

​ 把一小部分通用的业务逻辑进行封装,多个封装形成一个模块或者文件,多个模块或者文件就发展成为库或者框架

:函数库,不会改变编程的思想,如:jQuery。

框架:框架改变了编码思想,代码的整体结构,如:vue,react,小程序等等。

MVC架构模式

M:model,模型,主要完成业务功能,在数据库相关的项目中,数据库的增删改查属于模型(重点)。
V:view,视图,主要负责数据的显示
C:controller,控制器,主要负责每个业务的核心流程,在项目中体现在路由以及中间件上。

优点:耦合度低、重用性高、生命周期成本低、部署快、可维护性高、有利软件工程化管理
缺点:由于模型和视图要严格的分离,这样也给调试应用程序带来了一定的困难。

MVP架构模式

​ MVP是单词Model View Presenter的首字母的缩写,分别表示数据层、视图层、发布层,它是MVC架构的一种演变。作为一种新的模式,

M:model,模型,主要完成业务功能,在数据库相关的项目中,数据库的增删改查属于模型(重点)。
V:view,视图,主要负责数据的显示
P:Presenter负责逻辑的处理,Presenter是从Model中获取数据并提供给View的层,Presenter还负责处理后端任务。

MVP模式与MVC模式的区别:

​ 在MVP中View并不直接使用Model,而在MVC中View可以绕过Controller从直接Model中读取数据。

MVVM架构模式

MVVM是Model-View-ViewModel的缩写,MVVM模式把Presenter改名为ViewModel,基本与MVP模式相似。
唯一区别是:MVVM采用数据双向绑定的方式

vue是MVVM

MVC衍生出很多变体,MVP,MVVM,MV*, VUE是MVVM,M----V----VM,M数据,V视图, VM是负责M与V相互通信

总结:

​ 架构只是一种思维方式,不管是MVC,MVP,还是MVVM,都只是一种思考问题解决问题的思维,其目的是要解决编程过程中,模块内部高内聚,模块与模块之间低耦合,可维护性,易测试等问题。
​ 架构在于,做好代码的分工,配合

三、开发工具

vscode,webstorm,HbuilderX等等

四、vue框架的初识

vue官网](https://cn.vuejs.org/)

作者:尤雨溪 ( 华人 ) , 前Google员工

vue的介绍

  • 构建数据驱动的web应用开发框架

  • Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架

  • Vue 被设计为可以自底向上逐层应用

  • Vue 的核心库只关注视图层

  • vue框架的核心:数据驱动组件化

  • 便于与第三方库或既有项目整合,另一方面,当与单文件组件和 Vue 生态系统支持的库结合使用时,
    Vue 也完全能够为复杂的单页应用程序提供驱动。

  • Vue 不支持 IE8 及以下版本

vue的示例代码

<body>
  V
  <div id="app">
    要被控制的html{
  {key}}
  div>
body>
<script src="vue.js">script>
<script>
	let vm = new Vue({
    
    	el:'#app'  //要控制的那片html代码  
    	data:{
    key:value}//数据  M
  })
script>

vue框架的理解

1、首先:一个页面包括:结构(HTML模板),表现(css),行为(js)
2、其次:原生JS中的做法:写好HTML的模板和css样式,用js产生数据(逻辑),通过dom的方式控制数据显示在HTML中的那个位置,包括如何显示(DOM的方式改变样式)
3、vue框架:vue中,写好HTML模板,声明式地告知vuejs库,数据显示在何处,在vue对象中处理数据,不用做DOM操作(vuejs库负责)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9pJFGpla-1617256399567)(C:\Users\31759\AppData\Roaming\Typora\typora-user-images\1590679733619.png)]

简单理解,new出来一个Vue的实例,传一堆配置参数,控制一片html

记住一点:有了vue,不用程序员操作dom了,因为,vue把dom操作都做好了。

数据驱动和声明式渲染

1、数据驱动
数据驱动,就是通过控制数据的变化来改变(驱动)DOM。背后使用了观察者模式,靠数据的变化来控制页面的变化。这是vue框架的核心,第一周,一定要把数据驱动的思路和编程习惯养成。

2、声明式渲染

声明的意思就是告知,广而告之,即告知程序(Vue框架),在何处渲染什么数据

Vue 实现数据绑定的原理(面试题)

vue数据绑定是通过 数据劫持观察者模式 的方式来实现的
1、数据劫持:使用Object.defineProperty();
当你把一个普通的 JavaScript 对象(json)传入 Vue 实例作为 data 选项,Vue 将遍历此对象所有的属性,并使用 Object.defineProperty 把这些属性全部转为 getter/setter。
目的是:感知属性的变化。当给属性赋值时,程序是能够感知的(知道的)。如果知道的话,就可以控制属性值的有效范围,也可以改变其它属性的值等。
Object.defineProperty()函数:https://blog.csdn.net/jiang7701037/article/details/102785223

​ 2、观察者模式(发布订阅模式):
​ 目的:当属性发生变化时,其它使用该数据地方跟着变化

五、vue语法(view层)

data选项

功能:

​ data选项中存储的是页面中需要显示的数据(当然数据可以进行一定的加工后再显示)

是初始化数据的位置,是元数据,是vue实例的一个实例属性,可以接受的数据类型: number/string/boolean/array/json/undefined/null/function

数据绑定

https://cn.vuejs.org/v2/guide/syntax.html#%E6%8F%92%E5%80%BC

插值表达式

功能:可以让html标签里的内容变成动态的(从data中获取), 使用 mustache语法

格式:{ {变量|属性名|表达式|函数调用等等}};

示例:

Message: { { msg }}
new Vue({ el:"#app" msg:"hello 哥们!" });

这种写法叫作:声明式渲染,即:只需要告知vue,数据在何处显示。

内容指令

指令名:v-text和v-html

指令是什么? 指令就是html自定义属性

1、v-text="数据名"

功能:可以让html标签里的内容变成动态的(从data中获取),相当于innerText。

​ 示例:

内容:

对比v-text和插值表达式:

​ 1)、当网络速度慢的时候,插值表达式会在页面上出现 { {}} 的显示,但是指令v-text不会,因为,v-text是自定义属性,最多不做解读。

​ 2)、插值表达式更加灵活,可以在标签里面的某个地方显示,但是v-text会让整个标签的内容全部变化。

2、v-html="数据" 非转义输出

​ 功能:可以让html标签里的内容变成动态的(从data中获取),但是不会对内容中的html标签进行转义。相当于innerHTML。

​ 示例:

 输出真正的 HTML
 

内容:

双花括号和 v-text(相当于innerText)会将数据解释为普通文本。
v-html相当于innerHTML

属性指令

​ 指令名:v-bind

​ 功能:可以让html标签里的**属性(名和值)**变成动态的(从data中获取)

1、 属性动态绑定:v-bind:html属性="数据" 简写 :html属性=“数据”`

2、 属性动态绑定: v-bind:[属性名]="数据"

示例:

注意: 属性是布尔值 的情况

   

​ 如果 isButtonDisabled 的值是 null、undefined 或 false,则 disabled 属性甚至不会被包含在渲染出来的 元素中

javascript表达式

在dom里面插入数据,除了可以写原始的数据,还可以使用javascript表达式,

格式:{ {数据+表达式}}v-指令="数据+表达式"

示例:

{
  { number + 1 }}     
{
  { ok ? 'YES' : 'NO' }}     
{
  { 'i love you'.split('').reverse().join('') }}

注意:

不能使用语句 ,流程控制可以使用三元表达式代替

条件渲染(指令)

https://cn.vuejs.org/v2/guide/conditional.html

指令名: v-if 和 v-show

功能:一段dom可以根据条件进行渲染

<div v-show="true">box1div>
<div v-if="false">box2div>

v-show VS v-if

v-show=“布尔” v-if=“布尔”
区别 操作css 操作dom
场景 适合频繁切换 适合不频繁切换
性能消耗 初始渲染消耗 频繁切换消耗

面试题: v-if和 v-show的区别?

相同点:
v-show和 v-if都是 控制 dom元素 的 显示和隐藏 的。

不同点:
1、原理:

​ v-show是通过控制元素的样式属性display的值,来完成显示和隐藏;
​ v-if是通过对dom元素的添加和删除,完成显示和隐藏

​ 2、使用场景:由原理(做法)得出使用场景的区别

​ v-show:使用在dom元素频繁切换的场景
​ v-if:当dom元素的切换不频繁,可以使用。特别是,首次元素处于隐藏的情况下。

补充: dom的操作(如:创建和删除)是非常耗性能的。为什么?
请看:https://blog.csdn.net/jiang7701037/article/details/98516468

另外,v-if指令还可以结合v-else-if , v-else一起使用。

示例:

宝宝

大宝宝

非宝宝

列表渲染(指令)

​ https://cn.vuejs.org/v2/guide/list.html

指令名: v-for

功能:把数据进行循环显示在html里(渲染)。推荐操作的数据类型:数组、对象、字符串、数字

​ 格式:

用in或者用of都可以:

  • { {值}}
  • { {值}}
  • 各种情况:

    <li v-for="(值,索引) in 数组">{
      {值}}/{
      {索引}}li>
    <li v-for="(对象,索引) in 数组">{
      {对象.key}}/{
      {索引}}li>
    <li v-for="(值,键) in 对象">
    <li v-for="(数,索引) in 数字">
    <li v-for="(单字符,索引) in 字符">
    

    注意:

    空数组,null,undefined不循环

    也可以进行循环嵌套

    v-for和v-if使用在同一个标签里时,v-for 的优先级比 v-if 更高,即:if是套在for里的,先循环再判断

    列表渲染时的key:

    ​ 在标签里使用属性key,可以唯一标识一个元素。

     1、当 Vue.js 用 v-for **更新**已渲染过的元素列表时,它默认用“就地复用”策略。即:**尽量不进行dom元素的操作,只替换文本**。
    

    ​ 2、如果你希望进行dom操作,就用key,因为key的目的是为了唯一标识一个元素。

    ​ 有了key后,可以跟踪每个节点的身份,从而重用和重新排序现有元素
    ​ 建议尽可能在使用 v-for 时提供 key attribute,除非遍历输出的 DOM 内容非常简单,或者是刻意依赖默认行为以获取性能上的提升。

    注意:

    key不要使用(数组)下标

    事件绑定(指令)

    https://cn.vuejs.org/v2/guide/events.html

    指令名:v-on

    ​ v-on指令可以简写为:@

    功能:绑定事件,vue通过v-on指令把事件和处理函数进行绑定。

    ​ 事件处理函数需要放在methods选项当中去,事件名 不带on,函数可以按照ES5的写法,也可以按照ES6的写法。

    格式:

    <input type="button" v-on:事件名="javascript代码">
    <input type="button" v-on:事件名="方法">
    <input type="button" v-on:事件名="方法(参数)" >
    <input type="button" v-on:事件名="方法($event,参数)">
    
    new Vue({
       
      methods:{
       
        方法1:function(ev,参数){
       
            业务
            这里面的this是vue对象本身
        }
        方法2(ev,参数){
       
             业务
    	}
      }
    })
    

    获取事件对象:

    1、 不传参,默认第一个参数,就是事件对象

    ​ 如:

    
    ………………
    checkData4(ev){
    	console.log('事件对象',ev);
    },
    

    2、 传参,事件对象需要手动传入(使用官方提供的 $event)

    如:

    
    ………………
    checkData5(str,ev){
        console.log('事件对象',ev);
        console.log('参数',str);
    },
    

    事件处理函数的this:

    1、methods选项里的函数里的this是vue对象本身,所以,事件处理函数里的this也是vue对象本身

    2、vue提供的选项的值如果是函数时,不可用箭头函数 , 会造成this丢失

    事件修饰符

    .stop 阻止单击事件继续传播 .prevent 阻止默认行为 .capture 使用事件捕获模式 .self 点到自己时才触发,不是从其它地方(事件流的流)流过来的 .once 只会触发一次 .passive onScroll事件 结束时触发一次,不会频繁触发,移动端使用

    注意:

    使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生。因此,用 v-on:click.prevent.self 会阻止所有的点击,而 v-on:click.self.prevent 只会阻止对元素自身的点击。

    按键修饰符

    
    
    .left 上下左右 .enter 回车 .13 可以使用键码
    .ctrl .alt .shift .exact 精准控制,@键盘事件.修饰符1.修饰符2.exact 只有1+2才可触发 1+2+3不可以
    .left .right .middle 鼠标中键

    双向绑定(指令)_表单控件绑定

    https://cn.vuejs.org/v2/guide/forms.html

    指令名:v-model

    功能:视图控制数据,数据也可控制视图,这就是双向绑定,可通过属性+事件绑定实现。而vue中直接提供了一个指令v-model直接完成(v-model 本质上不过是语法糖)。v-model指令只能使用在表单元素上。

    不使用v-model完成双向绑定
    <input type="text" :value="data数据" v-on:input="changeIptValue">
    
    使用v-model完成双向绑定
    <input type="text" v-model="data数据">
    

    其它表单元素的双向绑定

    https://cn.vuejs.org/v2/guide/forms.html

    表单修饰符

    .number 把标签的值转成数字赋给vue的数据 .trim 删除前后空格 .lazy 确认时才修改model数据

    示例:

    //需求:    
    //在下拉框里选择 房间类型(一个房子住多少人)
    //动态产生 相应数量的文本框
    
     
    
    

    指令总结

    ​ 指令 (Directives) 是带有 v- 前缀的特殊属性。其实就是html标签的里的自定义属性。指令属性的值预期是单个 JavaScript 表达式 (v-for 是例外情况)。指令的职责是,当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM,以下是官方的指令,程序员也可以自定义指令。

    常见指令:

    • v-text: 更新元素的 textContent。如果要更新部分的 textContent ,需要使用 { { Mustache }} 插值。
    • v-html:更新元素的 innerHTML
    • v-bind:动态地绑定一个或多个属性(特性),或一个组件 prop 到表达式。
    • v-show:根据表达式值的真假,切换元素的 display (CSS 属性)。
    • v-if:根据表达式的值的真假条件渲染元素(与编程语言中的if是同样的意思)
    • v-else:表示否则(与编程语言中的else是同样的意思)
    • v-else-if:(与编程语言中的else if是同样的意思)
    • v-for:可以循环数组,对象,字符串,数字,
    • v-on:绑定事件监听器。事件类型由参数指定。
    • v-model:在表单控件或者组件上创建双向绑定
    • v-pre:跳过这个元素和它的子元素的编译过程。可以用来显示原始 Mustache 标签。跳过大量没有指令的节点会加快编译。
    • v-cloak:防闪烁,模板没编译完,电脑配置差,有可能会看到{ {}},体验不佳,不如用css先隐藏,之后再显示,包括被包裹的子元素。这个指令保持在元素上直到关联实例结束编译。和 CSS 规则,如 [v-cloak] { display: none } 一起用时,这个指令可以隐藏未编译的 Mustache 标签直到实例准备完毕。
    • v-once:只渲染元素和组件一次。随后的重新渲染,元素/组件及其所有的子节点将被视为静态内容并跳过。这可以用于优化更新性能。

    指令缩写:

    v-bind 缩写 是冒号
    v-on 缩写是 @

    样式操作

    https://cn.vuejs.org/v2/guide/class-and-style.html

    操作样式,就是属性绑定,只不过绑定的属性是class和style,vue在class和style属性上做了加强,还可以使用对象,数组的方式。

    绑定姿势

    属性值的类型支持

    字符串/对象 / 数组

    
    

    class的属性值(对象的方式)示例:

     //
     <div class='big-box' :class="{active:isActive,borderbox:isBorder}"></div>
      let vm = new Vue({
       
            el: "#app",
            data: {
       
                  isActive:true,
                  isBorder:true
            }
        });
    
    

    注:vue绑定的class属性和普通的class属性可以共存

    class的属性值(数组的方式)示例:

    <div v-bind:class="[activeClass, errorClass]"></div>
    data: {
       
         activeClass: 'active',
         errorClass: 'text-danger'
    }
    
    

    style的属性值(对象的方式)示例:

    <div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
    
    data: {
       
          activeColor: 'red',
          fontSize: 30
    }
    
    

    style的属性值(数组的方式)示例:

    <div :style="[obj1,obj2]"> 我是div</div>
     data: {
       
                obj1:{
       
                        width:"200px",
                        height:"150px"
                },
                obj2:{
       
                       "background-color":"red"
                }
            }
    
    

    示例:

    todoList 练习的实现

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lmQmxH3r-1617256399571)(C:\Users\31759\AppData\Roaming\Typora\typora-user-images\1594365849928.png)]

    为了让大家体会vue是数据驱动,根据班级情况尝试扩展如下:
    二阶段的运动
    全选反选(购物车)
    增删改查(或者留言板,或者员工信息)

    非响应式情况

    ​ 在vue中,使用某些方式改变数据(model层)时,vue不会把结果呈现在页面上(view层),这就是vue出现的非响应式的情况:

    • 对数组使用了 非变异 (non-mutating method) 方法。因为,没有改变原始数组的内容(如:concat)

    • 修改数组的长度时

    • 修改数组索引上的值(根索引)时

    • 给对象添加新的属性时。

      ​ 所以,强烈建议:不要修改数组的根键,不要修改数组的长度,可以把未来需要的数据都声明在data选项内部,不要对数组使用非变异的api(数组的变异方法:https://cn.vuejs.org/v2/guide/list.html#%E5%8F%98%E6%9B%B4%E6%96%B9%E6%B3%95)

    vue也提供了非响应式问题 解决方案(尽量不要使用)

    Vue.set|this.$set(数组, index, value)

    Vue.set|this.$set(对象, key, value)

    this.$forceUpdate() 强制刷新


    六、vue语法(model层)vue的配置项

    data属性:

    不再说了

    计算属性

    ​ 在模板中放入太多的逻辑会让模板过重且难以维护,而且不好阅读。计算属性computed来帮忙。

    ​ 计算属性是一个函数,是经过元数据(data里)进一步运算后的数据,计算属性的优点是:当元数据不发生变化时,不会再做计算(即:缓存),只有元数据发生变化时,才做计算。是响应式的,需要在模板中渲染才可调用

    语法

    //定义
    computed:{
       
      计算属性: function(){
       return 返回值}		
    }
    
    //使用
    使用:	{
       {
       计算属性}} |  v-指令="计算属性"
    

    computed VS methods

    methods computed
    方法每次调用都会进行运算 基于它们的响应式依赖进行缓存的,如果依赖没有变化,就不再运算
    一般 性能高
    { {methodname()}} { {computedname}}
    适合强制执行和渲染 适合做筛选

    属性检测(侦听属性)

    https://cn.vuejs.org/v2/guide/computed.html#%E8%AE%A1%E7%AE%97%E5%B1%9E%E6%80%A7-vs-%E4%BE%A6%E5%90%AC%E5%B1%9E%E6%80%A7

    ​ 需要在数据变化时执行异步或开销较大的操作时,这个时候需要属性检测watch。而不要使用计算属性,因为计算属性是同步的(需要立即返回结果)

    定义一个选项

    watch:{
       
      数据名:'methods的里函数名'    //数据名==data的key
      数据名:函数体(new,old){
       }
      数据名:{
       
        handler:fn(new,old){
       },
        deep: true //深度检测,当侦听的属性是个对象,修改对象的某个键时,就能检测到
        immediate: true //首次运行,要不要监听
      }
    }
    

    示例:

    请输入您的问题:<input type="text" v-model.lazy="question" /><br/>
             答案:<input type="text" v-model="answer" /><br/>
            
     let vm = new Vue({
       
            el:"#app",
            data:{
       
                question:"",
                answer:""
            },
            watch:{
       
                question:function(){
       
                    setTimeout(()=>{
       
                        this.answer = "吃的是草"
                    },2000);
                }
            }
        });
    

    深度检测:

    <div id="app">
        <input type="button" value="测试" @click="fn" />
    </div>
    
    let vm = new Vue({
       
            el:"#app",
            data:{
       
                person:{
       
                    name:"张三疯",
                    wife:{
       
                        name:"梅超风"
                    }
                },
            },
            methods:{
       
                fn(){
       
                    this.person.name="李思峰";
                }
            },
            watch:{
       
                person:{
       
                    deep: true, //深度检测,当侦听的属性是个对象,修改对象的某个键时,就能检测到
                    handler:function(){
        
                       console.log("person变了");
                    },
                    immediate: true
                }
            }
        });
    

    计算属性 VS 函数 VS 属性检测

    计算属性(computed) 函数(methods) 属性检测(侦听)(watch)
    为了显示而用 只是处理逻辑,跟普通的函数一样 属性变化的检测(相当于事件),当属性的值发生变化时,可以调用函数
    依赖模板调用 √(在模板上调用的) -(可以在模板使用) ×(不能在模板上使用)
    是否缓存 ×
    异步 ×(必须是同步)

    自定义指令

    https://cn.vuejs.org/v2/guide/custom-directive.html

    系统指令在不够用的情况下,考虑自定义,指令是个函数|对象,用来操作dom的, 里面的this 返回window

    全局定义

    Vue.directive('指令名',{
       
    		    bind:fn(el,binding){
       }//指令第一次绑定到元素时调用,此时DOM原始还没有显示在页面上
    			inserted:fn(el,binding){
       } //绑定指令的DOM元素插入到父节点时调用。DOM已经渲染(显示)
    			update:fn(el,binding){
       }  //指令所在的元素的model层的数据,view有更新请求时
    			componentUpdated:fn(el,binding){
       }  //更新完成时
    })
    
    
    • **指令名:**定义指令时,不用加 v- , 使用指令时,加 v-

    • 钩子函数的参数:

      钩子函数的参数 (即 el、binding、vnode 和 oldVnode)。
      https://cn.vuejs.org/v2/guide/custom-directive.html#%E9%92%A9%E5%AD%90%E5%87%BD%E6%95%B0%E5%8F%82%E6%95%B0

    ​ name: 指令名(不带v-)

    ​ arg:写在指令名后面的参数,如:v-myfocus:id , arg就是id v-bind:value

    ​ expression: 等号后面的表达式,如:v-myfocus:id=“msg+‘1’” ,expression就是msg+‘1’。

    ​ value:绑定数据的值,如:v-myfocus:id=“msg+‘1’” , value就是msg的值和1拼接的结果

    示例:

    //定义指令:
    Vue.directive('myfocus', {
      inserted: function (el) {   // 当被绑定的元素插入到 DOM 中时……
        // 聚焦元素
        el.focus()
      }
    })
    使用指令
    

    全局定义格式(简写)

    Vue.directive('指令名', function(el,binding){ //等价于:bind + update
    
    })
    

    钩子函数的详解:

    bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
    inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
    update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新
    componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。
    unbind:只调用一次,指令与元素解绑时调用。

    局部定义

    new Vue({
       
    	directives:{
       
        指令名	: function(el,binding){
       },//简写方式: bind + update
      	指令名(el,binding){
       },
        指令名:{
       
    				inserted:fn(el,binding){
       }		//绑定指令的元素插入到父节点时调用  v-focus
    				bind:fn	//指令第一次绑定到元素时调用	v-drag
    				update:fn	//指令所在的元素的model层的数据,view有更新请求时
    				componentUpdated:fn	//更新完成时
        }
      }
    })
    

    示例:

    回到顶部

    //自定义指令的代码
    // 注册一个全局自定义指令 `v-pagetop`
    Vue.directive('pagetop', {
       
        inserted: function (el) {
       
            el.onclick = function(){
       
                document.body.scrollTop = 0;
                document.documentElement.scrollTop = 0;
            }
        }
    })
    
    //使用指令
    <div id="app" >
            <div v-pagetop
            style="width: 100px;height: 100px;background-color:red;">
                回到顶部
            </div>
        </div> 
    
    

    过滤器

    https://cn.vuejs.org/v2/guide/filters.html

    对数据在模板中的表现过滤,符合预期,比如数据是0和1,想要表现成对错、成功失败、数据需要过滤器来格式化,vue1.x版本有系统自带过滤器,vue2.x之后完全需要自定义,没有自带过滤器

    全局定义
    Vue.filter('过滤器名称',函数(要过滤的元数据,参数1,参数n){
       
               		过滤器的功能
               		return 过滤的结果           
               })
    
    使用
    {
      {数据名 | 过滤器名(参数1,参数2)}}
    :属性="数据| 过滤器名(参数1,参数2)
    
    局部定义
    filters:{
       
      过滤器名称:函数(要过滤的元数据,参数){
       
            过滤器的功能
            return 过滤的结果      
      }	//函数必须要有返回值
    }
    

    预购阿里云服务器(ecs云服务器)

    链接 -》个人云 -》突发性能型 t5(74/年)-》系统(centOs系统,认准ecs云服务器-》控制台做一下实名认证

    域名购买

    链接

    混入

    意义在于分发 Vue 组件中的可复用功能,混入对象就是一个json对象,json对象的属性就是 Vue对象的配置项(data,methods等等,但是没有el)

    用法

    //定义
    
    let mixin1 = {
       
      data: ...
      methods: ...
    }
    let mixin2 = {
       
      data: ...
      methods: ...
    }
    
    //组件内部混入 组件选项内
      mixins: [mixin1,mixin2] //当混入的键与引入键冲突时以组件内的键为主
    
    //根实例混入
      new Vue({
        
          el:"#app",
          data:{
       
          	msg:"hello"
      	  }
          mixins: [mixin1,mixin2]
    })
    
    //全局混入:
     Vue.mixin(mixin1)
    

    ​ 混入普通选项与组件(vue对象)选项合并,遇冲突,以组件(Vue对象)为主。

    ​ 如果是钩子函数,那么都会调用(混入的钩子先调用)

    虚拟DOM和diff算法

    什么是虚拟DOM(virtual DOM):
    所谓的虚拟 dom,也就是我们常说的虚拟节点,它是通过JS的Object对象模拟DOM中的节点,然后再通过特定的render(渲染)方法将其渲染成真实的DOM的节点。

    为什么使用虚拟DOM:
    使用js操作DOM时(增删改查等等),那么DOM元素的变化自然会引起页面的回流(重排)或者重绘,页面的DOM重绘自然会导致页面性能下降,那么如何尽可能的去减少DOM的操作是框架需要考虑的一个重要问题!
    https://blog.csdn.net/jiang7701037/article/details/98516468

    真实DOM和虚拟DOM的区别:
    虚拟DOM不会进行排版与重绘操作
    真实DOM频繁排版与重绘的效率是相当低

    虚拟DOM进行频繁修改,然后一次性比较并修改真实DOM中需要改的部分,最后并在真实DOM中进行排版与重绘,减少过多DOM节点排版与重绘损耗

    虚拟DOM有效降低的重绘与排版,因为最终与真实DOM比较差异,可以只渲染局部

    diff算法:
    虚拟DOM,是一种为了尽可能减少页面DOM频繁操作DOM的方式,那么在虚拟DOM中,通过什么方式才能做到呢? 就是Diff算法进行对比

    diff算法的原理:
    逐步解析newVdom的节点,找到它在oldVdom中的位置,如果找到了就移动对应的DOM元素,如果没找到说明是新增节点,则新建一个节点插入。遍历完成之后如果oldVdom中还有没处理过的节点,则说明这些节点在newVdom中被删除了,删除它们即可。

    总结:

    1、产生两个虚拟DOM树:newVDom,oldVDom。

    2、oldVDom和真实DOM保持一致

    3、操作的newVDom

    4、操作完毕后,通过diff算法对比newVDom和oldVDom的差异,并在oldVDom标注哪些节点要删除,哪些节点要增加,修改

    5、根据oldVDom操作真实的DOM,让真实Dom和oldVDom保持一致

    vue-dev-tools安装

    方案1: 登录谷歌应用商城->索引vue-dev-tools->安装->重启浏览器

    方案2: https://blog.csdn.net/jiang7701037/article/details/99708017

    七、组件

    组件的概念:

    ​ 组件是自定义标签,vueJS提供的组件可以让程序员自定义标签,对页面进行模块化。每个标签里包含HTML,CSS,JS。

    ​ vue的组件就是一个vue对象。(vue的两大核心:数据驱动,组件化) 。vue对象的配置项,在vue组件里也可以使用。
    ​ 配置项如下:
    ​ 没有el属性。
    ​ template:html模板代码,只能有一个根标签
    ​ data:必须是个函数
    ​ methods:

    ​ ………………………………

    一个完整的标签格式是: <标签名 属性名=“属性值" 事件=”函数“>内容

    vue组件的基本使用(标签名):

    1、定义组件:

    ​ 第一种:

    let 组件变量名= Vue.extend({
       
            template:'
    { {msg}},我是header组件
    '
    data:function(){ return { msg:”hi” } }, });

    第二种(简化写法):

    let 组件变量名={
       
            配置项
    }; 
    
    2、注册组件:

    全局注册:

    Vue.component('组件名',组件变量名);
    

    全局注册的组件,在任何vue对象里都可以使用

    局部注册:

    //在vue对象的components选项里进行注册
    new Vue({
       
         el:
         components:{
       
        	 组件名:组件变量名
         }     
    });
    

    局部注册的组件,只能在当前vue对象(组件)里使用。

    3、使用组件:

    组件就是自定义标签,所以,使用组件,就跟使用标签是同样的。

    <组件名>
    
    4、组件嵌套:

    把一个组件的标签写在另外一个组件的template里,就是组件嵌套。

    如:

      //子组件 
      let myComSon = {
       
            template:"
    我是son里的div:{ {msg}}
    "
    , data:function(){ return { msg:"hi:son" } } }; //父组件 let myComParent = { template:`

    我是p:{ {msg}}

    `
    , data:function(){ return { msg:"hi" } }, components:{ // 局部注册了另外一个组件 "my-com-son":myComSon } };
    5、组件编写方式与 Vue 实例的区别:

    ​ 1、 data是个函数(面试题)
    ​ 一个组件的 data 选项必须是一个函数,且要有返回object,只有这样,每个实例(vue组件对象)就可以维护一份被返回对象的独立的拷贝,否则组件复用时,数据相互影响,也就是说,组件的作用域是独立的。
    ​ 2、组件模板(html代码)只能有一个根标签
    ​ 3、组件名不可和html官方的标签名同名
    ​ 4、组件没有el选项,只有根实例存在el
    ​ 5、书写:组件名如果小驼峰,那么使用时,用短横线(羊肉串的写法),或者组件名直接都用大驼峰。

    组件的属性(标签的属性)

    使用props来完成组件属性的声明。 props是外部给组件传入的数据。而组件的data是组件内部的数据。

    使用 Prop 传递静态数据

    1)、在组件内部增加配置项 props来声明组件里的属性。props里面可以声明多个属性,所以,是个数组。

      let myComParent = {
       
            props:["name","sex"], //声明了两个自定义属性
            template:`

    我是p:{ {msg}}

    人的信息:

    姓名:{ {name}}

    性别:{ {sex}}

    `
    , data:function(){ return { msg:"hi" } } };

    2)、使用组件时,给属性传入数据:

    
    <my-com-parent name="张三疯他哥" sex="">my-com-parent>
    

    总结提升认识:

    把封装组件和封装函数进行类比:

    ​ 在组件内部用props声明的属性,相当于封装函数时声明的形参。

    ​ 使用组件时,相当于调用函数,传递实参。

    动态Prop

    组件属性和官方标签的属性是同样的道理,所以,给组件的属性也可以v-bind 数据。即:绑定动态的数据

    <my-com-parent v-bind:name="name" sex="">my-com-parent>	
    

    ​ 如果你想把一个对象的所有属性作为 prop 进行传递,可以使用不带任何参数的 v-bind (即用 v-bind 而不是 v-bind:prop-name)。例如,已知一个 todo 对象:

    todo: {
       
      text: 'Learn Vue',
      isComplete: false
    }
    
    <todo-item  v-bind="todo"></todo-item>
    
    等价于:
    <todo-item 
      v-bind:text="todo.text"
      v-bind:is-complete="todo.isComplete"
    ></todo-item>
    
    

    奇葩情况

    在 JavaScript 中对象和数组是通过引用传入的,所以对于一个数组或对象类型的 prop 来说,在子组件中改变这个对象或数组本身将会影响到父组件的状态

    Prop 验证

    vueJS还提供了对属性类型的验证,包括属性默认值,是否必须等等。这时候,props不能使用数组,而需要使用对象。

    如:

      props:{
       
                "name":{
       
                    type:String

    你可能感兴趣的:(vue.js)