Vue学习笔记

前言

前后分离的开发思想主要时基于Soc(关注度分离原则)!

什么是CSS预处理器

​CSS 预处理器定义了一种新的语言,其基本思想是,用一种专门的编程语言,为CSS增加了一些编程的特性,将CSS作为目标生成文件,然后开发者就只要使用这种语言进行CSS的编码工作。转化成通俗易懂的话来说就是 “用一种专门的编程语言,进行Web页面样式设计,再通过编译器转化为正常的CSS文件,以供项目使用” 。

常用的CSS预处理器有哪些:

1、SASS:基于Ruby,通过服务端处理,功能强大。解析效率高。需要学习Ruby语言,上手难度高于LESS。

2、LESS:基于NodeJS,通过客户端处理,使用简单。功能比 SASS简单,解析效率也低于SASS,但在实际开发中足够了,所以我们后台人员,如果需要的话,建议使用LESS。

概念:

Vue : 一款渐进式JavaScript框架,所谓渐进式就是逐步实现新特性的意思,如实现模块化开发、路由、状态管理等新特性。其特点是综合了Angular(模块化)和React(虚拟 DOM)的优点!

Axios :前端通信框架;因为 vue 的边界很明确,就是为了处理DOM,所以并不具备通信能力。此时就需要额外使用一个通信框架与服务器交互;当然也可以直接选择使用jQuery提供的AJAX通信功能!

WebPack:模块打包器,主要作用是打包、压缩、合并及按序加载!

NPM:项目综合管理工具,类似于Maven!

MVVM模式的实现者

  • Model:模型层,在这里表示JavaScript 对象!
  • View:视图层,在这里表示 DOM (HTML操作的元素)!
  • **ViewModel **连接视图和数据的中间件,Vue.js 就是 MVVM中的ViewModel层的实现者在MVVM架构中,是不允许数据和视图直接通信的,只能通过ViewModel来通信,而ViewModel就是定义了一个 Observer观察者!
  • ViewModel 能够观察到数据的变化,并对视图对应的内容进行更新. ViewModel能够监听到视图的变化,并能够通知数据发生改变。至此,我们就明白了,Vue.js 就是一个 MVVM的实现者,他的核心就是实现了DOM监听与数据绑定!

为什么要使用MVVM
MVVM模式和MVC模式一样,主要目的是分离 视图(View) 和模型(Model),有几大好处

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

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

  • 独立开发:开发人员可以专注于业务逻辑和数据的开发(ViewModel),设计人员可以专注于页面设计。

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

  • img

1.Vue基本语法

<template>
  <div>
    {{msg}}
  </div>
</template>

<script>
export default {
  components: {
      
  },
  props: {
      
  },
  data () {
    return {
      msg: "template"
    }
  },
  computed: {
      
  },
  mounted () {

  },
  methods: {

  }
}
</script>

<style   lang="less"   scoped>
</style>

1、v-bind:来绑定元素特性! v-bind:等被称为指令。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

</head>
<body>
<!--view层  模板-->
    <div id="app">
        {{message}}
        <span v-bind:title="message">
            鼠标悬停几秒查看此处动态绑定的提示信息!
        </span>
    </div>

<!-- 1. 导入Vue.js-->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
    <script>
        var vm = new Vue({
            /*el:挂载点,与html中的id属性绑定为#,与class选择器绑定为.  推荐挂在到div标签上*/
            el:"#app",
            // Model : 数据
            data:{
                message:"hello vue"
            }
        });
    </script>
</body>
</html>

1.Vue实例的作用范围是什么呢?
Vue会管理el选项命中的元素及其内部的后代元素

2.是否可以使用其他的选择器?
可以使用其他的选择器,但是建议使用ID选择器

3.是否可以设置其他的dom元素呢?
可以使用其他的双标签,不能使用HTML和BODY

2、v-if,v-else

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div id="app">
        <h1 v-if="type === 'A'">A</h1>
        <h1 v-else-if="type === 'B'">B</h1>
        <h1 v-else>C</h1>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
    <script>
        var vm = new Vue({
            el:"#app",
            data:{
                ok: true,
                type: 'B'
            }
        });
    </script>
</body>
</html>

3、v-for : 指令可以绑定数组的数据来渲染一个项目列表

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<!--view层  模板-->
<div id="app">
    <li v-for="item in items">
        <!--item相当于foreach中的每一项 , items是下边定义的数组-->
        {{item.message}}
    </li>
</div>

<!-- 1. 导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
    var vm = new Vue({
        /*el为元素的意思*/
        el:"#app",
        // Model : 数据
        // {}是对象,[]是数组
        data: {
            items: [
                {message: '学java'},
                {message: '学前端'}
            ]
        }
    });
</script>
</body>
</html>

2. Vue绑定事件

1、v-on 指令添加一个事件监听器

<button v-on:click="sayHi">click me</button>
<button @click="sayHi">click me</button>

<button v-on:monseenter="sayHi">click</button>

<!--  v-on:事件 = "事件方法名"  -->
<!--想知道都有什么事件,去查jQuery文档,click为鼠标单击事件!-->
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<div id="app">
  <!--想知道都有什么事件,去查jQuery文档,click为鼠标单击事件!-->
  <button v-on:click="sayHi">click me</button>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
  var vm = new Vue({
    el:"#app",
    data: {
      message: "学JAVA!"
    },
    methods: {
      // 方法必须定义在vue的methods对象中
      // 所有的都是键值对形式
      sayHi : function () {
        alert(this.message);
      }
    }
  });
</script>
</body>
</html>

V-bind 缩写

<!-- 完整语法 -->
<a v-bind:href="url">...</a>

<!-- 缩写 -->
<a :href="url">...</a>

<!-- 动态参数的缩写 (2.6.0+) -->
<a :[key]="url"> ... </a>

v-on缩写 @

<!-- 完整语法 -->
<a v-on:click="doSomething">...</a>

<!-- 缩写 -->
<a @click="doSomething">...</a>

<!-- 动态参数的缩写 (2.6.0+) -->
<a @[event]="doSomething"> ... </a>

在这里插入图片描述

3.Vue双向绑定

在表单中使用双向数据绑定:

​ 你可以用 v-model 指令在表单 , 及 元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊理。

注意: v-model 会忽略所有表单元素的 value、checked、selected 特性的初始值而总是将Vue实例的数据作为数据来源。你应该通过JavaScript在组件的data选项中声明初始值!

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<div id="app">
  性别:
  <input type="radio" name="sex" value="" v-model="message"><input type="radio" name="sex" value=""  v-model="message"><p>
    选中了谁:{{message}}
  </p>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
  var vm = new Vue({
    el:"#app",
    data: {
      message: ''
    }

  });
</script>
</body>
</html>

4.Vue第一个组件

组件就是自定义标签!({}表示对象 []表示数组 ()表示函数)

  • vue.component():注册组件,第一个参数是组件的名字,第二个参数是组件的对象,对象里有两个东西,第一个是props可以接收参数,第二个是template模板。
  • my-component-li:自定义组件的名字。
  • template:组件的模板。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<div id="app">
    <!--组件:传递给组件中的值,ports来接收-->
    <yst v-for="item in items" v-bind:qin="item"></yst>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
    //定义一个vue组件component,组件名叫yst,template为模板,props用来接收参数!
    Vue.component("yst",{
        props: ['qin'], // 不用ports无法接受外边的参数
        template: '<li>{{qin}}</li>'
    });

    var vm = new Vue({
        el:"#app",
        data:{
            items:["java","linux","Sql"]
        }
    });
</script>
</body>
</html>

5.Axios异步通信(难点)

什么是Axios

​ Axios是一个开源的可以用在浏览器端和Node]s 的异步通信框架,她的主要作用就是实现 AJAX异步通信,其功能特点如下:

  • 从浏览器中创建XMLHttpRequests
  • 从node.js 创建http请求
  • 支持 Promise API [ JS中链式编程 ]
  • 拦截请求和响应
  • 转换请求数据和响应数据
  • 取消请求
  • 自动转换JSON数据
  • 客户端支持防御XSRF(跨站请求伪造)
  • GitHub: https://github.com/axios/axios
  • 中文文档: http://www.axios-js.com/

第一个Axios应用程序

​ 咱们开发的接口大部分都是采用 JSON 格式,可以先在项目里模拟一段 JSON 数据,数据内容如下:

​ 创建一个名为data.json 的文件并填入上面的内容,放在项目的根目录下!

{
  "name": "dell",
  "version": "1.0.0",
  "url": "www.baidu.com",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": ["001", "002", "003"],
  "author": "YST",
  "license": "ISC"
}
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>

  <!--解决闪烁问题 没拿到数据之前不显示-->
  <style>
    [v-cloak]{
      display: none;
    }
  </style>

</head>
<body>

<div id="app" v-cloak>
  <div>{{info.name}}</div>
  <a v-bind:href="info.url">点我</a>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
  var vm = new Vue({
    el:"#app",
    // 注意:data()函数 与 data{}对象不一样
    data(){
      return{
        //  请求返回参数格式,必须和json字符串一样
        info:{
          // 可以不写,但不能写错
          name: null,
          version: null,
          url: null
        }
      }
    },
    mounted(){
        // mounted() 钩子函数,就是页面渲染完成后需要执行的函数,在这个时候传数据最合适.
        axios.get('../data.json').then(response=>(this.info = response.data));
        // --链式编程 直接.什么.什么    箭头函数
    }

  });
</script>
</body>
</html>

渲染完成后的文本有两种方式:

渲染普通文本有2种方式:{{}}与v-text

​ 但是,需要注意的是,在使用{{}}展示或更新页面数据时:当网速比较慢时,会出现一个不好的过度现象,会让用户先看到我们的表达式(上面页面中的{{msg}}),然后才看到data中的值(欢迎Vue!)------->即所谓的闪烁问题!

解决:1、v-cloak指令,然后为其设置css样式display:none; 2、使用v-text

注意:

1、{{}}与v-text的区别

  • 默认v-text是没有闪烁问题,{{}}存在闪烁的问题。
  • v-text会覆盖掉元素中原本的内容,但是{{}}只会替换自己的这个占位符。

2、{{}}、v-text与v-html的区别

  • 前两个向页面渲染普通文本,后者向页面输出html。
  • v-html指令的作用是:设置元素的innerHTML,内容中有html结构会被解析为标签
    v-text指令无论内容是什么,只会解析为文本
  • 与v-text一样,v-html也会覆盖掉元素中原本的内容。

Vue生命周期

​ Vue实例有一个完整的生命周期,也就是从开始创建、初始化数据、编译模板、挂载DOM、渲染→更新→渲染、卸载等一系列过程。通俗说就是Vue 实例从创建到销毁的过程,就是生命周期。

​ 在Vue 的整个生命周期中,它提供了一系列的事件,可以让我们在事件触发时注册 JS 方法,可以让我们用自己注册的 JS 方法控制整个大局,在这些事件响应方法中的this直接指向的是 Vue 的实例。

img

6.计算属性

计算属性:计算出来的结果,保存在属性中。它是在内存中运行∶虚拟Dom!

​ 计算属性的重点突出在属性两个字上(属性是名词),首先它是个属性其次这个属性有计算的能力(计算是动词),这里的计算就是个函数;简单点说,它就是一个能够将计算结果缓存起来的属性(将行为转化成了静态的属性),仅此而已;可以想象为缓存!

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<div id="app" >
    <p>curentTime1 {{curentTime1()}}</p>
    <p>curentTime2 {{curentTime2}}</p>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
  var vm = new Vue({
    el:"#app",
    data:{
      message: "hello"
    },
    methods: {
      curentTime1: function (){
        return Date.now();  // 返回一个当前时间戳
      }
    },
    computed:{  // 计算属性  methods,computed中的方法名不能重名,重名后methods方法的优先级高!!
      curentTime2: function (){
        //类似mybatis缓存,第一次计算存到结果里边,一旦有增删改后立马缓存失效重新计算。
        this.message;
        return Date.now();  // 返回一个当前时间戳
      }
    }
  });
</script>
</body>
</html>

methods:定义方法,调用方法使用currentTime1(),需要带括号!
computed:定义计算属性,调用属性使用currentTime2,不需要带括号;this.message是为了能够让currentTime2观察到数据变化而变化!
​ 如果在方法中的值发生了变化,则缓存就会刷新!可以在控制台使用vm.message=“qinjiang” ,改变下数据的值,再次测试观察效果!

在这里插入图片描述

结论:

​ 调用方法时,每次都需要进行计算,既然有计算过N则必定产生系统开销,那如果这个结果是不经常变化的呢?此时就可以考虑将这个结果缓存起来,采用计算属性可以很方便的做到这一点,计算属性的主要特性就是为了将不经常变化的计算结果进行缓存,以节约我们的系统开销。

7.插槽slot

​ 在 vue.js中我们使用 元素作为承载分发内容的出口,作者称其为插槽,可以应用在 组合组件的场景中。

​ 在Vue中,我们使用组件来组织页面和组织代码,类似于搭积木,每一个组件都是一个积木,使用一些相同或者不同组件就能搭建出我们想要的页面。slot(插槽)是组件功能的重要组成部分,插槽必须用于组件才有意义。它为组件提供了对外的接口,允许从组件外部传递内容,并将这部分内容放置到指定的位置。

​ 当一个组件可能被使用至少两次并且两次使用内容(这里指组件视图的组成)不同时,插槽才有存在的必要。

​ 一个不带 name<slot> 出口会带有隐含的名字“default”。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<div id="app" >
  <todo>
    <todo-title slot="todo-title" v-bind:title="title"></todo-title>
    <todo-items slot="todo-items" v-for="item in todoItems" v-bind:item="item"></todo-items>
  </todo>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>

<script>
  //定义一个vue组件component,组件名叫yst,{}中为方法体。template为模板,props用来接收参数!
  Vue.component("todo",{
    template:
    '<div>\
         <slot name="todo-title"></slot>\
           <ul>\
             <slot name="todo-items"></slot>\
           </ul>\
    </div>'
  });

  Vue.component("todo-title",{
    props: ['title'],
    template: '<div>{{title}}</div>'
  });

  Vue.component("todo-items",{
    props: ['item'],
    template: '<li>{{item}}</li>'
  });

  var vm = new Vue({
    el:"#app",
    data:{
      title: "学习列表",
      todoItems: ['学java','学vue','学linux']
    }
  });
</script>
</body>
</html>

8.自定义事件内容分发

JavaScript如何删除指定元素

在这里插入图片描述

组件内部绑定事件需要使用到this.$emit(“事件名”,参数);

this.$emit() 作用:子组件向父组件传值

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<div id="app" >
  <todo>
    <todo-title slot="todo-title" v-bind:title="title"></todo-title>
    <todo-items slot="todo-items" v-for="(item,index) in todoItems"
                v-bind:item="item" v-bind:index="index" v-on:remove="removeItems(index)"></todo-items>
  </todo>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
  //定义一个vue组件component,组件名叫yst,{}中为方法体。template为模板,props用来接收参数!
  Vue.component("todo",{
    template:
    '<div>\
         <slot name="todo-title"></slot>\
           <ul>\
             <slot name="todo-items"></slot>\
           </ul>\
    </div>'
  });

  Vue.component("todo-title",{
    props: ['title'],
    template: '<div>{{title}}</div>'
  });

  Vue.component("todo-items",{
    props: ['item','index'],
    // 只能绑定当前组件的方法!
    template: '<li>{{index}}---{{item}}<button @click="remove">删除</button></li> ',
    methods:{
      remove: function (index){
        //  this.$emit() 自定义事件分发
        this.$emit('remove', index);
      }
    }
  });

  var vm = new Vue({
    el:"#app",
    data:{
      title: "学习列表",
      todoItems: ['学java','学vue','学linux']
    },
    methods:{
      removeItems: function (index) {
        console.log("删除了" + this.todoItems[index] + "OK");
        // this指vue对象
        this.todoItems.splice(index, 1);  // 一次删除一个元素!
      }
    }
  });
</script>
</body>
</html>

在这里插入图片描述

说明:

​ Vue的开发都是要基于NodeJS,实际开发采用vue-cli脚手架开发,vue-router路由,vuex做状态管理;Vue UI,界面我们一般使用ElementUI(饿了么出品),或者ICE(阿里巴巴出品!)来快速搭建前端项目~

9.第一个vue-cli项目

什么是vue-cli

​ vue-cli官方提供的一个脚手架,用于快速生成一个vue的项目模板。

​ 预先定义好的目录结构及基础代码,就好比咱们在创建Maven项目时可以选择创建一个骨架项目,这个骨架项目就是脚手架,我们的开发更加的快速。

主要的功能:

  • 统一的目录结构
  • 本地调试
  • 热部署
  • 单元测试
  • 集成打包上线

步骤:

  • 1、安装node.js

  • 2、安装vue-cli

  • 3、创建一个vue程序, 命令行:vue init webpack 项目名

  • Project name:项目名称,默认回车即可

    Project description:项目描述,默认回车即可

    Author:项目作者,默认回车即可

    lnstall vue-router:是否安装vue-router,选择n不安装(后期需要再手动添加)

    Use ESLint to lint your code:是否使用ESLint做代码检查,选择n 不安装(后期需要再手动添加)

    Set up unit tests:单元测试相关,选择n不安装(后期需要再手动添加)

    Setup e2e tests with Nightwatch:单元测试相关,选择n不安装(后期需要再手动添加)

    Should we run npm install for you after the project has been created:创建完成后直接初始化,选择n,我们手动执行;

  • 进入创建的vue项目,输入命令:npm install 会

创建方法2:管理员进入命令行,进入目标目录,输入指令:vue create 项目名 ,创建一个vue项目!!!

在这里插入图片描述

注意:

dev是vue-cli2版本的命令,它有它自己的config文件夹,build文件夹

serve是vue-cli3版本的命令,它不需要config,build文件夹,而是以vue.config.js配置文件的形式代替。

因此,如果你创建的是vue-cli3版本的Vue项目,想用dev命令,会涉及到很多的插件不兼容,以及这些配置文件缺失的情况,是个旋涡坑…,既然创建了3版本就用serve即可…。

Vue目录结构!!

1、node_modules文件夹: 这个文件夹里面全部都是node的一些基础的依赖包,当我们拓展的安装一些别的插件时 也会装在这个文件夹里。
2、public文件夹: phpstudy 的 www 目录服务器的静态资源目录。
3、src 文件夹:用来开发的文件夹。
4、assets 文件夹:里面主要放置一些资源文件。比如js 、css 之类的文件。
5、components 文件夹:她可以说是vue 的 灵魂了 , 组件文件全部都可以放到这里面。一个vue项目就是由一个个的组件拼装起来的。
6、router 文件夹 及 子目录:这个文件夹里的是整个vue项目的路由,vue 是单页面应用的代表,这里面就是设置一个一个组件的地址的文件。
7、app.vue 文件 :这个文件是整个项目的入口文件,相当于包裹整个页面的最外层的div。
8、main.js 文件 :这个文件是项目的主js,全局的使用的各种变量、js、插件 都在这里引入 、定义。
9、packpage.json :包管理文件。
10、readme.md :项目使用说明书。

10.webpack学习使用

CommonsJS

​ 服务器端的NodeJS遵循CommonsJS规范,该规范核心思想是允许模块通过require方法来同步加载所需依赖的其它模块,然后通过exports或 module.exports来导出需要暴露的接口。

ES6模块

​ EcmaScript6标准增加了JavaScript语言层面的模块体系定义(但是现在网页还在ES5规范)。ES6模块的设计思想,是尽量静态化,使编译时就能确定模块的依赖关系,以及输入和输出的变量。也可以有编译时异常,比如在js中使用’use strict’就会编译时检查错误。CommonsJS和AMD模块,都只能在运行时确定这些东西。

import "jquery";			// 导入
export function dostuff() {}	//暴露
module "localModule" {}		//模块

WebPack

​ WebPack是一款模块加载器兼打包工具,它能把各种资源,如JS、JSX、ES6、SASS、LESS、图片等都作为模块来处理和使用。

​ 作用:把ES6规范的代码打包编译成ES5规范,也就是所有浏览器都能够运行的!!!

​ 安装:

​ npm install webpack -g
​ npm install webpack-cli -g

​ 测试安装成功:

​ webpack -v
​ webpack-cli -v

​ 配置:(了解就行!)

​ 创建webpack.config.js 配置文件!

​ entry: 入口文件,指定WebPack用哪个文件作为项目的入口.

​ output:输出,指定 WebPack 把处理完成的文件放置到指定路径.

​ module:模块,用于处理各种类型的文件

​ plugins:插件,如:热更新、代码重用等. resolve:设置路径指向

​ watch:监听,用于设置文件改动后直接打包

11.ES6 语法

打包!!!

// hello.js
// 暴露一个方法
exports.sayHi = function (){
    document.write("<h1>学ES6!</h1>")
}
exports.sayHi2 = function (){
    document.write("<h1>学ES6!</h1>")
}
exports.sayHi3 = function (){
    document.write("<h1>学ES6!</h1>")
}

// main.js
var hello = require("./hello"); //相当于new了一个类!
hello.sayHi();
// webpack.config.js
module.exports = {
    entry: './module/main.js',
    output: {
        filename: "./js/bundle.js"
    }
}

①、es6语法详解:模块化

​ 什么是模块化:模块化就是把代码进行拆分,方便重复利用。类似Java中的导包,要使用一个包,必须先导包。Js中没有包的概念,换来的就是模块。

​ 模块的功能主要有两个命令构成:export 和 import

  • export命令用于规定模块的对外接口,export不仅可以导出对象,一切js变量都可以导出。比如:基本类型变量、函数、数组、对象
  • import命令用于导入其他模块提供的功能!

②、let声明变量

1、var声明的变量往往会越域;let声明的变量有严格局部作用域。

    {
      var a = 1;
      let b = 2;
    }
    console.log(a)  // 1
    console.log(b)  // Uncaught ReferenceError: b is not defined

2、var 可以声明多次;let只能声明一次

    var m = 1;
    var m = 2;
    let n = 1;
    let n = 2;
    console.log(m) //2
    console.log(n) //Uncaught SyntaxError: Identifier 'n' has already been declared

3、var会变量提升;let不存在变量提升

    console.log(x);
    var x = 10; // undefined
    console.log(y);
    let y = 12; // Uncaught ReferenceError: Cannot access 'y' before initialization

注意:以后要习惯使用let声明变量

③、const声明变量 相当于声明了一个常量

1、声明之后不允许改变

    const a = 1;
    console.log(a) //1
    a = 2;
    console.log(a) // Uncaught TypeError: Assignment to constant variable.

2、一旦声明必须初始化,否则会报错

  const a;
  a = 1; 
  console.log(a) //	Uncaught SyntaxError: Missing initializer in const declaration

④、解构表达式

1、数组解构

 let arr = [1, 2, 3];
 let [a, b, c] = arr;
 console.log(a, b, c) //1,2,3

2、对象解构

    const person = {
      name: "qiyue",
      age: 23,
      language: ['java', 'js', 'css']
    }
    const { name, age, language } = person 
    console.log(name, age, language) //qiyue 23 (3) ["java", "js", "css"]
    const person = {
      name: "qiyue",
      age: 23,
      language: ['java', 'js', 'css']
    }
    //从person里解析出name的值在赋值给abc
    const { name:abc, age, language } = person
    console.log(abc, age, language) //qiyue 23 (3) ["java", "js", "css"]

⑤、字符串扩展

    let str = "hello.vue";
    console.log(str.startsWith("hello")) //true
    console.log(str.endsWith("vue")) //true
    console.log(str.includes("e")) //true
    console.log(str.includes("hello")) //true

⑥、字符串模板

let str = `<span>hello world</span>`
console.log(str) // <span>hello world</span>

⑦、字符串插入变量和表达式

let info = `我是${abc},今年${age}`
console.log(info) //我是qiyue,今年23
function fun() {
    return "这是一个函数";
}
let info = `我是${abc},今年${age + 10},我想说:${fun()}`
console.log(info) //我是qiyue,今年33,我想说:这是一个函数

⑧、函数优化

1、函数默认值:直接给参数写上默认值,没传就会自动使用默认值

function add(a, b = 1) {
   return a + b;
}
console.log(add(10)) //11

2、不定参数:不定参数用了表示不确定的参数个数,形如…变量名,由…加上要给具名参数标识符组成。具名参数只能放在参数列表的最后,并且有且只有一个不定参数

 function fun(...params) {
      console.log(params.length)
    }
fun(1, 2) // 2
fun(1, 2, 3, 4) //4

3、箭头函数

//以前
var sum = function (a, b) {
      c = a + b
      return c
    }
console.log(sum(2, 3)) // 5

//箭头函数
var sum2 = (a, b) => a + b;
console.log(sum2(2, 4)) // 6

箭头函数的简写
(1)当形参只有一个时候,可以省略小括号!
let fun = a => {}

(2)当大括号内只有一句话的时候,大括号可以省略,而且语句执行结果就是函数的返回值!
let fun = a => a+b

(3)箭头函数适合与this无关的回调,如定时器,数组方法的回调。不适合与this有关的回调,如事件回调,对象方法!

4、箭头函数结合解构表达式

//以前
function hello(person) {
    console.log("hello" + person.name)
}
hello(person); //helloqiyue

//箭头函数
let hello2 = params => console.log("hello" + person.name)
hello2(person) //helloqiyue

//箭头函数加解构表达式
var hello3 = ({ name }) => console.log("hello" + name)
hello3(person) //helloqiyue

⑨、对象优化

1、es6给Object扩展了许多新的方法,如

  • key(obj):获取对象的所有key形成的数组
  • value(obj):获取对象的所有value形成的数组
  • entries(obj):获取对象所有的key和value形成的二维数组
const person = {
    name: "qiyue",
    age: 23,
    language: ["java", "js", "css"]
}
console.log(Object.keys(person)) //["name","age","language"]
console.log(Object.values(person)) // ["qiyue",23,Array(3)]
console.log(Object.entries(person)) //[Array(2),Array(2),Array(2)]

2、Object.assign方法的第一个参数是目标对象,后面的参数都是源对象;将源对象的属性赋值到目标对象中

    onst target = { a: 1 }
    const source1 = { b: 2 }
    const source2 = { c: 3 }
    Object.assign(target, source1, source2);
    console.log(target) //{a: 1, b: 2, c: 3}

3、 声明对象简写

    //以前
    const name = 'sanyue'
    const age = 21
    //将属性值name,age分别赋给person1对象的name,age,后面是属性值
    const person1 = { name: name, age: age }
    console.log(person1) //{name: "sanyue", age: 21}

    //es6:属性名和属性值变量名一样,可以省略
    const person2 = {name,age}
    console.log(person2) //{name: "sanyue", age: 21}

4、对象的函数属性简写

 let person3 = {
      name: "qiyue",
      //以前
      eat: function (food) {
        console.log(this.name + "在吃" + food);
      },
      //箭头函数中this不能使用,用对象.属性
      eat2: food => console.log(person3.name + "在吃" + food),
      eat3(food) {
        console.log(this.name + "在吃" + food)
      }
    }
    person3.eat("苹果") //qiyue在吃苹果
    person3.eat2("香蕉") // qiyue在吃香蕉
    person3.eat3("西瓜") //qiyue在吃西瓜

5、对象的扩展运算符

扩展运算符(…)用于取出参数对象所有可遍历属性然后拷贝到当前对象

    //拷贝对象(深拷贝)
    let p1 = { name: "qiyue", age: 23 }
    let obj = { ...p1 }
    console.log(obj)//{name: "qiyue", age: 23}

    //合并对象
    let age1 = { age: 24 }
    let name1 = { name: "qiyue" }
    let p2 = {}
    p2 = { ...age1, ...name1 }
    console.log(p2) //{age: 24, name: "qiyue"}
    //如果p2中原本有name,age属性会被覆盖

⑩、es6语法详解:map和reduce方法

1、map():接收一个函数,将原数组中的所有元素用这个函数处理后放入新数组返回

let arr = ["1", "3", "4", "23"]
arr = arr.map(item => item * 2)
console.log(arr) //[2, 6, 8, 46]

2、reduce():为数组中的每一个元素依次执行回调函数,不包括数组中被删除或未被赋值的元素

语法:arr.reduce(callbace,[initialValue])

callback(执行数组中每个值的函数,包含四个参数)

  • previousValue(上一次调用回调返回的值,或者是提供的初始值(initialValue))
  • currentValue(数组中当前被处理的元素)、
  • index(当前元素在数组中的索引)
  • array(调用reduce的数组)

initialValue(作为第一次调用callback的第一个参数)

let arr1 = [2, 40, -10, 6]
let result = arr1.reduce((a, b) => {
    return a + b
}, 10)
console.log(result)//48

12.Vue-router

Vue Router是 Vue.js 官方的路由管理器。它和Vue.js 的核心深度集成,让构建单页面应用变得易如反掌。相当于管理跳转路径。

热部署:就是你修改代码,页面不用刷新直接改变!

// router文件夹中的index.js是路由主配置文件
import Vue from 'vue'
import VueRouter from 'vue-router'
import HomeView from '../views/HomeView.vue'

//安装路由
Vue.use(VueRouter)

const routes = [
  {
    // 路由路径
    path: '/',
    name: 'home',
    // 跳转的组件
    component: HomeView
  },
  {
    path: '/about',
    name: 'about',
    // route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.
    component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')
  }
]

const router = new VueRouter({
  routes
})

// 导出路由
export default router
<!--router-link相当于a标签, to相当于hrf-->
<router-link to="/">Home</router-link> 

13.Element - UI

element-ui的安装!

普通安装:

​ element-ui是款热门的vue前端UI框架,官方文档为:https://element.eleme.io/#/zh-CN。要安装element-ui,只需要在vue项目根目录中执行:

npm i element-ui -S

搬运组件:

​ https://element.eleme.cn/#/zh-CN/component/installation

14.路由嵌套

​ 嵌套路由又称子路由,在实际应用中,通常由多层嵌套的组件组合而成。同样地,URL中各段动态路径也按某种结构对应嵌套的各层组件。

import VueRouter from 'vue-router'
import Vue from 'vue'
//使用插件
Vue.use(VueRouter)

//导入组件
import Home from '../pages/Home.vue'
import News from '../pages/News.vue'
import Sports from '../pages/Sports.vue'

import SportsUSA from '../pages/SportsUSA.vue'
import SportsCha from '../pages/SportsCha.vue'
import SportsHome from '../pages/SportsHome.vue'

//创建路由规则
const router = new VueRouter({
    routes: [
        {
            path: '/home',
            component: Home
        },
        {
            path: '/news',
            component: News
        },
        {
            path: '/sport',
            component: Sports,
            //体育下的二级路由
            children: [
                {
                    path: '/china',
                    component: SportsCha
                },
                {
                    path: '/usa',
                    component: SportsUSA
                },
                {
                    path: '/homes',
                    component: SportsHome
                },
            ]
        }
    ]
})

//导出
export default router

15.参数传递及重定向

Vue路由跳转的四种方式

  • router-link 例如:

    三部:①前端传 ②中间router/index.js去接收 ③用户展示

    // 1、不带参数!!!!!
    <router-link :to="{name:'aa'}">
    <router-link :to="{path:'/bb'}"> //name,path都行, 建议用name
    // 注意:router-link中链接如果是'/'开始就是从根路由开始,比如当前此时的路由是xxx/aa,:to="/bb",点击后路径就是xxx/bb
    // 如果开始不带'/',则从当前路由开始。比如当前此时的路由是xxx/aa,:to="bb",点击后路径就是xxx/aa/bb
    
    // 1、带参数!!!!!
    <router-link :to="{name:'aa', params: {id:1}}">
    // name地址,params传参数 (类似post)
    // 路由配置 path: "/aa/:id" 或者 path: "/aa:id"
    // 不配置path ,第一次可请求,刷新页面id会消失
    // 配置path,刷新页面id会保留
     
    // html 取参 $route.params.id
    // script 取参 this.$route.params.id
        
    <router-link :to="{name:'aa', query: {id:1}}">
    // query传参数 (类似get,url后面会显示参数)
    // 路由可不配置
     
    // html 取参 $route.query.id
    // script 取参 this.$route.query.id
    
    // 2、接受参数
    children: [
        {path: '/user/profile/:id' ,component: UserProfile},
        {path: "/user/list" ,component : UserList},
    ]
    
    // 3、在profile.vue、list.vue中可以取到
    
    
  • this.$router.push() 函数里面调用

  • this.$router.replace() 函数里面调用

  • this.router.go(n) 向前或者向后跳转n个页面,n可为正整数或负整数

重定向:

 
const routes = [
  //重定向操作
  {
      path:'/',
      redirect:'/login'	  //重定向操作
  },
  {
      path:'/login',
      component: Login
  }
]

16.404和路由钩子

路由模式有两种:

hash:路径带#符号,如http://localhost/#/login (默认)

history:路径不带#符号,如http://localhost/login

export default new Router ({
    mode: 'history',
    routes: [
    ]
});

处理404页面:

// 创建一个404页面 NotFound.vue --> 配置路由
import NotFound from '../views/NotFound'
{
    path :'*',	// *代表所有路由,如果其他都没有访问到则访问这个
    component: NotFound
}

Vue路由钩子 、 异步请求:

路由钩子分为三种

  • 全局钩子: beforeEach、 afterEach、beforeResolve
  • 单个路由里面的钩子: beforeEnter
  • 组件路由:beforeRouteEnter(在进入路由前执行)、 beforeRouteUpdate、 beforeRouteLeave(在离开路由前执行)

全局钩子

  • beforeEach :全局前置守卫 进入路由之前
  • beforeResolve :全局解析守卫(2.5.0+) 在beforeRouteEnter调用之后调用
  • afterEach :全局后置钩子 进入路由之后

路由的三个参数

  • to: 将要进入的路由对象
  • from: 将要离开的路由对象
  • next: 这个参数是个函数,且必须调用,否则不能进入路由(页面空白)
    • next() 跳入下一个页面
    • next(‘/path’) 改变路由的跳转方向,使其跳到另一个路由
    • next(false) 返回原来的页面
    • next((vm)=>{}) 仅在 beforeRouteEnter 中可用,vm是组件实例
// main.js 入口文件
import router from './router'; // 引入路由
router.beforeEach((to, from, next) => { 
    next();
});
router.beforeResolve((to, from, next) => {
    next();
});
router.afterEach((to, from) => {
    console.log('afterEach 全局后置钩子');
});

为某些路由单独配置守卫

const router = new VueRouter({
 routes: [
   {
      path: '/test',
      component: Test,
      beforeEnter: (to, from, next) => { 
      // 参数用法与全局的钩子都一样,调用顺序在全局前置守卫后面,所以不会被全局守卫覆盖
    }
   }
 ]
})

触发钩子的顺序

将路由导航、keep-alive、和组件生命周期钩子结合起来的,触发顺序,假设是从a组件离开,第一次进入b组件:

  • beforeRouteLeave:路由组件的组件离开路由前钩子,可取消路由离开。
  • beforeEach: 路由全局前置守卫,可用于登录验证、全局路由loading等。
  • beforeEnter: 路由独享守卫。
  • beforeRouteEnter: 路由组件的组件进入路由前钩子。
  • beforeResolve: 路由全局解析守卫。
  • afterEach: 路由全局后置钩子。
  • beforeCreate: 组件生命周期,不能访问this。
  • created: 组件生命周期,可以访问this,不能访问dom。
  • beforeMount: 组件生命周期。
  • deactivated: 离开缓存组件a,或者触发a的beforeDestroy和destroyed组件销毁钩子。
  • mounted: 访问/操作dom。
  • activated: 进入缓存组件,进入a的嵌套子组件(如果有的话)。
  • 执行beforeRouteEnter回调函数next。

17.JS中async与await详解

1、async

​ 带async关键字的函数,是声明异步函数,返回值是promise对象,如果async关键字函数返回的不是promise,会自动用Promise.resolve()包装。

async function test() {
    return 'test'
}
test();
//返回值为 Promise {<resolved>: "test"}

2、await

await等待右侧表达式的结果,这个结果是promise对象或者其他值。

如果它等到的不是一个 promise 对象,那 await 表达式的运算结果就是它等到的东西。

如果它等到的是一个 promise 对象,await 就忙起来了,它会阻塞后面的代码,等着 promise 对象 resolve,然后得到 resolve 的值,作为 await 表达式的运算结果。

function test() {
    return new Promise(resolve => {
        setTimeout(() => resolve("test"), 2000);
    });
}
 
const result = await test();
console.log(result);
console.log('end');
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值