Skip to content
标签
VUE
前端框架
字数
9735 字
阅读时间
39 分钟

一、简介

1.1 介绍

Vue.js是一个构建数据驱动的 web 界面的渐进式框架。Vue.js 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。 渐进式框架:Progressive,说明vue.js的轻量,是指一个前端项目可以使用vue.js一两个特性也可以整个项目都用 vue.js。 自底向上逐层应用:作为渐进式框架要实现的目标就是方便项目增量开发。 地址:https://cn.vuejs.org/v2/guide/

1.2 使用

  1. 在html页面使用script引入vue.js的库即可使用。
  2. 使用Npm管理依赖,使用webpack打包工具对vue.js应用打包。 大型应用推荐此方案。
  3. Vue-CLI脚手架 使用vue.js官方提供的CLI脚本架很方便去创建vue.js工程雏形。

1.3 功能

  1. 声明式渲染 Vue.js 的核心是一个允许采用简洁的模板语法来声明式地将数据渲染进 DOM 的系统。 比如:使用vue.js的插值表达式放在Dom的任意地方, 差值表达式的值将被渲染在Dom中。

  2. 条件与循环 dom中可以使用vue.js提供的v-ifv-for等标签,方便对数据进行判断、循环。

  3. 双向数据绑定 Vue 提供v-model 指令,它可以轻松实现Dom元素和数据对象之间双向绑定,即修改Dom元素中的值自动修改绑 定的数据对象,修改数据对象的值自动修改Dom元素中的值。

  4. 处理用户输入 为了让用户和你的应用进行交互,我们可以用 v-on 指令添加一个事件监听器,通过它调用在 Vue 实例中定义的 方法

  5. 组件化应用构建 vue.js可以定义一个一个的组件,在vue页面中引用组件,这个功能非常适合构建大型应用。

二、基础

2.1 MVVM模式

MVVM是Model-View-ViewModel的简写。它本质上就是MVC 的改进版。MVVM 就是将其中的View 的状态和行为抽象化,让我们将视图 UI 和业务逻辑分开 MVVM模式和MVC模式一样,主要目的是分离视图(View)和模型(Model) Vue.js 是一个提供了 MVVM 风格的双向数据绑定的 Javascript 库,专注于View 层。它的核心是 MVVM 中的 VM,也就是 ViewModel。 ViewModel负责连接 View 和 Model,保证视图和数据的一致性 vue.js是一个MVVM的框架,理解MVVM有利于学习vue.js。

  • MVVM拆分解释为:
    • Model:负责数据存储
    • View:负责页面展示
    • View Model:负责业务逻辑处理(比如Ajax请求等),对数据进行加工后交给视图展示
  • MVVM要解决的问题是将业务逻辑代码与视图代码进行完全分离,使各自的职责更加清晰,后期代码维护更 加简单

2.2 页面引入vue的js文件

html
<!DOCTYPE html> 
<html lang="en"> 
    <head>
        <meta charset="UTF‐8"> 
        <title>vue.js入门程序</title>
        <script src="/js/vue/vue.min.js"></script> 
    </head> 
    <body> 
        <div id="app"> 
            {{name}} 
            <!‐‐ 在Vue接管区域中使用Vue的系统指令呈现数据 这些指令就相当于是MVVM中的View这个角色 ‐‐>
        </div> 
    </body> 
    <script>
        // 实例化Vue对象
        //vm :叫做MVVM中的 View Model 
        var VM = new Vue({ 
            el:"#app",//表示当前vue对象接管app的div区域 
            data:{
                name:'传智播客'// 相当于是MVVM中的Model这个角色 }
                 }); 
    </script>
</html>

2.3 模板语法

  • 插值

    • 使用
      • 内容可以为data中的变量名、运算、或者表达式
    • 向标签中添加html代码
      • v-html标签,后跟data中的变量名
  • 指令

    • v-bind

      • 绑定属性
      • v‐bind可以将数据对象绑定在dom的任意属性中。可以给dom对象绑定一个或多个特性,例如动态绑定style和class,如:
        <img v‐bind:src="imageSrc"> 
        <div v‐bind:style="{ fontSize: size + 'px' }"></div>
      • 可简写为
    • v-on:

      • 绑定事件,事件对应名称为methods中的方法名
      • v-on:click:监听点击 v-on:keydown:监听案件 v-on:mouseover:监听鼠标移入
  • template

    • 只在VUE代码中显示,在html网页不显示,框选其中内容,但不影响其选择级别,和标签外的标签同级

2.4 绑定多个class和style属性

  • 使用对象语法
    • 使用对象语法向其中添加内容需使用VUE.set方法
  • 使用数组语法
    • 向其中添加元素使用push方法即可

2.5 条件渲染

  • v-if
    • 对取值进行判断,为ture则显示
  • v-else
    • 与if标签相反
  • v-else-if
    • 多重判断
  • v-show
    • if相同功能,区别是v-show是将所修饰的标签隐藏,if是删除

2.6 列表渲染

  • v-for
    • in of
      • 对数组进行遍历
        • v-for="元素名 in 数组名"
    • key
      • 对vue检测进行优化,没有key值则依靠索引进行对比,若不同则进行修改,修改的多,效率低,设定key值则对key值进行判断,值未变则不修改,若中间有插入的则插入,不影响其他,
      • key值是每项都有且唯一的id

2.7 数组更新检测

  • vue可以检测到的变动

    • push() pop() shift() unshift() splice() sort() reverse()
  • 生成新的数组

    • filter(), concat() 和 slice() ,map(),新数组替换旧数组
    • 生成的新数组与原数组不是同一个,需将新数组替换为旧数组
  • 不能检测到的变动

    • vm.items[indexOfItem] = newValue

      • 根据索引修改值
    • 解决方案

      • Vue.set(哪个数组,索引位置, 新的值)
      • 使用splice方式
  • 过滤显示数组内容

    • 通过filer方法中调用函数判断
      • this.list.filter((item)=>item.indexOf(this.mytext)>-1)

2.8 事件处理

  • 添加事件

    • 直接写表达式

      • 简单的事件处理可以使用该方式
    • 写函数名不加括号

      • 获取的是该事件的对象
    • 写函数名后加括号

      • 传参时使用,既想获取事件对象,又想传参时在括号中添加$event
  • 事件修饰符

    • 是在事件绑定参数后用.连接的,如@click.stop

    • stop

      • 阻止父标签的事件触发
    • prevent

      • 阻止默认事件
        • 如a标签的跳转
    • self

      • 只对当前标签元素有效,对其子标签无效
    • once

      • 事件只触发一次
    • event.stopPropagation();//阻止冒泡

  • 按键修饰符

    • @keydown.加案件对应的值即可为对应的案件添加相应的按键事件,.enter 和上下左右键可以直接写字符,vue对其进行了封装

    • 如:

      .enter .tab .delete (捕获 "删除" 和 "退格" 键) .esc .space .up .down .left .right .ctrl .alt .shift .meta v-on:keyup.enter
  • 事件解绑

    • 通过一个变量为boolean类型的值与事件&&连接,修改变量的值即可使事件是否执行
      • @click="isFirst && handleLiClick1()"

2.9 表单控件

  • v-model
    • 对输入框中的值和data中的变量值进行双向绑定,哪一方进行修改都会改变
    • 在表单控件或者组件上创建双向绑定 2、v-model仅能在如下元素中使用:input 、select 、textarea 、components(Vue中的组件)
    • 如对复选框绑定时,data中对应一个数组,每个复选框标签对应一个值,当勾选是即可使对应的值存入对应的数组中,数组中有某个值时,该复选框的状态也是被勾选的状态(单选框同理,对应的data中变量取值为字符串)
  • 修饰符
    • .lazy
      • 不同步更新,只在失去焦点时同步一次
    • .number
      • 格式化数字,将输入内容强制转换为数字,若转换不了则失效
    • .trim
      • 去除首位空格
  • v-html 可解析页面
  • v-text可以将一个变量的值渲染到指定的元素中,它可以解决插值表达式闪烁的问题

三、组件

3.1 实现数据请求

  • fetch
    • get方式

      • fetch("**").then(res=>res.json()).then(res=>{console.log(res)})
    • 获取内容转为json格式

    • fetch("**").then(res=>res.text()).then(res=>{console.log(res)}

      • 内容为文本格式
    • post方式

      js
        fetch("**",{
        method:'post',
        headers: {	//请求头信息
        "Content‐Type": "application/x‐www‐form‐urlencoded"
        },
        body: "name=kerwin&age=100" //传递的值
        }).then(res=>res.json()).then(res=>{console.log(res)});
js
      fetch("/users",{
      method:'post',
       // credentials: 'include',    //默认不携带cookie,添加则携带
       headers: {
      "Content‐Type": "application/json"   //json格式
       },
       body: JSON.stringify({    //传递的对象需转为json格式
       name:"kerwin",
       age:100
       })
       }).then(res=>res.json()).then(res=>{console.log(res)});
  • axios
    • get
js
      axios.get("json/test.json").then(res=>{
      console.log(res.data);//真正的后端数据藏在res.data
       })
  • post
js
      axios({
      url:"",   //请求地址
      method: "",//请求方式
      headers:{},     //携带的请求头信息
      data:{}             //携带数据
      }).then(res=>{
      console.log(res.data);
      })

3.2 计算属性

  • 在computed中添加函数,调用时后面不加括号,必须有返回值 (调用属性和计算不需要加括号,调用方法需要)

  • 页面中多次调用时,只在第一次计算结果,后面调用从缓存中取值

  • 特点

    • 计算属性是基于它们的依赖进行缓存的。
    • 计算属性只有在它的相关依赖发生改变时才会重新求值
  • 适用场景

    • 在一个页面多次调用计算结果,如购物车总金额计算,模糊查询结果
  • watch

    • 与computed同属于vue的属性,可以监听某个data中属性的值的改变,监听必须保证其中属性名与data中的属性名保持一致

3.3 混入mixins

  • 混入 (mixins) 是一种分发 Vue 组件中可复用功能的非常灵活的方式。 混入对象可以包含任意组件选项
  • 可以将其他对象的方法加入vue代码中,提高代码复用性
  • mixins对应的是一个数组,可以添加多个对象
  • 若混入的对象与当前vue对象的方法中包含同名方法,则调用vue的方法

3.4 组件

  • 组件作用
    • 扩展html元素,封装可重用的代码
  • 注册方式
    • 全局组件
      • Vue.component

        • 代码实例
js
Vue.component("navbar",{
            template: `htmldom节点,只能有一个根标签`,
            data(){
              return {data必须是函数形式}
              // 组件与组件 的状态需要相互隔离, 要设计成函数。
            },
            methods:{ 与之前相同},
            components:{
            })
  • 局部组件
    • 使用components属性中添加组件
      • 代码示例
components:
            navbarchild:{
              template:`<div>navbarchild--{{title}}</div>`,
                  data(){ return { }   }
             } }
  • 调用方式

    • 使用标签调用,标签为组件名
  • 注意事项

    • *自定义组件需要有一个root element
    • *父子组件的data是无法共享
    • *组件可以有data,methods,computed....,但是data 必须是一个函数
  • 父子组件之间传值

    • 父传子

      • 父组件在调用子组件的标签时对其添加属性,属性名自定义,若传递的是非字符串类型如布尔类型的值需前面加v-bind绑定
      • 子组件使用props属性获取父组件传递的值,可为数组类型或对象类型,数组类型中为父组件传值的属性名,获取后可作为data中的属性值使用,若为对象类型,则对象中为 属性名:类型
        • props:{name:Number}Number,String,Boolean,Array,Object,Function,null(不限制类型)
        • 添加属性验证若所传递的值类型不符合,则在控制台报错
    • 子传父

      • 父组件在调用子组件的标签中绑定一个事件,绑定名称自定义,事件名后不加括号,在vue的methods属性中添加事件,添加形参可以获取子组件传来的值
      • 子组件向父组件传值时,需要添加事件,在事件中调用this.$emit("父组件绑定的名称",向父组件传递的数据)
    • ref方式

      • 在标签中添加ref属性,对应的名称自定义
      • 在方法中可以通过this.$refs获取页面所有的具有的ref属性的标签对象
        • 对于普通标签,取到的是原生节点dom对象 对于组件标签,取到的是组件对象
      • 调用某个指定对象通过this.$refs.ref属性对应的名称调用,可以查看和修改对象的信息,也可用于子传父和父类调用子类信息
  • 兄弟之间传值(bus)

    • 首先创建一个新的空白vue实例
      • 新建一个空白实例作为桥梁
    • 发送方添加事件,新建实例名.$emit(“事件名”,传递的信息)发送
    • 接收方需在
js
mounted(){
    新建实例名.$on(“事件名”,函数可通过形参获取值))
    }

中添加

  • monted是生命周期的钩子,在模板渲染成html后调用,通常是初始化页面完成后,再对html的dom节点进行一些需要的操作

    • 通过$on对事件进行监听
  • 传值还可在外部模块中建立,模块只会加载一次,因此,不同的部分导入的都是同一个实例

  • 动态组件

    • <component> 元素,动态地绑定多个组件到它的 is 属性 is后可以是全局组件或局部组件,is指向哪个组件就显示哪个
  • <component :is="who"></component>

  • <keep-alive> 保留状态,避免重新渲染 即在切换组件后再切换回来仍保持切换之前组件被修改后的状态

四、虚拟dom与diff算法

vue管理会创建一个虚拟dom节点,当发生改变时会对dom节点进行对比

对比原则

  • 逐层对比,只对比相应层级的dom节点
  • 同key值对比,key值指定是唯一的,对key值进行对比就能发现哪些不对应或者是新增的
  • 同组件对比,如对标签类型进行对比,若不相同,则直接对其进行删除,新建新的节点

五、高级用法

5.1 slot插槽

  • 单个插槽

    • 概述

      • 即在子组件中使用<slot>标签占位,在调用的父组件的标签内填写要在子组件中添加的内容,将父组件中的内容添加至子组件中,父组件的内容在父组件的作用域中编译,可调用父组件的属性及事件
    • 适用场景

      • 需要依赖父组件属性的子组件,设定成模板,需用户自己添加内容的组件
  • 具名插槽

    • 对插槽起一个名字,在父组件调用时,在父组件添加的内容标签添加slot属性,该属性与想替换的插槽名字对应

5.2 transition过渡动画

  • 单元素单组件过渡
    • 使用自带的动画
      • 1.将类选择器的动画添加,类选择器的命名规则如: enter-active之前的名字为自定义
css
        .kerwinfade-enter-active, .kerwinfade-leave-active {
        transition: all 1.5s;
        }
        .kerwinfade-enter, .kerwinfade-leave-to /* .fade-leave-active below version 2.1.8 */ {
        opacity: 0;
        transform: translateX(100px);
        }
  • 2.将需要添加动画的元素或组件使用<transition>标签包裹,并将name属性赋值为自定义名称

    • 结合animate.css动画库
      • 1.引入animate的css文件
      • <transition>标签的特定class 赋animate的样式的值
html
		<transition enter-active-class="animated bounceInRight" leave-active-class="animated bounceOutRight">            
				<p v-show="isShow">33333333333333333</p>
        </transition>
  • 多组件的过渡

    • 还是只有一个主标签,只是内容改变,如v-if和v-else只显示一个的标签,如果他们修饰的标签类型相同,当添加切换动画时,由于是相同标签,vue会直接复用标签,不涉及删除修改,若想添加动画,则需添加key值,添加mode属性的值修改动画执行的方式 :in-out 先来再走 out-in先走再来 <component>动态组件 标签修改显示组件 也涉及动画 ,同理
  • 列表过度

    • 使用transition-group不同于transiton,他会以一个真实的元素呈现,默认为一个span标签,可使用tag属性更换为其他标签元素
      • 必须提供唯一的key属性值
    • 注意:当使用索引当作key值时,若遍历后删除中间的元素,key值是最后一个key值删除,其他元素改变,因此添加移除动画时都会显示在最后一个上
  • 可复用过渡

    • 将组件内的内容使用动画标签包裹,将动画效果封装在组件里

5.3 生命周期

vuejs

  • beforeCreate(创建vue实例前'):
    • 数据还没有监听,没有绑定到vue对象实例,同时也没有挂载对象
  • created(创建vue实例后):
    • 数据已经绑定到了对象实例,但是还没有挂载对象
  • beforeMount(挂载到dom前):
    • 模板已经编译好了,根据数据和模板已经生成了对应的元素对象,将数据对象关联到了对象的el属性,el属性是一个HTMLElement对象,也就是这个阶段,vue实例通过原生的createElement等方法来创建这个html片段,准备注入到我们vue实例指明的el属性所对应的挂载点
  • mounted(挂载到dom后)
    • 将el的内容挂载到了el,相当于我们在jquery执行了(el).html(el),生成页面上真正的dom,上面我们就会发现dom的元素和我们el的元素是一致的。在此之后,我们能够用方法来获取到el元素下的dom对象,并进 行各种操作
  • beforeUpdate(数变化更新前)
    • 数据更新到dom之前,我们可以看到$el对象已经修改,但是我们页面上dom的数据还没有发生改变
  • updated(数据变化更新后)
    • dom结构会通过虚拟dom的原则,找到需要更新页面dom结构的最小路径,将改变更新到dom上面,完成更新
  • beforeDestroy(vue实例销毁前),destroyed(vue实例销毁后)
    • 实例的销毁,vue实例还是存在的,只是解绑了事件的监听还有watcher对象数据与view的绑定,即数据驱动

Vue在实例化的过程中,会调用这些生命周期的钩子,可以在函数中定义业务逻辑

5.4 swiper

  • https://www.swiper.com.c

  • 动态效果插件

    • 注意:防止swipe初始化过早
  • 解决异步请求动态数据的问题

    • 当添加动态效果的标签是ajax异步请求后获得的,应在请求结束后再新建swiper对象
    • vue的解决方式:在调用组件的标签中绑定key值,如果发生改变,key值变化则对其进行销毁,再新建一个,因此会再次执行vue的mounted生命周期,在此生命周期中新建swiper则能解决

5.5 指令

  • 可以获取dom节点和对dom节点的生命周期进行检测
  • 声明
    • 使用
js
Vue.directive('指令名',{
    dom的生命周期状态(el, bind,vnode){    }
    })
- el是当前dom对象,bind为当前节点声明所传递的值,可以为对象,vnode(vnode.context)可以使用newvnode和oldvnode获取更改前和更改后的dom节点,vnode.context可以拿到当前的vue实例
  - 虚拟dom,可以理解为对dom的备份,当修改后,会再形成一个dom,将两个dom节点对比后就能发现哪些不同
  • 调用

    • 在节点中添加属性v-指令名,后可跟值,在指令中可使用bind进行获取
  • this.$nextTick

    • 再监听dom完成更新后调用回调函数
    • this.$nextTick()将回调延迟到下次 DOM 更新循环之后执行。在修改数据之后立即使用它,然后等待 DOM 更新。它跟全局方法 Vue.nextTick 一样,不同的是回调的 this 自动绑定到调用它的实例上。

5.6 过滤器

  • 作用:对数据和字符串格式的转换
  • 声明方式
js
 Vue.filter(“过滤器名称”,function传递的形参){
    对传递的值进行处理并返回
    })
  • 调用方式
    • 在需要进行转换的值后加“|”和过滤器名称

5.7 一个js文件中多个函数到处方法

  • 封装一个对象,将多个函数引入,导出该对象

    • 引入时需导入对象
    • 导入时必须导入全部
  • 将export后的default删除,更改为{函数1,函数2.。。}方式

    • 引入时导入{函数名,函数2}
    • 该方式可以导入某个函数

六、vue脚手架

6.1 vue脚手架

  • https://blog.csdn.net/weixin_30918415/article/details/101076043

  • 单文件组件https://cn.vuejs.org/v2/guide/single-file-components.html

    html
    <template>
    html代码
    </template>
    <script>
    js代码
    </script>
    <style>
    css代码
    </style>
    
    <template>
    html代码
    </template>
    <script src="相对路径的外部的js"></script>
    <style src="相对路径的外部的css"></style>
  • vue-cli3.0的使用

    npm install -g @vue/cli (一次安装)
    vue create myapp
    *npm run serve 开发环境构建
    *npm run build 生产环境构建
    *npm run lint 代码检测工具
    
    style标签 加上scoped属性,css局部生效
    style标签 加上lang="scss",支持scss
  • Vue.config.js的配置

    • proxy代理https://cli.vuejs.org/zh/config/#全局-cli-配置

      devServer: {
      port:8000, //随便改端口号
      proxy: {
      '/v4': {
      target: 'https://m.maizuo.com',
      host: 'm.maizuo.com',
      changeOrigin:true
      }
      }
      }
    • alias别名配置

      • @ is an alias to /src
    • vue.config.js 中配置 publicPath: './ ',

    • 关闭eslint

    • Json-server实现mock数据https://github.com/typicode/json-server

    • MPA(多页面)应用的配置https://cli.vuejs.org/zh/config/#pages

      module.exports = {
      pages: {
      index: {
      // page 的入口
      entry: 'src/index/main.js',
      // 模板来源
      template: 'public/index.html',
      // 在 dist/index.html 的输出
      filename: 'index.html',
      // 当使用 title 选项时,
      // template 中的 title 标签需要是 <title><%= htmlWebpackPlugin.options.title %></title>
      title: 'Index Page',
      // 在这个页面中包含的块,默认情况下会包含
      // 提取出来的通用 chunk 和 vendor chunk。
      chunks: ['chunk‐vendors', 'chunk‐common', 'index']
      },
      // 当使用只有入口的字符串格式时,
      // 模板会被推导为 `public/kerwin.html`
      // 并且如果找不到的话,就回退到 `public/index.html`。
      // 输出文件名会被推导为 `kerwin.html`。
      kerwin: 'src/kerwin/main.js'
      }
      }
  • 利用vue-cli进行组件化开发

    • 迁移todolist、swiper案例到vue-cli中

6.2 vue单文件

  • css作用域

    • style标签 加上scoped属性,css局部生效 style标签 加上lang="scss",支持scss
  • 解决请求跨域

    • 通过Vue.config.js的配置proxy代理

      • https://cli.vuejs.org/zh/config/#%E5%85%A8%E5%B1%80-cli-%E9%85%8D%E7%BD%

      • vue.config.js 中配置 publicPath: ./

  • 导入问题

    • 用@符号 表示src,相当于根目录,绝对路径

6.3 vue多页面开发

  • https://cli.vuejs.org/zh/config/#pag

6.4 别名

  • 通过配置slias属性,对该路径起一个别名

    @ is an alias to /src

6.5 路由

  • 修改router.js文件在其中添加匹配的路径的所加载的组件

    • 添加的属性path:路由匹配的路径component对应的 组件名children 嵌套的路由(不必须) name 路由别名 alias 路径别名
    • 需导入相应的组件,并在主页面的vue对象中添加router属性
    • 使用 <router-view> 标签在指定的位置添加通过路径匹配的组件
  • 导航

    • 声明式导航

      • 通过<router-link>组件可以设置点击该标签内容跳转指定路径
        • to属性后跟要跳转的路径 tag可以设置该标签的类型 如li标签 span标签
    • 编程式导航

      • 在方法中调用通过this.$router.push('跳转的路径')
  • 重定向

    • 指定路由的跳转界面
      • 在router.js中配置路径通过redirect属性匹配重定向的地址,/表示进入主页面自动加载的路径,*表示如果没有配置该路径则默认跳转的路径
  • 路由嵌套

    • 在router.js的对象中添加children的属性
      • 添加的嵌套路由和路由配置相同,调用方式也相同,只能在父路由中调用
  • 动态匹配

    • 在编程式导航中,可以在路径中匹配动态参数,传递给路由,在路由中在路径后使用:参数名获取,参数名应该相同
    • 注意,后可跟多个参数
  • 命名路由

    • 在路由中添加name属性,在编程式导航中可通过this.$router.push({name:路由的名字,params:{参数名:值}})
      • 参数没有即不是动态路由
  • 命名视图

    • 在router.js的component属性中添加别名:对应的组件名,在<router-view>标签中可通过属性name指向别名
  • 模式

    • 在router.js的router实例中添加mode属性 默认为hash,可修改为history

    • hash

      • 该模式访问的路径中不含#
      • 切换和切换监听
        • location.hash可以获取当前路径信息
        • window.onhashchange 监听路径的切换
    • history

      • 路径中不含# 但需要后端进行处理

      • 切换和切换监听

        • history.pushState 切换
        • window.onpopstate 监听路径的切换
  • 获取当前路由对象

    • 通过this.$route
    • this.$router获取的是所有对象
  • 路由守卫|拦截

    • 全局守卫

      • 添加方式

        • 在router.js中新增一个方法router.beforeEach((to,from,next) =>{进行一些判断 调用next()放行})
          • to表示要去的路由的对象,from是来的时候的对象,next()放行
    • 局部守卫

      • 添加方式
        • 在vue对象中添加biroteRouteEnter(to,from,next){进行判断}
          • 例子
js
            <script type="text/javascript">
            export default {
            beforeRouteEnter (to, from, next) {
            if(true){
            next();
            }else{
            next("/login");
            }
            },	 
            }
            </script>
  • 生命周期
    • beforeRouteEnter (to, from, next) {
      // 在渲染该组件的对应路由被 confirm 前调用
          // 不!能!获取组件实例 `this`
          // 因为当守卫执行前,组件实例还没被创建
- `beforeRouteUpdate (to, from, next) {`
      // 在当前路由改变,但是该组件被复用时调用
         // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
         // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
         // 可以访问组件实例 `this`
- `beforeRouteLeave (to, from, next) {`
// 导航离开该组件的对应路由时调用
// 可以访问组件实例 `this`

6.6 iconfont

  • 图标的css组件

  • 引入方式

    • 将文件放入public文件夹中,在index页面中引入css文件
    • 将文件放入src/assets文件夹中,在script中使用import中导入css文件
  • 添加方式

    • 在class中添加iconfont 和对应的图标名

6.7 Better-Scroll

  • 概述

    • 主要完成的功能需要包含Better-Scroll实现页面中拖动滚动、拉 动属性等功能
      • https://ustbhuangyi.github.io/better-scroll/doc/zh-han
  • 调用过程

    • 导入betterScroll包
    • 为要实现的拖动的最外层添加一个固定宽度,然后设置一个class名
    • this.$nextTick(()=>{new BetterScroll(‘class名’)})

七、vuex

7.1 概述

  • Vuex是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生
  • vuex组件是独立出来的一个组件,将所有的与状态有关的共享变量放入其中进行管理

7.2 作用

  • 状态共享

  • 数据快照

    • 缓存后端数据,避免重复请求,影响用户体验,主要用于不常改变的数据
      • 在state中的值可以经过判断,如果为空则获取,不为空则从缓存中获取,缓存在内存中
  • 时光旅行

    • 调试

7.3 状态获取方式

  • vuex(store.js)中定义vuex信息,在vue实例中导入vuex的store并引用

    • vuex的属性 state存放状态的对象, mutations存放同步修改状态方法的对象 actions存放异步修改状态方法的对象 getters 对state中的属性进行处理,比如只显示前五个数据

      • mutations可设计为常量写法常量属性方式[常量名]表示获取常量值对应的值 使用常量方式使代码可维护性变强
  • 获取方式

    • 通过this.$store(定义的vuex名).state(存放状态信息的对象名).(状态参数名)

7.4 修改方式

  • 同步

    • 通过this.$store(定义的名).commit(自定义参数名,值)
      • 自定义参数名需与vuex对象的mutations中的名字对应
      • 在mutations的方法中获取两个值,第一个为state的对象,第二个为传递的值
  • 异步

    • 通过this.$store(定义的名).dispatch(自定义参数名,值)
      • 自定义参数名需与vuex对象的actions中的名字对应
      • 在actions中获取的形参为store的对象,修改status值需通过调用mutations中的方法,如store.commit('mutations中的方法名',参数),它不能直接修改state

7.5 调试工具

  • 浏览器vue插件

7.6 计算属性获取状态值

  • 首先在v-show中添加一个计算属性参数名

  • 通过一个计算属性方法中转,仍使用之前方式获取

  • 导入vuex的mapState函数方法,在计算属性对象后:mapState(['参数名'])

    • 导入方式为
  • 导入vuex的mapState函数方法,在计算属性对象{...mapState(['参数名'])}

    • ...表示展开,显示其中全部,可用于合并数组和对象
    • 相当于将查询方法合并到计算属性对象中

7.7 getters

  • 对state中的数据进行处理

  • 创建方式

    • 在getters对象中添加方法,返回所需的state值
  • 调用方式

    • this.$getters.(方法名)
    • 调用方式同state

7.8 注意

  • (1)应用层级的状态应该集中到单个 store 对象中。
  • (2)提交 mutation 是更改状态的唯一方法,并且这个过程是同步的。
  • (3)异步逻辑都应该封装到 action 里

八、组件库

8.1 第三方插件

8.2 使用第三方ui框架

8.3 移动端布局

8.3.1 移动端布局及适配方式

  • dpr与viewport

  • rem等比缩放方案

  • 1px边框问题 (为什么移动端css里面写了1px, 实际看起来比1px粗.)

    在devicePixelRatio = 2 时,输出viewport:
    <meta name="viewport" content="initial‐scale=0.5, maximum‐scale=0.5, mini
    mum‐scale=0.5, user‐scalable=no">
    在devicePixelRatio = 3 时,输出viewport:
    <meta name="viewport" content="initial‐scale=0.3333333333333333, maximumscale=
    0.3333333333333333, minimum‐scale=0.3333333333333333, user‐scalable=n
    o">
    https://www.cnblogs.com/lunarorbitx/p/5287309.html

8.3.2 移动端事件相关

  • click事件300ms延迟 为了检测是否还有双击或捏开

    解决:(1) 设置meta viewport (2) fastclick

  • Zepto.js

    Zepto是一个轻量级的针对现代高级浏览器的JavaScript库, 它与jquery有着类似的api。使用需要注意以下几点:

    • 提供 jQuery 的类似的API,但并不是100%覆盖 jQuery;
    • Zepto不支持旧版本的Internet Explorer浏览器(<10);
    • zepto添加了完整的touch手势支持;解决300ms延时(tap取代click,需要引入zepto.touch.js)
  • Hammer.js

    HammerJS是一个优秀的、轻量级的触屏设备手势库 hammer.js https://github.com/hammerjs/hammer.js vue touch https://github.com/vuejs/vue-touch/tree/next

九、高级应用

9.1 SSR

9.2 Nuxt.js

  • 服务端渲染, 解决首屏加载速度, 和 seo

  • 安装与介绍

    https://zh.nuxtjs.org/guide

    npx create-nuxt-app <项目名> 服务端渲染, 解决首屏加载速度, 和 seo问题

  • Nuxt.js的配置

  • 路由配置

  • 要在页面之间使用路由,我们建议使用<nuxt-link> 标签。 支持activeClass,tag

    • 一级路由

    • 路由由在page文件夹下的组件加载后自动创建

    • 嵌套路由

      • 在pages文件夹下创建与父组件的名字相同的文件夹,并在父组件中添加<nuxt-child>来表示子组件的位置

        pages/
        ‐‐| film/
        ‐‐‐‐‐| nowplaying.vue
        ‐‐‐‐‐| comingsoon.vue
        ‐‐| film.vue
    • 动态路由

      • 创建一个文件夹名字与在需要传值的路径名相同(该路径是用该文件夹表示,页面由动态参数组件展示),在文件夹中创建一个vue名字是以_下划线开头,后面是传递的参数名
      pages/
      ‐‐| detail/
      ‐‐‐‐‐| _id.vue
  • 获取动态路由参数
    asyncData({params}){
    console.log(params.id);
    }
  • 重定向

    • 在nuxt.config.js中添加配置
  • 组件

    • 全局组件
      • 在layouts文件夹下的default.vue中添加
      • 要在页面之间使用路由,我们建议使用<nuxt-link> 标签。 支持activeClass,tag
      • 要在页面之间使用路由,我们建议使用<nuxt-link> 标签。 支持activeClass,tag
  • 导航

    • 要在页面之间使用路由,我们建议使用<nuxt-link> 标签。 支持activeClass,tag
  • 定制模板

    • 在layouts中新增组件(相当于模板),在子组件的export default中添加属性layout:"模板名" //指定模板是谁
    • 所有的组件都加在里面, 但是有些页面 可能不一样,就可以使用 个性化定制页面
  • 视图

    • 在layout 里面 写好default.vue 可以认为这是根组件的模板了, 所有的组件都加在里面, 但是有些页面 可能不一样,就可以使用 个性化定制页面。
  • 异步数据

    • 使异步数据能够被百度爬虫加载到

    • 在asyncData对象中进行异步数据请求

      • 是先在后端渲染,然后在前端渲染
      • 如果在其中进行ajax请求,使用this获取不了当前对象,应对使用ajax请求获取的数据进行返回,并把ajax的方法得到的结果进行返回
      • 其后参数可跟data,为全部对象,也可用{data对象的属性名,拿到该对象}
    • 如果组件的数据不需要异步获取或处理,可以直接返回指定的字面对象作为组件的数据。

      export default {
      data () {
      return { foo: 'bar' }
      }
      }
    • 反向代理的配置 (重启服务器)

      npm i @nuxtjs/proxy ‐D
      在 nuxt.config.js 配置文件中添加对应的模块,并设置代理
      
      modules: [
      '@nuxtjs/axios', //添加axios
      '@nuxtjs/proxy' //添加proxy模块
      ],
      axios: {
      proxy: true
      },
      proxy: {
      '/api': {
      target: 'http://example.com',
      pathRewrite: {
      '^/api' : '/'
      }
      }
      }
  • 反向代理

    • 在nuxt.config.js中配置
    • 通过判断在客户端是代理路径,在服务端是完整路径
  • 操作dom的问题

    • 需在nuxt.config.js中配置,使其在(客户端)浏览器环境下进行渲染,在服务端不能渲染
  • vuex状态树

    • 需要添加 store/index.js 文件,并对外暴露一个 Vuex.Store 新的实例每次访问都要返回一个实例, 防止交叉请求状态污染

      import Vue from 'vue'
      import Vuex from 'vuex'
      
      Vue.use(Vuex)
      
      const store = () => new Vuex.Store({
      
      state: {
      counter: 0
      },
      mutations: {
      increment (state) {
       state.counter++
      }
      }
      })
      
      export default store
    • fetch 方法用于在渲染页面前填充应用的状态树(store)数据,与 asyncData 方法类似,不同的是它不会设置组件的数据。如果页面组件设置了 fetch 方法,它会在组件每次加载前被调用(在服务端或切换至目标路由之前)

      export default {
      async fetch ({ store, params }) {
       let { data } = await axios.get('http://my‐api/stars')
      store.commit('setStars', data)
      }
      }
  • nginx

    • 配置文件nginx.conf
      • location
        • root表示根目录 index表示加载哪个页面, 中间可以用空格隔开添加多个
      • error_page 表示错误页面 404 (中间空格隔开可使页面对应多个错误) 对应的404错误页面
      • alias可以设置别名,使其指向真实路径,alias后跟真实路径,location后为别名
      • location后跟/ajax/表示向ajax发送请求就走里面的代理 请求路径前缀需加/ajax/ 里面添加proxy_pass可添加代理的域名,实现跨域功能
        • 可定义多个,请求路径(/ajax/)不同,访问的也不同

十、项目目录

image-20200908210558796

assets:存放一些静态文件,如图片。 

base:存放基础组件 

base/api:基础api接口 

base/component:基础组件,被各各模块都使用的组件 

base/router:总的路由配置,加载各模块的路由配置文件。 

common:工具类 

component:组件目录,本项目不用。 

mock:存放前端单元测试方法。 

module:存放各业务模块的页面和api方法。 

下级目录以模块名命名,下边以cms举例: 

cms/api:cms模块的api接口 

cms/component:cms模块的组件 

cms/page: cms模块的页面

cms/router:cms模块的路由配置 

statics:存放第三方组件的静态资源 

vuex:存放vuex文件,本项目不使用 

static:与src的平级目录,此目录存放静态资源 

它与assets的区别在于,static目录中的文件不被webpack打包处理,会原样拷贝到dist目录下