vue基础

VUE基础

  • 1.VUE
  • 2.vue基础
    • 2.1 概述
    • 2.2 声明式渲染和组件化
      • 2.2.1 声明式渲染
      • 2.2.2 组件化应用构建
    • 2.3 开发模式
  • 3.vue入门
    • 3.1 传统DOM与vue实现对比
    • 3.2 vue devtools工具安装
    • 3.3 vue数据双向绑定原理 ***
    • 3.4 vue模版语法
      • 3.4.1 插值表达式
      • 3.4.2 指令
  • 4.常用指令
    • 4.1 v-cloak *
    • 4.2 双向数据绑定指令 v-model ***
    • 4.3 v-once *
    • 4.4 绑定属性 v-bind**
    • 4.5 v-on***
      • 4.5.1 基本使用
      • 4.5.2 事件修饰符
      • 4.5.3 按键修饰符
      • 4.5.4 自定义修饰符
    • 4.6 循环分支(判断)指令
      • 4.6.1 循环指令***
      • 4.6.2 分支指令 - 判断条件
    • 4.7 综合案例:简易购物车
    • 4.8 样式绑定
      • 4.8.1 class样式绑定
      • 4.8.2 style样式处理
    • 4.9 v-model修饰符
    • 4.10 综合案例: 购物车全选/全不选
  • 5.vue常用特性
    • 5.1 自定义指令
    • 5.2 计算属性 - computed**
    • 5.3 监听器 - watch***
    • 5.4 综合案例:继续完善购物车
    • 5.5 过滤器 - filters
    • 5.6 混入 - mixins
    • 5.7 生命周期***
    • 5.8 虚拟DOM与diff算法
  • 6.网络请求
    • 6.1 XMLHttpRequest
    • 6.2 jQuery
    • 6.3 fetch
    • 6.4 axios
      • 6.4.1 基本使用
      • 6.4.2 拦截器

1.VUE

  • 了解什么是VUE

2.vue基础

2.1 概述

官网:https://cn.vuejs.org/

Vue.js是一套构建用户界面的渐进式框架。

Vue 采用自底向上增量开发的设计。

Vue 的核心库只关注视图层,它不仅易于上手,还便于与第三方库或既有项目整合。

另一方面,当与单文件组件和 Vue 生态系统支持的库结合使用时,Vue 也完全能够为复杂的单页应用程序提供驱动。(SPA单页面应用,所有的显示都在一个页面当中)

渐进式:一步一步,不是说你必须一次把所有的东西都用上

自底向上设计:是一种设计程序的过程和方法,就是先编写出基础程序段,然后再逐步扩大规模、补充和升级某些功能,实际上是一种自底向上构造程序的过程

vue基础_第1张图片

Vue从设计角度来讲,虽然能够涵盖这张图上所有的东西,但是你并不需要一上手就把所有东西全用上,都是可选的。

声明式渲染和组件系统是Vue的核心库所包含内容,而路由、状态管理、构建工具都有专门解决方案。这些解决方案相互独立,我们可以在核心的基础上任意选用其他的部件,不一定要全部整合在一起。

2.2 声明式渲染和组件化

初始化项目 npm init -y

可以使用npm i -S vuecnpm i -S vue 下载vue的资源包,将dist/vue.js以及 v e.min.js 移动到lib目录下

2.2.1 声明式渲染

Vue.js的核心是一个允许采用简洁的模板语法来声明式的将数据渲染进DOM的系统,例如:

{{ message }}

2.2.2 组件化应用构建

组件系统是Vue的另一个重要概念(后续学习),因为它是一种抽象的允许我们使用小型、独立和通常可复用的“小积木”构建大型应用。几乎任意类型的应用界面都可以抽象为一个组件树。

vue基础_第2张图片

2.3 开发模式

注意:开发模式≠设计模式

开发模式,就是一个开发项目的方式或者标准。

比较常见的三种开发模式:MVC、MVP、MVVM

  • MVC

MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑(C)、数据(M)、界面显示(V)分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。

vue基础_第3张图片

  1. 用户可以向 View 发送指令(DOM 事件),再由 View 直接要求 Model 改变状态。

  2. 用户也可以直接向 Controller 发送指令(改变 URL 触发 hashChange 事件),再由Controller 发送给 View。

  3. Controller 非常薄,只起到路由的作用,而 View 非常厚,业务逻辑都部署在 View。

优点 ----- 高内聚 低耦合

耦合性低,重用性高,部署快,可维护性高,有利于软件工程化管理

缺点

由于模型model和视图view要严格的分离,给前端程序带来了很大的困难,每次操作需要彻底的测试

  • MVP

MVP是Model-View-Presenter简称,MVP是从经典的模式MVC演变而来,它们的基本思想有相通的地方Controller/Presenter负责逻辑的处理,Model提供数据,View负责显示:

vue基础_第4张图片

  1. 各部分之间的通信,都是双向的。

  2. View 与 Model 不发生联系,都通过 Presenter 传递。可以将一个Presenter用于多个视图,而不需要改变Presenter的逻辑。这个特性非常的有用,因为视图的变化总是比模型的变化频繁。

  3. View 非常薄,不部署任何业务逻辑,称为"被动视图"(Passive View),即没有任何主动性,而 Presenter非常厚,所有逻辑都部署在那里。

缺点

由于对视图的渲染放在了Presenter中,所以视图和Presenter的交互会过于频繁。一旦视图需要变更,那么Presenter也需要变了。

  • MVVM
    • M:(model)普通的javascript数据对象
    • V:(view)前端展示页面
    • VM:(ViewModel)用于双向绑定数据与页面,对于我们的课程来说,就是vue的实例

MVVM 模式将 Presenter 改名为 ViewModel,基本上与 MVP 模式完全一致。唯一的区别是,它采用双向绑定(data-binding):View的变动,自动反映在 ViewModel,反之亦然。这种模式下,页面输入改变数据,数据改变影响页面数据展示与渲染

vue使用MVVM响应式编程模型,避免直接操作DOM , 降低DOM操作的复杂性。

vue基础_第5张图片

优点

  • 低耦合。视图(View)可以独立于Model变化和修改,一个ViewModel可以绑定到不同的View上,当View变化的时候Model可以不变,当Model变化的时候View也可以不变。

  • 可重用性。你可以把一些视图逻辑放在一个ViewModel里面,让很多view重用这段视图逻辑。

  • 可测试。界面素来是比较难于测试的,而现在测试可以针对ViewModel来写。

3.vue入门

3.1 传统DOM与vue实现对比

假设需要输出 “hello bk2007”

传统开发模式的原生js,jQuery代码如下:

<div id="app">div>

<script>
  var msg = 'hello every';
  var oApp = document.getElementById('app');
  oApp.innerHTML = msg;
script>
<script src="../js/jquery.js">script>

<script>
  var msg = 'hello every';
  $('#app').html(msg);
script>

步骤

  1. 定义用于填充数据的标签

  2. 引入vue.js库文件( 学习测试使用开发版本,项目上线换成生产版本 )

  3. 使用vue语法实现需求

  4. 将vue提供的数据填充到“第1步”中的标签里

代码如下

<body>
 
  <div id="app">{{msg}}div> 
body> 
 
<script src="../js/vue.js">script>
<script type="text/javascript"> 
  // 3. 使用vue语法实现需求 
  var vue = new Vue({ 
    // 4. 将vue提供的数据填充到“第1步”中的标签里 
    el: "#app", 
    data: { 
      msg: "hello bk2007"
    }
  }); 
script> 

Vue实例细节分析:

  • Vue参数对象属性

    • el:元素挂载的位置,值可以是CSS选择器或DOM元素

    • data:模型数据,值是一个对象

  • 插值表达式 {{msg}}

    • 将数据填充到HTML标签中

了解:前端渲染方式

vue基础_第6张图片

前端渲染方式有:

  • 原生JavaScript拼接字符串(维护困难) - 吃了符号的亏,上了大小写的当

  • 使用前端模板引擎(维护较容易,但缺乏事件支持) - ejs / EasyTemplate

  • 使用Vue特有的模板语法

    • 插值表达式
    • 指令
    • 事件绑定
    • 属性绑定
    • 样式绑定
    • 分支循环结构

3.2 vue devtools工具安装

通过chrome中的谷歌插件商店安装Vue Devtools工具,此工具帮助我们进行vue数据调试所用,一定要安装。

Git仓库地址:https://github.com/vuejs/vue-devtools

  • 安装依赖包 cnpm i

  • 构建 cnpm run build

  • 打开Chrome扩展页面

  • 开启开发者模式

  • 加载已解压扩展,选择shells-chrome目录

  • 将产生的 .crx 文件拖入谷歌浏览器 扩展程序 界面

  • 在Windows策略管理器中添加Google策略模板文件,将插件对应的ID添加到 配置扩展程序白名 单

    • .crx 和 .adm 文件已打包上传至公有云,可以点击访问2url.cc/l3M5x1进行下载
  • 在谷歌浏览器 扩展程序 管理界面中给 Vue.js devtools 插件授权

    • 允许访问文件网址
    • 收集各项错误

可以使用 老师给的已经解压好的 chrome 包安装 vue插件

vue基础_第7张图片

vue基础_第8张图片

3.3 vue数据双向绑定原理 ***

核心:数据劫持 + 发布与订阅

在属性被访问和修改时通知变化。每个组件实例都有相应的 watcher 实例对象,它会在组件渲染的过程中把属性记录为依赖,之后当依赖项的 setter 被调用时,会通知 watcher 重新计算,从而致使它关联的组件得以更新。这些 getter/setter 对用户来说是不可见的,但是在内部它们让 Vue 能够追踪依赖,在 property 被访问和修改时通知变更。这里需要注意的是不同浏览器在控制台打印数据对象时对 getter/setter 的格式化并不同,所以建议安装 vue-devtools 来获取对检查数据更加友好的用户界面。

每个组件实例都对应一个 watcher 实例,它会在组件渲染的过程中把“接触”过的数据 property 记录为依赖。之后当依赖项的 setter 触发时,会通知 watcher,从而使它关联的组件重新渲染。

数据的改变会引起视图的二次渲染

var obj = { a: 1 }
// obj a.  setter getter
console.log(obj.a) // getter
obj.a = 2 // setter

vue基础_第9张图片

Object.defineProperty(obj, prop, descriptor)

obj

要定义属性的对象。

prop

要定义或修改的属性的名称 。

descriptor

要定义选项。

<body>
  
  <div id="app">
    <div id="msg">div>
    <input type="text" id="ipt" oninput="changeVal(this)">
  div>
body>
<script>
  // 参照值 - // 1. 定义对象 
  var userInfo = { username: 'laura' }
  // 需要劫持的对象 - 2. 数据劫持 
  var obj = {}
  // 劫持了 obj对象的 name属性,不管你有没有
  Object.defineProperty(obj, 'name', {
    get () {
      return userInfo.username
    },
    set (val) {
      userInfo.username = val
      document.getElementById('msg').innerHTML = obj.name
    }
  })
  // 3. 实时渲染  只作用了第一次,如果不数据劫持,显示的是 undefined
  document.getElementById('msg').innerHTML = obj.name
  // 4. 发布订阅 
  function changeVal (element) {
    // console.log(element.value)
    console.log(document.getElementById('ipt').value)
    obj.name = element.value
  }
script>

vue数据双向绑定是通过数据劫持结合发布者-订阅者模式的方式来实现的,每个组件实例都有相应的 watcher 实例对象,它会在组件渲染的过程中把属性记录为依赖,之后当依赖项的 setter 被调用时,会通知 watcher 重新计算,从而致使它关联的组件得以更新。

双向数据绑定需要 实现

1.实现一个监听器Observer,用来劫持并监听所有属性,如果有变动的,就通知订阅者。

2.实现一个订阅者Watcher,可以收到属性的变化通知并执行相应的函数,从而更新视图。

3.实现一个解析器Compile,可以扫描和解析每个节点的相关指令,并根据初始化模板数据以及初始化相应的订阅器。

当把一个普通的JavaScript对象传给Vue实例的data选项,Vue将遍历此对象所有的属性,使用Object.defineProperty把这些属性全部转为getter/setter(数据劫持/数据映射)。

3.4 vue模版语法

Vue.js 使用了基于 HTML 的模板语法,允许开发者声明式地将 DOM 绑定至底层 Vue 实例的数据。所有 Vue.js 的模板都是合法的 HTML,所以能被遵循规范的浏览器和 HTML 解析器解析。

在底层的实现上,Vue 将模板编译成虚拟 DOM 渲染函数。结合响应系统,Vue 能够智能地计算出最少需要重新渲染多少组件,并把 DOM 操作次数减到最少。

3.4.1 插值表达式

<body>
    <div id="app">
        1.文本插值--用双大括号显示变量的值<br />
        {{message}}<br />
        2.显示文字<br />
        <div v-text="stu">div>
        3.可以解析原始的HTML v-html<br />
        <div v-html="myhtml">div>
        4.使用v-bind 绑定属性<br />
        <div v-bind:id="myid" v-bind:class="myclass">电影列表div>
        <button v-bind:disabled="myDis">{{myBtnText}}button>
        <img v-bind:src="myImg" />
        
        
    div>
    <script src="../js/vue.js">script>
    <script type="text/javascript">
        var vm = new Vue({
            el: "#app",
            data: {
                message: "hello",
                stu: "熊大",
                myhtml: "

我来测试一下标签是否被解析

"
, myid: 'filmId', myclass: "red", myDis: true, myBtnText: '10', myImg: "../ziliao/meinv.jpg" } })
script> body>

注意:v-html容易引起xss攻击,尽量少用或不用。

html:''

无可避免时使用,需要进行以下配置,了解,面试或以后项目可能用到!

  1. 可以将标签替换成特殊编码:obj[key] = obj[key].replace(/

    2.使用DOMPurify使v-html绕过xss攻击.
    npm install dompurify
      下载完之后在main.js中,将DOMPurify挂在到vue上面,在需要的页面在引入

import VueDOMPurifyHTML from 'vue-dompurify-html'
Vue.use(VueDOMPurifyHTML)

然后在需要使用v-html的页面,将v-html改为 v-dompurify-html即可解决xss攻击问题.

3.最后我在网上找到一个更好的办法通过引入组件xss,在编译前将从vue-loader传入的compilerOptions.directives和baseOptions.directives进行了合并。 这样我们就能覆盖html指令。
npm install xss
同样在main.js页面引入

import xss from 'xss';
Vue.prototype.xss = xss

在vue.config.js中覆写html指令

chainWebpack: config => {
    config.module
        .rule("vue")
        .use("vue-loader")
        .loader("vue-loader")
        .tap(options => {
            options.compilerOptions.directives = {
                html(node, directiveMeta) {
                    (node.props || (node.props = [])).push({
                        name: "innerHTML",
                        value: `xss(_s(${directiveMeta.value}))`
                    });
                }
            };
            return options;
        });
}

这样的话,这个项目不论之后如何迭代都可以从根本上面解决xss攻击的问题

3.4.2 指令

指令 (Directives) 是带有 v- 前缀的特殊属性 attribute。指令 attribute 的值预期是单个 JavaScript 表达式。指令的职责是,当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM。

4.常用指令

4.0 v-text v-bind v-html ***

4.1 v-cloak *

这个指令保持在元素上直到关联实例结束编译。

和 CSS 规则如 [v-cloak] { display: none } 一起用时,这个指令可以隐藏未编译的 Mustache 标签直到实例准备完毕。

如果网络不好的情况下,网页先显示 {{ message }},如果vue加载完毕,显示 hello vue

闪烁

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Documenttitle>
  
  <style>
    [v-cloak] { /* 如果未加载完vue,{{ message }} 不显示 */
      display: none;
    }
  style>
head>
<body>
  
  <div id="app"  v-cloak>
    {{ message }}
  div>
body>
<script src="../js/vue.js">script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      message: 'hello vue'
    }
  })
script>

4.2 双向数据绑定指令 v-model ***

你可以用 v-model 指令在表单