vue.js

Vue.js

一、Vue基础

Vue基础1

1.0 前端开发流程规范
1.1 前端框架发展历史
html

  html [1990]----> html5 [2008.1.12]

css

  css 1.0 1996 
  css 2.0 1998
  css 3.0 2001

EcmaScript 

  1997年诞生
  2015  EcmaScript 2015
  2016  EcmaScript 2016          dart语言  vs  javascript

随着前端项目的逻辑越来越复杂和难以维护,那么前端这边引进了后端的架构思想( MV* )

    M  Model      数据层
    V  View       视图层
    C  Controller 控制器 ( 业务逻辑 )        MVC
 	P  Presenter  提出者( Controller 改名得来的 ) MVP
    VM ViewModel  视图模型( 业务逻辑  VM 是 由  P 改名得来的) MVVM
   
 

    Backbone.js  MVP    2010.10

    Angular.js( 1.0 )   MVC    2010.10

    Angular.ts ( 2.0 )  MVC -> MVVM 2016 目前已经更新到了 Angular9 ( 也属于angular2.0 版本 )

    Vue 1.0   MVVVM  2014/07

    Vue 2.0   MVVM   2016/09

    React 2012 不太认可前端MVC这种架构思想, 你可以将React单纯看做是MVC中V

    github统计量 ( 国际使用量 )不代表大陆地区       单位是: K

    angular.js   angular.ts       vue             React  

      59.6          49.1          146              134	

    学习难度: Vue < React < Angular( 2.0 )

    前端流行

      移动  web    &&  hybird app( 混合app )

      app
        1. native app ( 安卓  ios  java ME)
        2. webapp ( 应用在浏览器中的app )
        3. Hybird app ( 混合app ) 
           1. webapp 嵌入 第三方原生应用库( 可以访问原生设备(手机) 的接口权限,比如:照相机 )



	2016年: 	
		   1. es6
		   2. vue2.0
		   3. angular2.0x
           4. 微信小程序 /  微信小游戏

总结表:

[外链图片转存失败(img-DHkj6OLI-1568092342824)(E:\工作文件\2019-三阶段-授课笔记\2\img\前端框架时间图.png)]

  • 前端js框架到底在干嘛! 为什么要用?

    • js框架帮助开发者写js逻辑代码,在开发应用的时候js的功能划分为如下几点:

      1. 渲染数据

        [外链图片转存失败(img-faTMGwAX-1568092342826)(E:\工作文件\2019-三阶段-授课笔记\2\img\购物车.png)]

      2. 操作DOM

        [外链图片转存失败(img-frnMFlmt-1568092342828)(E:\工作文件\2019-三阶段-授课笔记\2\img\2019-01-11-03.gif)]

      3. 操作cookie等存储机制api

        [外链图片转存失败(img-slQvxbJz-1568092342829)(E:\工作文件\2019-三阶段-授课笔记\2\img\cookie.png)]

    • 在前端开发中

      • 难题: 如何高效的操作dom、渲染数据是一个前端工程师需要考虑的问题,而且当数据量大,流向较乱的时候,如何正确使用数据,操作数据也是一个问题???
        • 解决:
          • 而js框架对上述的几个问题都有自己趋于完美的解决方案,
          • 开发成本降低。高性能高效率。
          • 唯一的缺点就是需要使用一定的成本来学习。
1.2 初始Vue.js
  • 官网地址: 英文官网 中文官网

  • Vue.js框架项目介绍

    • 作者: 尤雨溪

      [外链图片转存失败(img-yGxR6yKH-1568092342830)(E:\工作文件\2019-三阶段-授课笔记\2\img\尤雨溪.jpg)]-

    • Vue.js是尤雨溪的个人项目

    • Vue.js也是一个MVVM框架

    • Vue.js它是一个单项数据流的框架

    • Vue.js是一个Js渐进式框架

    • 学习Vue的必要性

      	Vue近几年来特别的受关注,三年前的时候angularJS霸占前端JS框架市场很长时间,接着react框架横空出世,因为它有一个特性是虚拟DOM,从性能上碾轧angularJS,这个时候,vue1.0悄悄的问世了,它的优雅,轻便也吸引了一部分用户,开始收到关注,16年中旬,VUE2.0问世,这个时候vue不管从性能上,还是从成本上都隐隐超过了react,火的一塌糊涂
      
      	学习vue是现在前端开发者必须的一个技能
      
1.3 MV*模式介绍

MV*模式图示

1.4 Vue实现数据绑定的原理
  1. 书写第一个Vue案例

  2. Vue深入响应式原理图

    [外链图片转存失败(img-v7bcVJYh-1568092342831)(E:\工作文件\2019-三阶段-授课笔记\2\img\data.png)]

     // Vue 底层原理 
    
      // 目的: 使用原生js来实现Vue深入响应式 
    
      var box = document.querySelector('.box')
    
      var button = document.querySelector('button')
    
      var data = {
        name: 'Jick'
      }
    
      // 观察者对象
    
      var observer = {...data} 
    
      // es5提供的api方法,这个方法不兼容ie8以及以下
      // Object.defineProperty(对象,对象的属性,对象属性的修饰符 )
    
    
    
      Object.defineProperty(  data,'name',{
        // get/set  统称为: '存储器'
        get () {
          return  observer.name // 初始化赋值一个值给name属性
        },
        set ( val ) {
          console.log( val )
          box.innerHTML = val
        }
      })
    
      button.onclick = function () {
        data.name = "Rose"
      }
    
      box.innerHTML = data.name 
    
    • 面试题/理解: 如何理解深入响应式原理?
      • Vue是通过数据劫持和事件的订阅发布来实现的,数据劫持指的是Vue通过observer观察者对象对data选项中的数据进行getter和setter设置【 Object.defineProperty 】,事件的订阅发布指的是Vue通过事件来监听,通知Vue进行视图更新
        • 监听: 选项/watch

Vue基础2

2.1 模板语法

mustache 语法中是支持写js的

  1. 用法:

    • 内容: 必须加 {{ js语法 }}

    • 属性: 属性中属性值可以直接写js语法,并且属性值中的数据相当于全局变量

      • 给一个标签加一个自定义属性/已有属性

        img中的src就是已有属性
        <img src = "" /> 
        
        //data-index就是自定义属性 , web网页中建议我们使用data-形式来定义自定义属性
        <img data-index = "0" />
        
        
      • 思考: Vue现在想要在html中使用自己的属性,并且要和他的语法和数据结合?

        • 咋整?

        • 分析: 如何我能够标识出哪一个属性是具有vue标志的那就好了,也就是属性前加 v

          • Vue给这种带v标识的属性,起了一个名字: 指令【 借鉴angular 】
          <div v-html = "msg">
              
          </div>
          
  2. 研究它js的支持性

    • 数据类型
      • 市场上js的数据类型分类有两种?
        • 第一种
          • 初始数据类型: number string null undefine boolean
          • 引用数据类型: Object [ function array … ]
        • 第二种
          • 基础数据类型: number string boolean
          • 特殊数据类型: null undefine
          • 复杂数据类型; Object [ function array …]
    • 输出语法
      • console
      • alert
    • 表达式 / 运算符
      • 三元表达式
  3. 总结;

    • null 和 undefined 是不会显示的,其他数据类型都是支持的,可以显示的
    • 挂载在window身上的全局属性,我们都不能用的: 比如; console alert
    • {{ }} 不写流程控制
      • for
      • if
      • while
      • do…while
    • {{}} 支持三元表达式,同样也支持运算符
      • 短路原则也是支持的
2.2 指令

指令的目的是做什么: 操作DOM

​ 解释 : MVVM vm -> v 数据驱动

​ 所以: 今天开始,我们不想二阶段一样操作dom,改成操作数据,数据要想操控DOM,那么我们需要依赖指令,因为指令是直接绑定在dom身上的

  1. v-html 转义输出,也就是可以解析 xml 数据

  2. v-text: 非转义输出,也就是无法解析 xml 类型数据

  3. v-bind

    • 将数据和属性进行单向数据绑定: 将vue中数据赋值给属性值

      <img v-bind:src = "src" />
      <div v-bind:class = "">
          
      </div>
      <div v-bind:style = "">
          
      </div>
      
    • 简写形式

      <img v-bind:src="src" alt="">
      <img :src="src" alt="">
      
    • 类名绑定

      • 用法

        • 对象形式用法

              <p :class = "{ bg: true,size: true }"></p>
              <p :class = "{ bg: true,size: false }"></p>
              <p :class = "{ [classA]: true,[classB]: true }"></p>
          
        • 数组形式用法

              <p :class = "[ 'size','bg' ]"></p>
              <p :class = "[ classA,classB ]"></p>
              <p :class = "[ classA,classB,5>3?'a':'b']">  </p>
          
    • 样式绑定

      • 用法

        • 对象形式用法

          <p :style = "{width: '100px',height: '100px',background: 'yellow'}"></p>
          <p :style = "styleObj"></p>
          
        • 数组形式用法

          <p :style = "[{width:'100px',height: '100px'},{ background: 'green'}]"></p>
          <p :style = "[size,bg]"></p>
          
2.3 条件渲染
  1. v-if

  2. v-else-if

  3. v-else

  4. v-show 条件展示

     <h3> 条件渲染 - 单路分支 </h3>
    <p v-if = "flag"> A </p>
    
    
    <h3> 条件渲染 - 双路分支 </h3>
    <p v-if = "flag"> A </p>
    <p v-else > B </p>
    
    
    <h3> 条件渲染 - 多路分支 </h3>
    <p v-if = "type === '美食'"> 美食 </p>
    <p v-else-if = " type === '游戏' "> 游戏 </p>
    <p v-else> 睡觉 </p>
    
    <h3> 条件展示 </h3>
    
    <p v-show = " showFlag "> 条件展示 </p>
    
  5. 思考总结

    思考: v-if  vs  v-show  
          1. 效果看起来一样
          2. why Vue要出两个相似的指令?
            v-if控制的是元素的存在与否
            v-show控制的是元素的display:none属性
    
    思考? 如果出事条件为假时? v-if   v-show 谁的性能损耗较高?
    v-show
    
    总结: 项目中如何选择哪一个?
    频繁切换用  v-show
    如果不是很频繁的切换,那我们用 v-if   
    
    
2.4 列表渲染
  • v-for 指令

    <h3> 数组 </h3>
    <ul>
        <li v-for = "(item,index) in arr" :key = " index ">
            {{ item }} -- index{{ index }}
        </li>
    </ul>
    <h3> 对象 </h3>
    <ul>
        <li v-for = "(item,key,index) of obj" :key = "index">
            {{ item }} -- {{ key }} -- {{ index }}
        </li>
    </ul>
    <h3> json </h3>
    <ul>
        <li v-for = "item in json" :key = "item.id">
            <span> 商品名称: {{ item.shop_name }} </span>
            <span> 商品价格: {{ item.price }} </span>
        </li>
    </ul>
    
    <h3> 循环嵌套 </h3>
    
    <ul>
        <li v-for = "item in lists" :key = "item.id">
            <h3>  商品类型: {{ item.shop_name }} </h3>
            <ul>
                <li v-for = "item in item.type" :key = "item.id">
                    <p> 制造商: {{ item.maker }} </p>
                </li>
                <!-- <li v-for = "ele in item.type" :key = "ele.id">
    <p> 制造商: {{ ele.maker }} </p>
    </li> -->
            </ul>
        </li>
    </ul>
    
    <h3> 循环number / string  </h3>
    
    <p v-for = "item in 10"> {{ item }} </p>
    <p v-for = "item in 'abc'"> {{ item }} </p>
    
    
  • 总结:

      1. 列表渲染参数可以写三个,分别为 item key index
      1. 列表渲染,要在渲染的元素身上加一个key,作为这个元素唯一的标识 ,
        1. 思考: 这是为什么?
        2. 这个key最好是id,因为id唯一?思考: 为什么不能是index
      1. 循环嵌套式,参数名称是可以一致的
      1. in / of 都可以使用
2.5 事件处理器
  • v-on

  • key的重要性

    给列表渲染的每一层Vdom添加一个唯一标识,以便diff算法进行同层级比较

    扩展: 理解key

2.6 表单控件绑定
  • v-model
    • 双向数据绑定
      • VM 改变 V随之改变
      • V改变, VM也随之改变
    • v-model只用于表单
      • 理由: v-model默认绑定value属性
    • 技巧: 看到表单直接 v-model
2.7 作业
  1. 整理好笔记,发送博客
  2. 用深入响应式原理来解释 双向数据绑定原理 【 思考 】
  3. 使用单向数据绑定来实现 v-model 效果
  4. 今天讲的知识点在官网上对一对,看一看,

Vue基础3

3.1 axios && fetch

目的: 是在框架中使用数据请求

回顾:

  1. 封装ajax
    2. jquery 【 . g e t .get .get .post . a j a x .ajax .ajax .load 】

框架:

数据请求

  1. 使用原生js提供的fetch
  2. 使用第三方封装库: axios
    • Vue中可以统一对axios进行挂载
     Vue.prototype.$http = axios

  1. fetch vs axios
    • axios 对已获得的数据进行了一层封装 XSRF
      • axios底层自动对数据进行了格式化
    • fetch并没有进行封装,拿到就是格式化后的数据
      • fetch进行了多一层的格式化
        • res.json()
        • res.blob() 格式化二进制
        • res.text()
Axios总结
    1.get方法


    A: 无参数
        axios.get(url).then(res=>console.log(res).catch(error=>conosle.log(error))
    B: 有参数
        axios({
            url: 'http://xxx',
            method: 'get' //默认就是get,这个可以省略,
            params: {
                key: value
            }
        })

    2.post
        注意: axios中post请求如果你直接使用npmjs.com官网文档, 会有坑
        解决步骤: 
                1. 先设置请求头 
                2. 实例化 URLSearchParams的构造器函数得到params对象
                3. 使用params对象身上的append方法进行数据的传参


// 统一设置请求头
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'; 
let params = new URLSearchParams()

// params.append(key,value)

params.append('a',1)
params.append('b',2)

axios({
    url: 'http://localhost/post.php',
    method: 'post',
    data: params,
      headers: {  //单个请求设置请求头
       'Content-Type': "application/x-www-form-urlencoded"
    }
})
.then(res => {
    console.log( res )
})
.catch( error => {
    if( error ){
    throw error
}
})


Fetch
1.get

fetch('http://localhost/get.php?a=1&b=2')
    .then(res=> res.text()) // 数据格式化 res.json() res.blob()
    .then(data => {
        console.log( data )
    })
    .catch(error => {
        if( error ){
        throw error
    }
})

注意事项:
    A: fetch 的 get 请求的参数是直接连接在url上的, 我们可以使用Node.js提供的url或是qureystring模块来将
        Object --> String
    B: fetch 的请求返回的是Promise对象,所以我们可以使用.then().catch(),但是要记住.then()至少要写两个, 第一个then是用来格式化数据的,第二个then是可以拿到格式化后的数据
        格式化处理方式有
fetch('./data.json')
.then(res=>{
    res.json() //res.text() res.blob()
})
.then( data => console.log(data))
.catch( error => console.log( error ))


2.post
fetch 文档
https://developer.mozilla.org/zh-CN/docs/Web/API/Fetch_API/Using_Fetch#%E8%BF%9B%E8%A1%8C_fetch_%E8%AF%B7%E6%B1%82

fetch项目使用的博客
https://blog.csdn.net/hefeng6500/article/details/81456975

  • 历史
    • Vue1.0
      • Vue1.0数据请求我们使用的是一个第三方的封装库,这个封装库叫做 vue-resource
      • vue-resource现在已经淘汰了,它的作者也推荐我们使用axios
        • vue-resource使用形式和axios一样的
          • this.$http.get
          • this.$http.post
          • this.$http({})
          • vue-resource有jsonp方法,而axios是没有的
    • Vue2.0
      • axios [ 可以说是目前最好的数据请求的封装库 ]
      • fetch
3.2 计算属性

computed 是Vue中的一个选项

作用: ?

​ 业务: 如果我想让一个字符串反向,如何实现?

​ 分析: 反向 -> 数组【 reverse 】

3.2.1 侦听属性

watch 是Vue中一个选项

作用: ?

​ 监听数据的变化,当数据发生改变时,我们完成一些操作

业务:

watch: {
      firstName ( val ) {
        this.fullName = val + this.lastName
      },
      lastName ( val ) {
        this.fullName = this.firstName + val 
      },
      num: {
        deep: true, // 深度监听      
        handler ( val ) {
          //  当num发生改变时,触发的方法
          console.log( val )
        }
      }
    }

  • 总结: methods vs computed vs watch

    • 项目中如何使用

        1. 事件处理程序: methods
        1. watch

          有大量数据交互和异步处理时进行

        1. computed
          • 有逻辑处理
          • V中像全局变量一样使用
3.3 混入 【 青铜 】

minxin

  1. 混入的形式

    • 全局混入 【 不推荐 】
    • 局部混入
  2. 混入的作用:

      1. 将选项中某一个或是多个单独分离出去管理,让职能更加单一高效,符合模块化思想
  3. 局部混入的使用

    选项  minxins
    
    
  4. 全局混入

    Vue.mixin({})
    
    
3.4 组件 【 王者 】
  1. 了解前端组件化发展历史

    • 前后端耦合
      • 前后端不分离项目
          1. 找后台搭建项目开发环境
          1. 寻找项目目录中的静态资源目录
            • js
            • img
            • css
          1. 同步修改css
    • 前后端分离
    • 前端团队合作项目的出现
      • 组件化为了解决多人协作冲突问题
      • 复用
  2. 组件的概念

    • 组件是一个html 、 css 、js 、img 等的一个聚合体
  3. Vue中的组件属于扩展性功能

    • 通过 Vue.extend() 来扩展的

      ƒ Vue (options) {
          if (!(this instanceof Vue)
             ) {
              warn('Vue is a constructor and should be called with the `new` keyword');
          }
          this._init(options);
      }
      ƒ VueComponent (options) {
          this._init(options);
      }
      
      
    • VueComponet这个构造函数我们不进行new实例化,我们希望组件是以标签化的形式展示

      <Hello/> -->  <div></div>
      <Banner></Banner>
      
      
    • 组件要想合法化,必须注册解析

    • 组件的注册 【 创建 】

      • 全局注册
      • 局部注册
    • 组件的规则

    • is属性 - 动态组件 - 动态缓存组件

    • template模板标签

      • 直接子元素有且仅有一个
    • 组件的嵌套

3.5 作业
  1. 面试题: ajax 和 fetch 有什么区别? 【 提问率: 60% 】
  2. 进行数据请求,然后布局一个移动端列表 【 亲亲网 】
    • 弹性盒
    • rem
  3. 了解前后端耦合,前后端分离
  4. 进行页面布局
    • 寺库登录页面布局
    • 卖座首页布局

Vue基础4

4.0 组件的通信 【 王者 】

为什么要进行组件通信?

​ 组件是一个聚合体,将来项目要合并,那么必然各个组件之间需要建立联系,这个联系就是数据通信

  1. 分类

    • 父子组件通信

      • 理解: data选项为什么是一个函数?

        • 组件是一个聚合体,也是一个整体,它需要一个独立的作用空间,也就是它的数据需要是独立的,目前js的最大特点是函数式编程,而函数恰好提供了一个独立作用域,所以我们data在出根组件外都是函数
      • 理解: 为什么data函数需要返回一个返回值,返回值还是对象,不能是数组吗?

        • Vue通过es5的Object.definePerproty属性对一个对象进行getter和setter设置,而data选项是作为Vue深入响应式核心的选项
      • 过程

        • 父组件将自己的数据同 v-bind 绑定在 子组件身上

        • 子组件通过 props属性接收

          <template id="father">
              <div>
                  <h3> 这里是father </h3>
                  <Son :money = "money"></Son>
              </div>
          </template>
          
          <template id="son">
              <div>
                  <h3> 这里是son </h3>
                  <p> 我收到了父亲给的 {{ money }} </p>
              </div>
          </template>
          
          <script>
            Vue.component('Father',{
              template: '#father',
              data () {
                return {
                  money: 10000
                }
              }
            })
          
            Vue.component('Son',{
              template: '#son',
              props: ['money']
            })
          
            new Vue({
              el: '#app'
            })
          </script>
          
          
      • props属性数据验证

        • 验证数据类型

        • 验证数据大小【 判断条件 】

          // props: ['money']
          // 数据验证
          // props: {
          //   'money': Number 
          // }
          props: {
              'money': {
                  validator ( val ) { // 验证函数
                      return val > 2000
                  }
              }
          }
          
          
        • 工作中: 第三方验证

          • TypeScript [ TS ]
          • 插件 vue-validator 等
    • 子父组件通信

      • 是通过自定义事件

        • 事件的发布
          • 通过绑定元素身上实现
        • 事件的订阅
          • 通过this.$emit触发
        // html
        <div id="app">
            <Father></Father>
          </div>
          <template id="father">
            <div>
              <h3> 这里是father </h3>
              <p> 我现在有 {{ gk }} </p>
              <Son @give = "fn"></Son>
            </div>
          </template>
        
          <template id="son">
            <div>
              <h3> 这里是son </h3>
              <button @click = "giveHongbao"> 给父亲红包 </button>
            </div>
          </template>
        
        
        //js
        Vue.component('Father',{
            template: '#father',
            data ( ) {
              return {
                gk: 0
              }
            },
            methods: {
              fn ( val ) {
                this.gk = val 
              }
            }
          })
        
          Vue.component('Son',{
            template: '#son',
            data () {
              return {
                money: 5000
              }
            },
            methods: {
              giveHongbao () {
                this.$emit('give',this.money)
              }
            }
          })
          new Vue({
            el: '#app'
          })
        
        
    • 非父子组件通信

      • ref链

      [外链图片转存失败(img-fVVjMwc7-1568092342832)(E:\1906\2-Vue.js\note\vue笔记\img\非父子组件通信-ref(1)].png)

      • bus事件总线

        var bus = new Vue()
        
          Vue.component('Father',{
            template: '#father'
          })
          Vue.component('Son',{
            template: '#son',
            data () {
              return {
                flag: false
              }
            },
            mounted () { // 也是一个选项,表示组件挂载结束 , 也就是说我们可以在View视图中看到这个组件了
              // console.log( 'mounted ')
              // bus.$on(自定义事件名称,执行的事件处理程序)
              var _this = this
              bus.$on('cry',function () {
                _this.flag = true
              })
        
            }
          })
          Vue.component('Girl',{
            template: '#girl',
            methods: {
              kick () {
                bus.$emit('cry')
              }
            }
          })
          new Vue({
            el: '#app'
          })
        
        
    • 非常规手段进行组件通信 【 不推荐 】

      • 兵哥建议: 如果标准方案可以实现,就不要用非常规手段

        1. 可以实现子父通信
        • 父组件通过 v-bind 绑定一个方法给子组件
        • 子组件通过 props选项接收这个方法,然后直接调用
        1. 父组件 通过 v-bind 绑定 一个对象类型数据 给子组件
        2. 子组件直接使用,如果更改这个数据,那么父组件数据也更改了
          • 原因: 同一个地址
          • 非常规在哪里?
            • 违背了单向数据流
    • 多组件状态共享 【 vuex 】

4.1 slot

slot 插槽

​ 比如: 插卡游戏机

  1. 分类

    • 普通插槽

    • 具名插槽

      • 给slot加一个name属性

        <slot name = "header"></slot>
        
        
    • 注意: 以上内容是 Vue 2.5.x的版本

    • Vue 2.6.x以上的版本将使用 v-slot指令来代替 2.5.x使用方式

  2. v-slot指令

    • 作用:
      • 可以将组件的数据在组件的内容中使用
4.2 过渡效果

Vue框架使用css3过渡效果或是js动画

Vue内部提供了一个叫做transition的过渡组件

使用transition包裹过渡元素,那么会自动添加 6 个类名 8个钩子函数

  • 默认 类名 开头 v
  • 如果有name属性,那么使用 这个name属性值作为类名开头
  1. 实现方式
    • 在 CSS 过渡和动画中自动应用 class 【 自己写 】
    • 可以配合使用第三方 CSS 动画库,如 Animate.css
    • 在过渡钩子函数中使用 JavaScript 直接操作 DOM
    • 可以配合使用第三方 JavaScript 动画库,如 Velocity.js
  2. 第一种 [ 在 CSS 过渡和动画中自动应用 class 【 自己写 】 ]
  3. 第二种: animate.css 【 推荐 】
  4. 第三种: Vue提供了8个javascript钩子,我们需要自定义js动画
  5. 第四种: 使用第三方插件: Velocity.js
4.3 生命周期
4.4 swiper

swiper是一个实现滑动操作的一个第三方库,目前最好的滑动操作库

4.5 自定义指令

业务: 页面开启时自动获得 search 按钮焦点

  • 定义形式

    • 全局定义

      // Vue.directive('focus',{
        //   // 5个javascript钩子     5个中掌握2个
        //   bind (el,binding,vnode,oldVnode) { // 当自定义指令和元素绑定时触发
        //     console.log( 'bind', )
        //   },
        //   inserted ( el,binding,vnode,oldVnode ) { // 当自定义指令绑定的元素插入到页面时触发
        //     console.log( 'el',el) 
        //     console.log( 'binding',binding)
        //     console.log( 'vnode',vnode)
        //     console.log( 'oldVnode',oldVnode)
        //     console.log('inserted')
      
        //     if ( binding.modifiers.a ) {
        //       el.style.background = 'red'
        //     } else {
        //       el.style.background = 'blue'
        //     }
      
        //     el.value = binding.expression
      
        //     el.focus()
      
        //   },
        //   updated () { // 当自定义指令的元素或是他的子元素发生变化式触发
      
        //   },
        //   componentUpdate () { //当自定义指令的元素或是他的虚拟子节点 发生变化式触发
      
        //   },
        //   unbind () { // 当自定义指令绑定的元素解绑时触发
      
        //   }
        // })
      
      
    • 局部定义

       new Vue({
          el: '#app',
          directives: {
            'focus': {
              bind () {
      
              },
              inserted ( el ) {
                el.focus()
              }
            }
          }
        })
      
      
4.6 过滤器
    1. 作用
      • 是对已经有的数据做数据格式化
    1. 使用格式

      • 已有数据 | 过滤器名称(arg1,arg2)
        <img 
             :src = "item.img | imgFilter "
             οnerrοr="this.style.visibility='hidden'"
             >
      
      
      • | 我们称之为 管道符
  • 定义

    • 全局定义
      • Vue.filter
    • 局部定义
      • filters选项
    全局定义
    // Vue.filter('imgFilter',function ( val ) {
      //   //val就是需要格式化的数据
      //   // console.log('val',val)
      //   return val.replace( 'w.h', '128.180')
      // })
    
      new Vue({
        el: '#app',
        data: {
          lists: []
        },
        filters: { // 局部定义
          // 过滤器名称:function () {}
          'imgFilter': function ( val ) {
            return val.replace( 'w.h', '128.180')
          }
        },
        methods: {
          getList () {
            fetch('./data/list.json')
              .then( res => res.json())
              .then( data => {
                this.lists = data.movieList
              })
              .catch( error => console.log( error ))
          }
        }
      })
    
    
4.7 作业
  • 自定义指令实现选项卡
  • 预习Vue生命周期 并 试着 实现 将 swiper 应用在 Vue中
  • 复习着一周内容
  • todolist尝试实现

Vue基础5

5.1 todolist案例
  • sui - ui库 + Vue + OOCSS
5.2 虚拟DOM & DIff算法
  • 掌握程度: 了解

  • 案例

    • 操作真实DOM越少越好,尽量的去操作数据
    • 所以总结出来虚拟dom,
    • 所以Vue利用VDOM的对象模型来模拟DOM结构
    • 但是当一个页面很复杂式,DOM结构的模拟就变的很复杂了,所以Vue使用了一个新的语法糖,叫做JSX
  • jsx

    • javascript + xml 让我们可以在js中书写dom结构

        <template id="mask">
          <div class="mask-box">
            <div class="mask-bg"></div>
            <div class="mask-content">
              <p> 您确定要离开吗? </p>
              <button 
                class="button button-warning button-fill pull-right"
                @click = "removeItem( activeIndex )"
              > 确定 </button>
            </div>
          </div>
        </template>
      
  • render

    • ( createElement => VNode )
    • 将 jsx 通过 render 方法解析为对象模型
  • 流程

    • 第一次时

    • template模板使用jsx语法进行编辑

    • 通过render函数将jsx解析为 vdom 对象模型

    • 将VDOM对象模型渲染为真实DOM,然后挂载到页面中

    • 当我们的数据发生改变时

    • 重新生成VDOM

      [外链图片转存失败(img-kSM48PWK-1568092342833)(E:\1906\2-Vue.js\note\vue笔记\img\VDOM.png)]

    • 总结:

        1. 为什么Vue中要使用VDOM?
        1. VDOM为什么可以优化Vue ?
        1. VDOM渲染流程
        1. JSX语法
        1. render函数
5.3 生命周期 [ 王者 ]

掌握程度

  1. 会写
  2. 会念
  3. 明白和了解每一个钩子函数的作用和意义

特别注意:

​ 钩子函数不要写成箭头函数,箭头函数可能会改变this指向

  • 理解: 为什么要有生命周期 ?

  • Vue为了在一个组件的从创建到销毁的一系列过程中添加一些功能,方便我们更好的去控制组件

  • 类比: 人

    • 出生 - 哭
    • 小学 - 小学
    • 中学
    • 高中
    • 大学 / 专科
    • 工作
    • 。。。
  • Vue的生命周期分为三个阶段,8个钩子函数

    • 初始化

      自动执行

      研究方向

      ​ 数据

      ​ 真实DOM

      • beforeCreate

        组件创建前

        • 作用: 为整个生命周期做准备工作,初始化事件和自身或是子组件的生命周期做准备
        • 类比: 父母为子女的相亲做准备
        • 意义:
          • 数据拿不到
          • 真实dom拿不到
        • 项目中
          • 不常用
      • created

        组件创建结束

        • 作用: 初始化注入其他选项 和 激活 选项
        • 类比: 我们本人知道了父母准备给我们相亲这件事,父母通知你了
        • 意义:
          • 数据可以拿到
          • 真实dom拿不到
        • 项目中:
          • 数据请求,也可以修改一次数据
      • beforeMount

        组件挂载前

        ​ 挂载: 组件插入到页面

        • 类比:两人初步联系
        • 意义:
          • 数据可以拿到
          • 真实dom没有拿到
        • 在项目中
          • 数据请求,数据修改
          • 建议不要去使用它了,让它完成内部事务,不给加负担
        • 内部完成事务
          • 判断el选项 - new Vue 是否有 el
            • 有,继而判断是否有template选项,证明有子组件
              • 有template,那么我们通过render函数将jsx解析为VDOM对象模型
              • 无template,那么我们需要通过outerHTML手动渲染
                • outerHTML,元素外进行渲染,并且会代替原来的容器盒子,并且template在实例内会被解析,将来不会渲染到页面
            • 无: 那么我们需要手动挂载: new Vue().$mount(’#app’)
      • mounted

        组件挂载结束,也就是已经插入到页面中了

        • 类比: 两人约见面 【 奔现 】
        • 意义:
          • 数据可以拿到
          • 真实DOM也可以拿到
        • 项目中
          • 数据修改,数据请求
          • 真实DOM操作 【 不推荐 】
            • 理由: 我们要用数据驱动视图
            • 应该做的: 第三方实例化 【 静态数据 】
    • 运行中

      运行中触发条件是: 数据改变

      ​ 只要数据改变,就会触发这两个钩子函数

      • beforeUpdate

        组件更新前

        • 类比: 奔现失败后,再一次在一次进行
        • 意义:
          • 数据是可以拿到更新后的数据
          • 也可以拿到更新后的真实DOM
          • 兵哥解析:
            • 为在一次的更新准准备工作
            • 生成Virtual DOM
        • 项目中
          • 不常用
      • updated

        组件更新结束

        • 类比: 两人看对眼了 / 两人看不对眼
          • 看对眼: 相亲这件事就有一个结果
          • 看不对眼: 相亲这件事继续
        • 意义:
          • 可以拿到修改后的数据
          • 也可以拿到真实DOM
        • 在项目中:
          • 真实DOM操作 【 不推荐 】
          • 第三方库动态实例化 【 动态数据 】
        • 内部
          • VDOM重新渲染,然后通过render函数解析为VDOM对象模型,在通过Diff进行比对生成patch补丁对象,然后重新渲染为真实DOM
            • 只改变变化的部分,其他部分不改变
    • 销毁

      触发条件:组件被删除

      • 外部开关销毁
      • 内部调用$destroy()

      这两个钩子函数没有太大区别,所以我们统一说

      • beforeDestroy
      • destroyed
      • 外部销毁
        • 通过开关完成
          • DOM被删除了,组件也被删除了
      • 内部销毁
        • 通过调用$destroy()来完成
          • DOM没有被删除,但是组件被删除了
          • Dom需要手动删除
      • 项目中如何使用:
        • 善后
          • 比如: 计时器,比如滚动事件等
    5.4 生命周期案例
    • Swiper
      • 静态数据
      • 动态数据
        • updated中写式,会有重复实例化问题
          • 第一个解决方案: 加判断条件
          • 第二个解决方案: setTimout
            • 放在主线程后执行,异步队列中,保证真实DOM渲染完成
          • 第三种解决方案: 推荐 Vue内部提供的 nextTick
            • nextTick表示真实DOM渲染完成之后才执行
              • Vue.nextTick( callback )
              • this.$nextTick( callback )

    [外链图片转存失败(img-TquwQTHV-1568092342834)(E:\1906\2-Vue.js\note\vue笔记\img\lifecycle.png)]

作业:
  1. todolist
    2. VDOM & Diff

二、Vue高级

Vue高级 - cli

vue项目的快速构建工具 cli 【 脚手架 】

​ 底层 webpack

​ React 第一天

​ Vue中我们注重应用

在市场上
cli2 【 扩展 】
cli3 【 大纲 】

  1. 什么是cli?

    cli是vue提供的一个用来快速构建项目环境的一个工具,底层使用的是webpack

  2. cli目前有哪些版本?

    cli2 cli3

    cli3对电脑的配置有一定要求

  3. cli如何使用?

    1. cli的安装 【 推荐使用yarn 】
      npm/cnpm/yarn 都可以使用 【 yarn 配置国内镜像 】

      $ cnpm i yarn -g

      使用国内镜像加速npm和yarn
      npm config set registry=https://registry.npm.taobao.org
      yarn config set registry https://registry.npm.taobao.org
      下载cnpm:npm install -g cnpm –registry=https://registry.npm.taobao.org
      
      
      1. $ yarn add @vue/cli global 这个是cli3的版本
        如果我们还想使用cli2的脚手架,那么我们可以在安装一个包

        cli3 @vue/cli

        cli2 vue-cli 【 不要安装 】

        所以一个电脑只能装一个

        问题: 如果我们同时想使用 cli2 和 cli3 怎么办呢?

      2. $ yarn add @vue/cli-init global

      如果有的同学安装3失败了,
      那么你可以使用cnpm继续安装 @vue/cli @vue/cli-init

       1. `$ cnpm i  @vue/cli -g`    这个是cli3的版本
            如果我们还想使用cli2的脚手架,那么我们可以在安装一个包
       1. `$ cnpm i  @vue/cli-init -g`
      
      

      如果还有问题:
      那么你就不要使用cli3了,你可以单独安装cli2 【 先卸载cli3,重启电脑 】

       `$ cnpm i vue-cli -g`
      
      
    2. 验证是否安装成功
      命令行输入: $ vue 看是否有东西输出,如果输出命令提示,证明安装成功

    3. 创建项目

      cli3版本创建

      1. 命令创建 【 推荐 】
        $ vue create project

        • 手动选择配置
        • 如果安装node-sass出问题,如何解决:
          • 先切换成npm源 nrm use npm
          • 使用cnpm 安装 cnpm i node-sass sass-loader -D
      2. 图形界面创建
        $ vue ui

        cli3两种形式创建的结果是一样的

      cli2版本创建

      1. 标准版
        $ vue init webpack project
      2. 简易版
        $ vue init webpack-simple project
    4. please pick a preset( user arrow keys ) 使用键盘上下键来选择一个配置

      1. default 默认配置

      2. Manually select features 手动选择配置

        配置指的是配置webpack

        babel 优雅降级 es6 —> es5

        eslint js语法检测

        CSS Pre-processors css 预处理语言 less sass/scss stylus

        Linter / Formatter eslint / jslint

        Unit Testing 单元测试

        E2E Testing 端到端的测试

        In dedicated config files 将所选的每一个选项用一个文件来保存( 配置 )

      PWA (web app ) 在浏览器中使用的app

    Save this as a preset for future projects? 将上面所选的配置保存下来,以备将来的项目使用

    我们cli3 使用的包管理器器建议 是 yarn 大家一定要记得配置国内镜像源

4.分析几个版本的目录

cli3

目录

  • node_modules 项目的依赖包
    • cli3 webpack配置放在node_modules中
  • public 静态资源目录( 生产环境 )【 这个目录下的静态资源不会被webpack 编译 】
    • img
    • js
    • css
    • favicon.ico 项目标题的logo
    • index.html 根实例组件的模板,也是整个项目的容器
  • src 源代码开发目录( 也是开发者主要开发的目录文件夹 )
    • assets 开发环境的静态资源目录 ( 这个目录中的资源会被webpack编译)
      • assets中如果图片的大小 > 4k 我们就原样拷贝到dist目录
      • assets中如果图片的小小 < 4K 我们就将这个图片转化成 base64
      • base64它是我们前端处理图片的一种形式,将图片路径进行编码,它可以减少一次ajax请求,达到前端性能优化的一个方案,但是base64有一个弊端,这个弊端就是会污染html结构
    • components 组件存储目录
      • xxx.vue文件 单文件组件 一个vue文件就是一个组件
        • 组成部分
          • template模板( 必须写的 )
          • script脚本 ( 可写可不写)
          • style样式 ( 可写可不写 )
            • scoped 作用是可以减少命名冲突,规定一个样式的作用域
  • .gitignore git上传忽略文件配置
  • babel.config.js 优雅降级配置文件 用来将es6 --> es5
  • package.json 整个项目的依赖配置文件
  • README.md 整个项目启动的说明性文件
  • yarn.lock 整个项目的依赖性文件的信息
  • postcss.config.js 项目css预处理的配置
  • .browserslistrc 浏览器版本的支持

cli2 标准版

​ build webpack配置

​ config webpack配置

​ node_modules

​ src

​ static 静态资源配置

​ js

​ css

​ img

​ .babelrc 优雅降级配置文件

​ .postcssrc css预处理配置文件

​ .editorconfig 编辑器配置文件

cli2 简易版

​ src 源代码开发目录

​ webpack.config.js webpack配置文件

5.学习cli使用

6.cli 它是 webpack + es6模块化来集中实现的

es6模块化

  1. 模块的定义

    const obj = {}
    const fn = function(){}
    
    
  2. 模块的导出

    // 模块的导出有两种形式
    export default //默认导出一个
    
    //export // 批量导出,导出多个
    
    
  3. 模块的引入

    // 如果是export  default 导出
    import xxx from '../xxx.xx'
    
    // 如果是export 导出
    
    improt  { xx } from '../xx.xx'  || import * as xx from '../xx.xx'
    
    

base64找一个博客了解一下

在cli3中创建组件,然后导出组件,然后使用组件

在 vs code编辑器中安装一个插件( Vetur ),可以使用vue文件代码高亮还可以有代码提示

【HMR】 热重载 自动刷新 webpack配置

cli3 将webpack配置放在 node_modules,所以Vue并不希望大家去修改这部分webpack配置

如果我们将来需要更改webpack配置,那么我们需要在 项目 根目录 下创建一个 vue.config.js文件

作业:

  1. 在cli3/cli2项目中完成todolist
    2. cli3

Vue高级 - vue-router

SPA ( single page App ) 单页面应用
  1. 多页面应用
    有多个html文件,通过a标签的连接联通各个页面
  • 缺点
    • 开发起来太冗余,编译、压缩很耗时间
    • 页面之间的跳转速度太慢,这个时候就会出现一个严重的问题,白屏
  1. 单页面应用
    • 不需要刷新页面,因为它就是一个页面
    • 这个页面内容在切换
    • 单页面内容之间的切换要想实现我们就是用路由了
    • 如今我们的app、后台管理系统 主要的开发形式就是spa
vue路由功能
  1. 实现单页面的切换
  2. 路由携带参数
  3. 路由的导航守卫
  4. 路由进行数据预载(进入组件前就请求获得数据)
vue-router 基础
  1. vue 路由的mode(模式)有几种, 分别是什么?在那些环境下运行? 【 黄金 】

    • hash: 使用 URL hash 值来作路由。支持所有浏览器,包括不支持 HTML5 History Api 的浏览器。 #/home
    • history: 依赖 HTML5 History API 和服务器配置。【需要后端支持】 /home
    • abstract: 支持所有 JavaScript 运行环境,如 Node.js 服务器端。如果发现没有浏览器的 API,路由会自动强制进入这个模式。【 这个模式不常用 】
    • hash/history 常用于浏览器端,abstract用于服务端
  2. 路由的使用步骤

    1. 安装 vue-router yarn add vue-router

    2. 在src目录下创建一个router目录, 里面创建一个index.js文件 , 这个目录就是router的模块

    3. 引入第三方的依赖包, 并注册路由

        import Vue from 'vue'
        import VueRouter from 'vue-router'
      
        Vue.use( VueRouter ) //使用vue-router这个第三方插件
      
      

      注意: import这个关键字要放在整个文件的上层

    4. 创建了一个router对象实例,并且创建路由表

        const routes = [ 
          {
            path: '/home',
            component: Home
          }//每一个对象就是一个路由
        ]
        const router = new VueRouter({
          routes//路由表  必写的
        })
      
      
    5. 导出router实例
      export default router

    6. 入口文件main.js中引入路由实例 router , 然后在根实例中注册

        import router from './router/index.js'
        new Vue({
          router,
          render: (h) => App 
        }).$mount('#app')
      
      
    7. 给路由一个路由展示区域

      1. 如果是以及路由, 那么我们放在App组件中,用一个 router-view 的组件表示
       <router-view />
      
      
    8. 当页面第一次的打开的时候, 需要做一个重定向, 就是要自动跳转到 /home 这个路由上

          const routes = [
            { //我们要求这个路由的配置要放在路由表的最上方
              path: '/',
              redirect: '/home'
            }
          ]
      
      
    9. 业务: 错误路由匹配,

          const routes = [
            {
              path: '/',
              redirect: '/home'   //重定向
            },
            {
              path: '/home',
              component: Home
            },
            {
              path: '/list',
              component: List
            },
            {
              path: '/detail',
              component: Detail
            },
            {
              path: '/login',
              component: Login
            },
            {
              path: '/register',
              component: Register
            },
            {
              path: '/user',
              component: User
            },
            {
              path: '/shopcar',
              component: Shopcar
            },
            {
              path: '/error',
              component: Error
            },
            {  //这个就是错误路由匹配, vue规定这个必须放在最下面,它必须将上面的路由全找一遍,找不到才用当前这个
              path: '**',
              redirect: '/error'
            }
          ]
      
    10. vue路由模式的确定 mode

      1. 如果你使用的是 hash , 那么a标签就可以了、
      2. 如果你使用 history , 那么我们最好将a标签改成 router-link 这个组件
        • router-link 这个组件 身上必须要有一个 to 属性
        • router-link 这个组件身上加一个 keep-alive属性可以进行浏览器缓存
    11. 二级路由

          const routes = [
            {
              path: '/shopcar',
              component: Shopcar,
              children: [
                {
                  path: 'yyb', //不写  /
                  component: Yyb
                }
              ]
            }
          ]
      
      
      • 注意: 写好配置之后,不要忘记了, 在对应的一级路由的组件中书写 路由展示区域
    12. 命名路由

      作用: 就是简写路径了

        {
            path: '/shopcar',
            component: Shopcar,
            //子路由 
            children: [
              { 
                path: 'yyb', // 容易犯错点  /yyb X 
                component: Yyb,
                name: 'yyb' //命名路由
              },
              {
                path: 'junge',
                component: Junge
              }
            ]
            
          },
      
      
      • 使用: 单项数据绑定to属性

          <router-link :to = "{name:'yyb'}"/>
        
vue-router 进阶

案例: 移动端

  • 【 分类 -》 列表 -》 详情
路由进阶 - 动态路由

核心功能

  • 路由传参
  • 路由接参
  • 动态路由:

    • url中路由是改变的,但是改变路由公用一个组件
    • 举例:
      • localhost:3000/detail/001?a=1&b=2
      • localhost:3000/detail/002?a=2&b=3
      • detail
  • vue cli3 配置反向代理 20分钟

    • 在根目录下面新建一个 vue.config.js
  // vue.config.js中可以默认直接使用  http-proxy-middleware
  module.exports = {
    devServer: {
      proxy: {
        '/douban': { // /douban 是一个标记
          target: 'http://api.douban.com', // 目标源
          changeOrigin: true, // 修改源
          pathRewrite: {
            '^/douban': '' 
          }
        },
        '/siku': {
          target: 'https://android.secoo.com',
          changeOrigin: true,
          pathRewrite: {
            '^/siku': ''
          }
        }
      }
    }
  }

/*
	注意: 修改了项目配置文件,项目必须重启
*/
  • 路由的传参 10分钟
  <router-link :to = "{name: 'list',params: {id: xxx}, query: {xxx:xxx}}"></router-link>
  • 路由的接参

    • 我们发现凡是使用了路由的组件,我们统称为: 路由组件
    • 路由组件身上会自动添加一个 $route的数据
      id: this.$route.params.id
      query: this.$route.query.xxx
    
  • 编程式导航 5分钟

    • push
      • this.$router.push('/home')
      • this.$router.push({name,params,query})
      • push可以将我们的操作存放到浏览器的历史记录
    • replace
      • this.$router.replace(’/home’)
      • this.$router.replace({name,params,query})
      • replace没有将我们的操作存放到浏览器的历史记录, 效果为返回了二级
    • push/replace的参数就是to属性的参数
  • 业务:

    • 按钮的返回
      • push
      • replace
      • back
      • go

思考: 有一个业务,当我们点击 /mine的时候,要自动跳转到 /mine/login,这个时候我们发现手段不够用了,生命周期钩子函数也实现不了,这个我们想,如果我们能监听到路由的变化,那该有多好?

思考: 如果用户没有登录,那么我们是无法进入首页的,如果登录了,那就可以进入

解决; vue为了能够监听路由的变化情况,给了一个解决方法: 这个就是导航守卫

路由进阶 – 导航守卫

别名:

  • 导航守卫
  • 路由守卫
  • 路由钩子
  • 路由拦截
  1. 作用: — 类似 【保安】

    • 守卫路由
        • 举例: 携带数据进
        • 举例: 事情完成才能出
  2. 导航守卫一共有三种形式 【 项目三选一 】

    • A: 全局导航守卫

      针对的整个项目,也就是管理或是监听整个项目

      1. 全局前置守卫 router.beforeEach(fn)
        1. fn中有三个参数
          1. to: 目标路由
          2. from: 当前路由
          3. next: 它是一个拦截,表示是否允许通过
            1. true/false/’/login’/{ name: ‘login’}/ vm => {}
        2. 使用场景: 当我们本地存储/cookie中有token,那我们就自动跳转 /mine
      2. 全局的解析守卫
        1. 在 2.5.0+ 你可以用 router.beforeResolve 注册一个全局守卫。这和 router.beforeEach 类似,区别是在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被调用。
        2. 必须保证整个项目的守卫和异步路由组件解析完成
      3. 全局的后置守卫
        • 可以做一些用户友好提示
    • B: 路由独享守卫 ·

      路由配置选项中的一个

      • 写在路由表中的守卫钩子
      • 针对的是和当前路由相关的,那么其他与之不相关的路由,它是无法监听它的变化情况的
      • 做路由拦截
        • 案例: 权限验证
          • 数据库: 用户组
            • 普通用户
            • 管理员
            • 超级管理员
          • 我们登录式,后台会返回给我们info信息,通过信息来判断它是哪个类型用户
    • C: 组件内守卫【 王者

      当前组件

      • 组件内的前置守卫 beforeRouteEnter((to,from,next)=>{})

        • 导航进入组件时,调用
        • this是访问不到的,如果非要访问this ,必须通过 next(vm=>{})访问
        • 因为组件此时没有创建,所以没有this
        • 案例: 数据预载(进入组件前就获得数据)
            next(vm => { //vm指的就是组件
               const result = JSON.parse(res.data.slice(7,-1)).rp_result.categorys
               vm.$set(vm.category,'categorys',result)
             })
        
      • 组件内的后置守卫

        • 当离开组件时,调用
        • this是可以访问到
        • 案例: 注册/内容提交,用户交互提示
      • 组件内的更新守卫( 路由传参和路由的接参 )

        • 在当前路由改变,但是该组件被复用时调用
        • 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
        • 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
        • 可以访问组件实例 this
  3. 功能: 导航守卫可以监听路由变化情况,做路由跳转拦截

  4. 名词

    • 前置: 要进入当前路由 — 老师进入教室前
    • 后置: 要离开当前路由 — 老师离开教室
  5. 关于next的使用

    • next() 等价于 next( true ) 表示可以从当前路由跳转到目标路由

    • next( false ) 表示不通过, 表示从当前路由跳转不到目标路由

    • next(’/login’) 等价于 next({path:’/login’}) 跳转指定的路由

    • next(’/login’) 等价于 next({path:’/login’,params,query})

    • next( fn ) 数据预载

      next( vm => {})
      
  6. 业务: 当我们进入到一个项目的首页时,但是当我们没有注册账号时,它主动跳转到了注册/登录页

  router.beforeEach((to,from,next) => {
      // next() // 默认true
      // next( false )
      // next()

      // 判断用户是否登录,我们找token值  cookie   localStorage 

      const token = localStorage.getItem('token')

      if ( to.path === '/home' ) {
        next()
      }
      if ( to.path == '/aa') {
        next()
      }

      if ( to.path === '/mine/login' ) {
        if ( token ) {
          // 条件成立,那么我们就可以进行页面跳转了
          next('/home')
        } else {
          // 条件不成立,留在当前页面 
          next()
        }
      } else {
        next( false )
      }

    })

  1. 业务: 当进入mine页面的时候, 要判断用户是否登录,如果没有登录,跳转登录页
  2. 路由导航守卫
    • 3中类型 7个路由监听钩子
  • 业务:
    • 监听整个项目的路由变化情况 全局的前置守卫
    • 监听某个路由的变化情况 路由的独享守卫
    • 监听的路由组件的路由变化情况 组件内的导航守卫
  1. 动效

    • animate.css 来实现路由动画
  2. 路由懒加载

  3. Vue异步组件 + Webpack

  4. 动态缓存

    • router-link 加一个keep-alive属性

      <router-link to = "" keep-alive></router-link>
      
  5. 作业:

    • 我演示内容要写出来,脱离视频写出来

Vue高级 - Vuex

Vuex称为Vue的状态管理工具,也是多组件状态共享的工具

Vuex相当于是Vue的一个集中式的存储仓库

  • 它存储的是数据 【 状态 】
  • 存储仓库: 本地存储 cookie 数据库

什么时候用: 打算开发中大型应用

集中式数据管理, 一处修改,多处使用

思维流程:
store.js
this. s t o r e . c o m m i t ( ′ i n c r e m e n t ′ ) − &gt; m u t a t i o n s t h i s . store.commit(&#x27;increment&#x27;) -&gt; mutations this. store.commit(increment)>mutationsthis.store.dispatch(‘jia’) -> actions
mapActions() ->actions mapGetters()->getters

      学生          代课老师         校长           财务      班主任             学生

(view)component - dispatch > action -> mutation -> state <- getter <- component
发送请求 处理 修改状态
业务逻辑 修改state 读取state
异步

案例: 比如我们报名考科一

  • 取号
  • 排队
  • 窗口
  • 走流程

为什么要集中式的车管所 ?

  • 统一管理、集中管理
  • 数据共享

为什么要走流程?

  • 控制执行 , 比如 100000个人同时进入会怎么样?

理解为什么要使用vuex

  • 它能够实现状态共享
  • 实现流程化,让项目的运行更加流程和优化

市场上出现了一个情况,不知道什么情况下使用vuex?

  • 中大型应用
  • 当你不确定你是否要使用vuex的时候,那就不要用了 flux作者说的

学习阶段: 必须要用

公司: 可用可不用

1. 什么是状态

​ 我们使用一条数据去管理一个视图,那么这个数据我们就称之为 ‘状态’

2. vuex是做什么的?

​ Vuex是一个集中式的存储管理中心,vuex中可以用来存储 数据( 状态 )

​ vuex也是一个状态管理中心,它也可以进行状态的管理

3. 什么是状态管理模式?

​ 我们使用一条数据去管理一个视图,那么这种管理模式就称之为 状态管理

4. 什么时候使用vuex

中大型应用使用 (使用的时间)

当你不确定你是否要使用vuex的时候,那就不要用了

5. vuex的开发流程

[外链图片转存失败(img-SstUeUiD-1568092342836)(E:\1906\2-Vue.js\note\vue笔记\img\vuex.png)]

看图说话:

  • Vuex的核心组成部分有三个,分别为: actions 、 state 、 mutations
    • actions表示动作的创建者,它的作用是创建动作,然后发送动作, 用于用户交互、后端数据交互
      • 距离: 一个用户点击了登陆按钮
    • mutations 表示动作的出发者,它的作用是用来修改数据 -更新视图
    • state它是数据的存储者,它的作用是定义数据【 状态 】
  • 后端数据交互写在actions中
  • vuex调试工具主要调试的mutations
  • vuex是流程化执行的,符合单向数据流思维

vuex - 基础操作流程

  1. 安装vuex

    $ yarn add vuex

  2. 在 src / store / index.js,【 数据不分块 】

    import Vuex from 'vuex'
    
    import Vue from 'vue'
    
    Vue.use( Vuex )
    
    // 1. 定义store 模块 
    
    // const store = new Vuex.Store( options )
    
    const store = new Vuex.Store({
      state:{
        count: 0 
      },
      actions:
        /* 
          1. actions是一个对象
          2. acitons里面放的都是方法
          3. 方法的作用是创建动作,发送动作
    
           increment ( store对象,组件发来的实际参数1,参数2 ) {}
        */
    
        increment ( { commit }, val ) {
          console.log('increment执行了')
          console.log('val', val )
          // 动作创建
          const action = {
            type: INCREMENT,
            val
          }
          // 发送动作
          commit( action )
        }
    
      },
      mutations:{
        /* 
          * 也是一个对象
          * 里面存放的也是方法
          * 方法名称是actions发送来的动作的类型
          * 接收两个参数
          *   state就是数据 , action就是actions发来的动作
          * mutations作用是用来修改数据的
          * payload表示从组件传递过来的参数   负载
        */
        [ INCREMENT ] ( state,action ) {
          console.log('mutations执行了')
          console.log( 'state',state)
          console.log( 'action',action )
          //修改数据
          state.count ++
        }
      },
      getters: {}, //getters表示帮助 视图【 组件 】  获得store中的 state 
      modules // 用来实现数据分块的
        /*
        	数据分块: 
            	一个项目中是有多个功能或是页面的,比如有
            		home
            		分类
            		列表
            		详情
            		用户
            			普通用户
            			会员
            			超级会员
                    底部栏
                    头部栏
                    图表数据
                    
                一个state管理所有的这些数据,就会变的杂乱,和不好维护,所以我们希望将数据分块,单一管理,一个数据一个模块
        */
    })
    
    // 2. 导出store模块
    
    export default store 
    
  3. 在main.js中注入store

    import store from './store'
    new Vue({
      router, // 在项目中注入路由,让所有的子组件都用于路由属性 $route  $router
      store, // 在项目中注入store,让所有的子组件拥有一个属性  $store , 用于和vuex进行通信
      render: h => h(App),
    }).$mount('#app')
    
    
  4. 在组件内使用

    <template>
      <div>
        vuex - 基础
    
        <hr/>
    
        <button @click = "add"> + </button>
        <p> {{ $store.state.count }} </p>
      </div>
    </template>
    
    <script>
    export default {
      methods: {
        add () {
          // 执行actions中的increment方法
          // this.$store.dispatch( actions中方法的名称 )
          this.$store.dispatch('increment',100)
        }
      },
      created () {
        console.log( this.$store )
      }
    }
    </script>
    
    

vuex操作流程 - 【 数据分块 】

  1. 安装vuex

    $ yarn add vuex

  2. 在 src / store /index.js

    import Vuex from 'vuex'
    import Vue from 'vue'
    import * as todos from '../pages/vuex_basic/store'
    
    Vue.use( Vuex )
    
    
    const store = new Vuex.Store({
      modules: {
        //每一个分块出去的数据包
        vue_basic: {
          state: todos.state,
          actions: todos.actions,
          mutations: todos.mutations,
          getters: todos.getters
        }
      }
    })
    
    export default store 
    
  3. 在main.js中注册

    import store from './store'
    new Vue({
      store, // 在项目中注入store,让所有的子组件拥有一个属性  $store , 用于和vuex进行通信
      render: h => h(App),
    }).$mount('#app')
    
    
  4. 在 vue_basic/store.js中打造 state actions mutations getters

    /* 
      核心组成部分是三个   +  getters 
    
      store 导出的不止一个
    
    */
    import axios from 'axios'
    const ADD_TODOS = 'addTodos'
    const GET_CATEGORY = 'getCategory'
    
    
    export const state = {
      todos: [
        {
          id: 1,
          task: '任务一'
        },
        {
          id: 2,
          task: '任务二'
        }
      ],
      category: null
    }
    
    export const actions = {
      addTodos ({ commit }, val ) {
        const action = {
          type: ADD_TODOS,
          val
        }
        commit( action )
      },
      getCategory ( {commit} ) {
        axios({
          url: '/index.php',
          params: {
            r: 'class/category',
            type: 1
          }
        }).then( res => {
          
          // 动作创建
    
          const action = {
            type: GET_CATEGORY,
            payload: res.data.data.data
          }
    
          commit( action )
    
        }).catch( error => console.log( error ))
      }
    }
    
    export const mutations = {
      [ ADD_TODOS ] ( state,action ) {
        state.todos.push({
          id: state.todos.length + 1,
          task: action.val
        })
      },
      [ GET_CATEGORY ] ( state,action ) {
        state.category = action.payload
      }
    }
    
    export const getters = {
      getTodos ( state ) {
        return state.todos 
      } 
    }
    
    
  5. 在 vue_basic/index.vue使用

    <template>
      <div>
        <h3> vuex - 数据分块 -  todolist增加功能 </h3>
        <input type="text" v-model = "val" @keyup.enter="add">
        <ul>
          <li v-for = "item in todos" :key = "item.id">
            {{ item.task }}
          </li>
        </ul>
    
        <button @click = "getCategory"> 点击获取数据 </button>
    
        <ul>
          <li v-for ='item in category' :key = "item.cid">
            {{ item.name }}
          </li>
        </ul>
    
      </div>
    </template>
    
    <script>
    import { mapState,mapActions } from 'vuex'
    export default {
      data () {
        return {
          val: ''
        }
      },
      methods: {
        ...mapActions(['addTodos','getCategory']), // 容易忘记
        add () {
          this.addTodos( this.val )
          this.val = ''
        }
      },
      computed: {
        ...mapState({
          todos: state => state.vue_basic.todos, // 这里是一个箭头函数来取数据
          category: state => state.vue_basic.category
        })
      }
    }
    </script>
    
    

四个方案:

1. 前: 标准    后: 标准  √

2. 前: 标准    后: 非标准  √

3. 前:  非标准  后: 非标准  

4. 前: 非标准  后: 标准  √

component ---dispatch---> actions ---commit--->mutations---state <----getters----component

思考:

  1. 数据的获取无论是标准还是非标准,都是很麻烦的,并且有些有些违背关注点分离
  2. actions或是mutations的通信会出现多个 this. s t o r e . d i s p a t c h / t h i s . ​ store.dispatch / this.​ store.dispatch/this.store.commit

解决方案: 、

​ 使用vuex辅助工具

6. 辅助工具

mapActions

mapMutations

mapGetters

mapState

export default 默认导出一个

export 叫批量导出,可以导出多个

7. vuex数据分块

将来我们的数据

​ 希望是分块管理的,这样方便我们将来为何和更新

vue是通过一个叫做 module 的模块来管理的

​ vue项目中 store下的一个目录就是一个数据包

​ 案例: todolist的添加操作

作业:
  1. 使用vuex实现计数
  2. 使用vuex实现todolist中添加( 使用数据分块 module )
  3. vuex实现购物车

三、Webpack

  1. 了解webpack在前端开发当中的一个重要性
  2. 了解webpack版本信息
  3. webpack基本配置
    • 如何使用webpack配置项目
  4. 掌握程度: <= webpack 30%
一、前端工程化工具

也叫: 自动化工具

  1. grunt
  2. gulp ( 4.x )
  3. Browserify ( Webpack 前身 )
  4. Webpack 【 主流行 】
  5. rollup.js https://www.rollupjs.com/guide/zh 【 小众 】
  6. parcel 【 小众 】
  7. FIS https://fis.baidu.com/ 【 小众 】
二、前端工程化工具的发展历程
  1. grunt
  2. gulp ( 4.x ) 流的操作 .pipe()
  3. Browserify ( Webpack 前身 ) 没有兼容模块化问题( es6 )
  4. Webpack 【 主流行 】 自动解决模块依赖性问题
    • AMD
    • CMD
    • es Module
    • 可以将其他类型文件做转换
三、 Webpack版本的发展过程

​ 官网: https://webpack.js.org/

​ 中文: https://www.webpackjs.com/

webpack1

​ 支持CMD和AMD,同时拥有丰富的plugin和loader,webpack逐渐得到广泛应用。

​ loader 转化器

webpack2

​ 支持ES Module,分析ESModule之间的依赖关系,

​ webpack1必须将ES,Module转换成CommonJS模块,2支持tree sharking

webpack3

​ 新的特性大都围绕ES Module提出,如Scope Hoisting和Magic Comment;

​ webpack3以上基本上都可以解决es6提出的模块化

webpack4

​ 可以解决es6模块化【 export default / export import 】

​ 更多个功能性 pulgin【 插件 】 和 loader 【 转换器 】

​ 前端框架中广泛使用: Angular Vue React 的脚手架都是由webpack来进行开发、管理

学习目标:

​ - 通过webpack自主构建一个项目 【 手动构建一个项目 】

  • webpack基本配置
  • webpack高级配置
四、 Webpack涉及到的前端环境问题
  1. Webpack底层是由 Node.js 来开发的,也就是说Webpack的配置文件都是 Node.js 文件
  2. Webpack的模块化书写的规范是Common.js规范
  3. 环境支持: Node.js 8+
  4. 前端环境: 【 重点 】
    • 开发环境 - 无法直接在服务器中去运行
    • 生产环境 - 将开发环境下的代码经过 打包 压缩 编译 之后的文件
    • 测试环境 - 将开发环境的代码经过 打包 压缩 编译 之后的文件,放在测试环境服务器中运行
      • unit test 单元测试 【 mocha Jest 】
      • e2e 端到端测试
    • 预上线环境: 将开发环境的代码经过 打包 压缩 编译 之后的文件,放到一个局域网中去运行
    • 上线环境:将开发环境的代码经过 打包 压缩 编译 之后的文件,放到云服务器或是服务器主机中,可以供任何人访问,使用的一个环境( 这个环境的上线要经过国家审核 )
      • 云服务器: 类比: 宾馆 中有很多的单间,每一个云服务器就是其中一个单间
      • 主机: 整个酒店
  5. 核心关注点在:
    • 开发环境
    • 生产环境
五、Webpack的安装

安装可以使用任何一个包管理器: npm yarn cnpm

yarn > cnpm > npm

举例: 我使用npm安装了一个叫做 node-sass 的包 ,但是出错了 ,这时,我们想卸载,发现卸载报错

解决: 覆盖安装

cnpm || yarn 进行覆盖安装

cnpm 和 yarn 优先级没有那么绝对

版本信息

​ webpack 4.39.3

​ webpack-cli 3.3.7

1.全局安装

$ npm install webpack webpack-cli -g

$ cnpm install webpack webpack-cli -g

$ yarn add webpack webpack-cli global

2.局部安装

$ npm install webpack webpack-cli -D

$ cnpm install webpack webpack-cli -D

$ yarn add webpack webpack-cli -D

局部优先级 > 全局

六、Webpack的概念
  • webpack* 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle( 分块束 )

    理解:

    ​ 举例: 我们又两个模块,A模块引用B模块,我们现在使用webpack打包A模块,webpack会自动寻找A和B之间的关系,进而打包B模块

七、Webpack 使用

默认源代码开发目录为: src

默认的入口文件名称为: src/index.js

默认出口目录为: dist

默认出口打包文件名称为: main.js

通过mode来设置是那个环境下打包使用

开发环境打包: 代码不经过压缩、注释不会被删除

eval 这个方法时用来解析字符串,这个字符串里面有js代码 【 性能不太好 】

1.终端命令行使用
  • 终端运行 webpack

    • 当我们局部安装了webpack webpack-cli后,发现运行webpack报错命名找不到

      • 解决: 全局安装webpack webpack-cli
    • 默认生成环境打包

  • webpack --mode development/production 开发环境/生产环境打包

2.配置文件使用
  • 默认webpack配置性文件名称为 webpack.config.js,这个文件是在根目录下运行的
  • 运行 webpack 命令就会自动的去寻找这个 文件
  • webpack.config.js文件中我们配置的就是 webpack的参数
3.配置webpack.config.js文件

我们接下来对这个文件进行配置,主要从以下几个方面来着手

1. 基础功能 :  入口   出口 文件配置
2. 转换器: loader 
3. 插件: plugin

单页面配置  vs  多页面配置 
	单页面配置指的只有一个入口一个出口的项目  【 推荐 】
	多页面配置指的是有多个入口多个出口的项目

1.单页面配置
1.1 基础功能
/* 
  webpack配置文件
  也是Node.js文件
  这个文件也是一个独立的 Common.js 模块
*/

const path = require('path')

// 1. 创建模块

const webpackConfig = {
  entry: './src/index.js', //网络路径( 相对路径 )
  output: { //出口目录、文件的配置
    path: path.join( __dirname,'dist'), // 磁盘路径
    filename: 'js/app.js' // 入口文件将来打包到出口目录中的文件的路径和名称
  },
  mode: 'development'//确定是生产环境还是开发环境的打包
}

// 2. 导出模块

module.exports = webpackConfig





1.2 问题: 验证webpack是否能自动解决模块化依赖问题 可以
  • 打造MVC
    • index.js 用了 C
    • C 里面用 M
    • M里面用 V
1.3 loader 转换器 可以将其他类型文件转换为我们想要的类型文件

​ 举例: 实现css的使用

  /* ------------------------------- 转换器 ------------------------------ */
  // 在webpack.config.js中做如下配置:
  module: { //这里用来存放转换器的配置
    rules: [
      // {} //每一个对象就是一个转换器的配置
      {//css的处理
        test: /\.css$/, // 整个项目下匹配 .css结尾的文件
        use: ['style-loader','css-loader'] //两个顺序是不写反的
        // 我们需要使用css-loader将css文件编译为js,然后通过style-loader将js处理插入到html文件中【 style 嵌入模式 】
      }
    ]
  },

1.4 配置前端静态服务器
	//需要自动刷新: webServer 搭建前端开发服务器
    cnpm install webpack-dev-server -g | -D
    参数:
        命令行
        webpack-dev-server --port 8088 --open --mode development

        写到webpack.config.js配置文件:

        devServer: {//和module同级
            port: 8088,
            open:true
        }

        终端运行方式2: webpack-dev-server
    
    把运行命令放到package.json文件:    devServer可以不要了
        "scripts":{
            "dev": "webpack-dev-server  --port 8088 --open"
        }

        终端: npm run dev

1.5 优雅降级配置
  • 先安装转换器需要的包

    $ cnpm install babel-loader@8.0.4 @babel/core @babel/preset-env -D

  • 配置webpack.config.js

    	// 在webpack.config.js的module.rules中进行配置
            {// 配置优雅降级
                test: /\.js$/,
                exclude: /node_modules/, // 排除node_models中的js文件
                use: [{
                  loader: 'babel-loader',
                  options: {
                    presets: ['@babel/preset-env']
                  }
                }]
    
              }
    
    
1.6 html产出 - 依赖的是插件
  • 安装插件需要的第三方包

    $ cnpm i html-webpack-plugin -D

    	const HtmlWebpackPlugin = require('html-webpack-plugin')
    	
        //添加一个配置项
        plugins:[
                new HtmlWebpackPlugin({
                    template: './public/index.html',
                    filename: './index.html',//默认到output目录
                    hash:true,//防止缓存,会给文件后面加入hash
                    minify:{
                        removeAttributeQuotes:true//压缩 去掉引号
                    }
                })
        ]
    
    
1.7 css抽离 - 依赖的是插件

将webpack编译过得css文件以 css外部引用的形式引入

  • 安装插件

    $ cnpm i extract-text-webpack-plugin@next -D

        const ExtractTextWebapckPlugin= require("extract-text-webpack-plugin")
    
        //loader配置:
        use: ExtractTextWebapckPlugin.extract({
              use: 'css-loader'
            }) //不再需要style-loader
    
        //pulgin配置
        new ExtractTextWebapckPlugin('css/[name][hash:6].css')
    
    
1.8 图片打包
yarn add url-loader file-loader --dev

npm I url-loader file-loader --save-dev

    //url-loader 存base64  file-loader存文件(woff mp3)
    {
        test:/\.(png|jpg|gif)/,
        use:[{
          loader: 'url-loader',
          options: {
            limit: 5000,//字节少于5000 ——》 base64  超过5000  file
            outputPath: 'images/', //5000意思存到images
          }
        }]
      }

//css中引入 | js动态(模块化) 引入

1.9 静态资源拷贝
  npm i copy-webpack-plugin -D

    const CopyWebpackPlugin = require('copy-webpack-plugin')
//plugin配置
    new CopyWebpackPlugin([
      { from: path.resolve(__dirname,'static'), to: 				path.resolve(__dirname,'build/static') }
    ])


1.10 配置文件拆分
"dev": "webpack --mode development --config config/webpack.config.dev.js",
"build": "webpack --mode production --config config/webpack.config.prod.js",
"server": "webpack-dev-server --mode development --config config/webpack.config.dev.js"


1.11 错误资源定制
// 在webpack.config.js中添加如下配置项:
devtool: 'source-map'  
制定报错信息的源


1.12 后缀名省略

   // 配置webpack.config.js
    resolve: {     //与module同级
        extensions: [ '.js', '.css', '.json', '.jsx']
    }
    require('./style')// 可以省略后缀名


2.多页面配置
2.1 基础功能
/* 
  webpack配置文件
  也是Node.js文件
  这个文件也是一个独立的 Common.js 模块
*/

const path = require('path')

// 1. 创建模块

const webpackConfig = {
  entry: { // 多页面配置,多个入口文件
    'index': './src/index.js',
    'main': './src/main.js'
  }, //网络路径( 相对路径 )
  output: { //出口目录、文件的配置
    path: path.join( __dirname,'dist'), // 磁盘路径
    filename: 'js/[name].js' // 入口文件将来打包到出口目录中的文件的路径和名称
  },
  mode: 'development'//确定是生产环境还是开发环境的打包
}

// 2. 导出模块

module.exports = webpackConfig






解释: 为什么我们的文件要跟上hash后缀?
  • 目的: 就是为了创建多个版本,便于版本切换

[外链图片转存失败(img-sKf4RZcs-1568092342837)(E:\1905\2-Vuejs\Vue高级\day05\code\为什么webpack会给文件加后缀.png)]

作业:

​ webpack配置功能完成 2 次

​ 配置sass

​ 配置postcss

​ 组件版的 todolist

​ 复习 【 整理 】

四、Vue项目 与 高级应用

数据中心机房是现代信息技术的核心设施,它承载着企业的重要数据和服务,因此,其基础设计与规划至关重要。在制定这样的方案时,需要考虑的因素繁多,包括但不限于以下几点: 1. **容量规划**:必须根据业务需求预测未来几年的数据处理和存储需求,合理规划机房的规模和设备容量。这涉及到服务器的数量、存储设备的容量以及网络带宽的需求等。 2. **电力供应**:数据中心是能源消耗大户,因此电力供应设计是关键。要考虑不间断电源(UPS)、备用发电机的容量,以及高效节能的电力分配系统,确保电力的稳定供应并降低能耗。 3. **冷却系统**:由于设备密集运行,散热问题不容忽视。合理的空调布局和冷却系统设计可以有效控制机房温度,避免设备过热引发故障。 4. **物理安全**:包括防火、防盗、防震、防潮等措施。需要设计防火分区、安装烟雾探测和自动灭火系统,设置访问控制系统,确保只有授权人员能进入。 5. **网络架构**:规划高速、稳定、冗余的网络架构,考虑使用光纤、以太网等技术,构建层次化网络,保证数据传输的高效性和安全性。 6. **运维管理**:设计易于管理和维护的IT基础设施,例如模块化设计便于扩展,集中监控系统可以实时查看设备状态,及时发现并解决问题。 7. **绿色数据中心**:随着环保意识的提升,绿色数据中心成为趋势。采用节能设备,利用自然冷源,以及优化能源管理策略,实现低能耗和低碳排放。 8. **灾难恢复**:考虑备份和恢复策略,建立异地灾备中心,确保在主数据中心发生故障时,业务能够快速恢复。 9. **法规遵从**:需遵循国家和地区的相关法律法规,如信息安全、数据保护和环境保护等,确保数据中心的合法运营。 10. **扩展性**:设计时应考虑到未来的业务发展和技术进步,保证机房有充足的扩展空间和升级能力。 技术创新在数据中心机房基础设计及规划方案中扮演了重要角色。例如,采用虚拟化技术可以提高硬件资源利用率,软件定义网络(SDN)提供更灵活的网络管理,人工智能和机器学习则有助于优化能源管理和故障预测。 总结来说,一个完整且高效的数据中心机房设计及规划方案,不仅需要满足当前的技术需求和业务目标,还需要具备前瞻性和可持续性,以适应快速变化的IT环境和未来可能的技术革新。同时,也要注重经济效益,平衡投资成本与长期运营成本,实现数据中心的高效、安全和绿色运行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值