Vue从入门到精通课程超详细

Vue2.0

1.认识Vue

1.创始人以及发展历程

Vue从入门到精通课程超详细_第1张图片

尤雨溪 (EvanYou)

美籍华人

Vue Technology LLC 创始人

高中:上海复旦大学附中

大学:纽约科尔盖特大学

发展历程

1.2014 年 2 月

尤雨溪开源了一个前端开发库 Vue.js。Vue.js 是构建 Web 界面的 JavaScript 库,也是一个通过简洁的 API 提供高效数据绑定和灵活组件的系统。

2.2016 年 9 月

在南京的 JSConf 上,尤雨溪正式宣布以技术顾问的身份加盟阿里巴巴 Weex 团队,来做 Vue 和 Weex 的 JavaScript runtime 整合,目标是让大家能用 Vue 的语法跨三端。

2020 年 4 月

Vue3.0beta版本测试发布。

2. Vue是什么?

Vue.js是一款轻量级的、以数据驱动的、前端JS框架,是一个通过简洁的API提供高效的数据绑定和灵活的组件系统

3.与Jquery的技术比较优势在哪里

旧:Jquery

操作DOM元素

jQuery是使用选择器($)选取DOM对象,对其进行赋值、取值、事件绑定等操作,其实和原生的HTML的区别只在于可以更方便的选取和操作DOM对象,而数据和界面是在一起的

复杂页面维护成本大

jquery则需要获取dom元素节点,并对dom进行添加一个标签的操作,如果dom结构特别复杂,或者添加的元素非常复杂,则代码会变得非常复杂且阅读性低。

很难达到组件化页面

JQuery 时代的代码大部分情况下是面条代码,耦合严重

性能损耗

损耗浏览器资源

新:Vue.js

数据与视图分离

Vue则是通过Vue对象将数据和View完全分离开来了。对数据进行操作不再需要引用相应的DOM对象,可以说数据和View是分离的,他们通过Vue对象这个vm实现相互的绑定。这就是传说中的MVVM。

数据双向绑定

这也就是vue.js最大的优点,通过MVVM思想实现数据的双向绑定,让开发者不用再操作dom对象,有更多的时间去思考业务逻辑。

灵活的组件化

Vue.js通过组件,把一个单页应用中的各种模块拆分到一个一个单独的组件中,我们只要先在父级应用中写好各种组件标签,并且在组件标签中写好要传入组件的参数,然后再分别写好各种组件的实现,然后整个应用就算做完了。

虚拟DOM,运行更快

Virtual DOM,是一种可以预先通过JavaScript进行各种计算,把最终的DOM操作计算出来并优化,由于这个DOM操作属于预处理操作,并没有真实的操作DOM,所以叫做虚拟DOM

4.技术点整理

Vue从入门到精通课程超详细_第2张图片

5.学习需要掌握的知识点

轻量级的框架

能够自动追踪依赖的模板表达式和计算属性,提供 MVVM 数据绑定和一个可组合的组件系统,具有简单、灵活的 API,使读者更加容易理解,能够更快上手。

双向数据绑定

声明式渲染是数据双向绑定的主要体现,同样也是 Vue.js 的核心,它允许采用简洁的模板语法将数据声明式渲染整合进 DOM。

客户端路由

Vue-router 是 Vue.js 官方的路由插件,与 Vue.js 深度集成,用于构建单页面应用。Vue 单页面应用是基于路由和组件的,路由用于设定访问路径,并将路径和组件映射起来

指令

Vue.js 与页面进行交互,主要就是通过内置指令来完成的,指令的作用是当其表达式的值改变时相应地将某些行为应用到 DOM 上。

组件化

可随时引用,通过传入参数实现不同的页面,可子父引用。

状态管理

状态管理实际就是一个单向的数据流,State 驱动 View 的渲染,而用户对 View 进行操作产生 Action,使 State 产生变化,从而使 View 重新渲染,形成一个单独的组件。

2. 搭建Vue2.0项目

1. npm、cnpm node环境搭建vue脚手架

1. 安装node.js环境

1.进入官网

https://nodejs.org/en/

2.安装msi,安装目录到C盘

安装好后,使用cmd执行 node- v npm -v看看是否都输出了版本号

3.在除C盘外创建一个nodejsFile文件夹,创建两个文件夹 node_global和node_cache,然后运行以下命令

npm config set prefix "D:\Program Files\nodejs\node_global"
npm config set cache "D:\Program Files\nodejs\node_cache"

4.检查当前系统变量中,path路径有没有叫C:\ProgramFiles\nodejs\node_modules

如果有,创建一个同名路径文件夹在C盘之外的盘符,如果没有就不用管了

  1. 在path变量中配置你的C:\Program Files\nodejs\node_modules路径

2. 安装淘宝镜像 cnpm

功能:和npm一样,npm是从海外镜像仓库下载,cnmp 是从阿里淘宝镜像仓库下载

npm install -g cnpm --registry=https://registry.npm.taobao.org

安装完成使用:cnpm -v 查看版本

3.安装webpack

npm install webpack -g

安装完成使用:npm webpack -v 查看版本

4. 下载vue脚手架

1.下载脚手架资源

cnpm install -g [email protected]

2.去到你的gloab目录查看是否有vue开头的文件

Vue从入门到精通课程超详细_第3张图片

  1. 到别的文件夹下创建一个空的文件夹,在文件夹中按住shift+鼠标右键,点击在此处打开pwershell窗口
  1. 打开窗口输入:vue init webpack

5.初始化构建vue脚手架

Vue从入门到精通课程超详细_第4张图片
Vue从入门到精通课程超详细_第5张图片

6.运行vue项目

在项目根目录下按住shift+鼠标右键,点击在此处打开pwershell窗口,执行 npm run dev

3. 使用VSCode构建Vue项目

下载VsCode

https://code.visualstudio.com/

组件下载

Vue从入门到精通课程超详细_第6张图片
Vue从入门到精通课程超详细_第7张图片

创建vue项目

  1. 创建一个空的项目文件夹
  2. 使用vsCode打开这个文件夹
  3. 设置vsCode语言:ctrl+shift+P 输入指令:Display language 先选择英文重启后再选择中文再重启就好了
  4. 打开终端
vue init webpack

会出现错误:not promite 。。。。 vsCode终端控制台没有系统写入权限

使用本机自带的cmd窗口使用管理员权限启动

将目录跳转至项目路径再执行vue init webpack指令

5.启动项目

npm run dev

Vue从入门到精通课程超详细_第8张图片

6.退出运行

ctrl+c

4. 编写第一个vue文件









使用VSCode创建一个自定义代码片段

文件–》首选项—》配置用户代码片段

{
	"Print to console": {
		"prefix": "myvue",// 代码段名称
		"body": [ //代码内容
			"",
			"",
"",
"",
"",
"",
"",
""
],
"description": "myvue"
}
}

5.App.vue文件

作用:vue项目首页,可以编写全局项目中公共的样式

注意:一般如果项目集成了路由功能,app.vue只会写一个路由标签







6.main.js-主入口文件

作用:配置通用组件的引入、vue通用配置

import Vue from 'vue'
import App from './App'
import router from './router'

Vue.config.productionTip = false

/* eslint-disable no-new */
// 创建vue,绑定主视图
// 脚手架项目中vue实例只会有一个,存在main.js中
new Vue({
  el: '#app',
  router,
  components: { App },
  template: ''
})

vue实例

每个 Vue.js 应用都是通过构造函数 Vue 创建一个 Vue 的根实例 启动的

Vue从入门到精通课程超详细_第9张图片

7. Vue组件的生命周期(vue2.0)

1. 组件创建阶段-create

Vue从入门到精通课程超详细_第10张图片

  1. 实例化组件
    1. beforeCreate 创建前
  2. 开启数据监听
  3. 初始化vue内部方法
    1. created 创建完成

vue中使用钩子函数








2.组件渲染阶段-mount

Vue从入门到精通课程超详细_第11张图片

  1. vue选择渲染模板,是要使用vue组件的方式渲染还是只是渲染部分html

    ​ 1.beforeMount - dom元素渲染之前

  2. 开始渲染

    1. mounted - dom挂载结束







3.组件运行阶段-数据更新-update

Vue从入门到精通课程超详细_第12张图片

  1. 监听器会监听所有data值的变化

    ​ 1.beforUpdate - 数据更新之前

  2. 使用VDom手段动态渲染html

    1. updated - 数据渲染完成







4.组件销毁阶段-destroy

注意:组件默认情况下不会主动销毁,需要借助v-if指令或者,Vue.$destroy()才会触发vue的销毁流程

Vue从入门到精通课程超详细_第13张图片

  1. 组件是否进入销毁流程(v-if指令或者,Vue.$destroy())
    1. beforeDestroy - 销毁之前
  2. 进行销毁 - 组件中所有的data值缓存都会消失、vdom缓存也会清除
    1. destroyed - 销毁结束

8.main.js进行全局配置

#取消 Vue 所有的日志与警告 - 开发不要配,生产环境配
Vue.config.silent = true


#配置是否允许 vue-devtools 检查代码 - 开发不要配,生产环境配
Vue.config.devtools = true 

#指定组件的渲染和观察期间未捕获错误的处理函数-全局异常处理回调
Vue.config.errorHandler = function (err, vm, info){} 

#设置为 false 以阻止 vue 在启动时生成生产提示 - 开发不要配true,生产环境配
Vue.config.productionTip = false


9. Vue语法

1. 插值表达式-文本类型(数值、boolean、字符串、字符、对象中的文本类型)

语法:{{ 数据变量名称 }}

是将vue绑定的数据渲染到视图产生关联,实现双向绑定




v-once指令

编写位置:插值表达式存在的开始标签中

作用:让插值表达式里的值不会根据data的变化而渲染,永远保持第一次加载的值




2.动态插入HTML文本

注意:{{ XXX }}解析的过程只会按照纯文本方式解析,如果要解析html代码段加载到dom中,需要使用v-html指令

v-html指令




3.标签属性值动态绑定(重点经常使用)

注意:title={{ xxxx }}不行,插值表达式不能使用在属性值以及属性名称上,标签位置上都不能使用插值表达式

那如果需要动态绑定一个数据给标签的属性值怎么办?就要使用v-bind指令

v-bind指令




v-bind指令可以简写为":"

 

欢迎访问网站

4.动态绑定表达式

当点击时动态绑定一段js代码

借助v-bind来实现




5.vue指令

编写的位置:开始标签中在标签的属性位置编写

1. v-once(不可再更新)

2.v-bind(动态绑定属性值)

3.v-html(动态添加子元素解析html)

4.v-on(事件绑定)

复杂写法:




简单写法:v-on用@替代

如:当点击时触发函数 @click=“函数”




键盘输入-实现事件触发

敲击回车,实现方法调用




js中所有keycode列表

https://blog.csdn.net/fghyibib/article/details/120670221?utm_medium=distribute.pc_relevant.none-task-blog-2defaultbaidujs_baidulandingword~default-1-120670221-blog-122497397.pc_relevant_multi_platform_whitelistv3&spm=1001.2101.3001.4242.2&utm_relevant_index=4

5.v-if 、v-show

v-if:
true: 标签或者组件被挂载
false:标签或者组件删除或销毁

v-show: 通过display样式控制组件显示隐藏
true: 标签或者组件 - 显示状态
false:标签或者组件 - 被隐藏




v-if挂载过程

当v-if值为true时:组件会进入创建阶段—渲染阶段

​ 如果父组件加载子组件时,子组件被v-if=“false” 描述时,子组件是不会被加载

当v-if值为false是:组件会进入销毁阶段

v-show挂载过程

当v-show值为true时:组件被显示-不会调用生命周期钩子

​ 如果父组件加载子组件时,子组件被v-show=“false” 描述时,子组件会加载但是不显示而已

当v-show值为false是:组件被隐藏-不会调用生命周期钩子

v-if根据boolean控制组件加载,v-show根据boolean控制组件显示隐藏不管值为true还是false都会被提前加载

6.v-else\v-else-if

多条件判断指令

注意:v-if v-els-if v-else要注意编写的顺序和数量,v-else只能有一个,v-else-if可以有多个

注意标签之间的顺序,不要有间隔

 // 独立的判断

123

//2 行 一组判断逻辑

7.v-for-有序列表的遍历 循环指令

v-for=“(循环中的每个对象,循环遍历的下标) in 要循环的集合数组”

​ 简写-只取出集合中的对象: v-for=“循环中的每个对象 in 要循环的集合数组”

循环中必填参数

​ key:描述循环的标签是独一无二的,只要绑定一个唯一值属性即可,提供给VDom更新元素








8.v-for - 遍历map\对象

v-for=“(对象的属性值,对象的属性名称,属性的序号) in 要迭代对象” :key=“唯一值”








9.v-model 表单数据绑定

在传统H5开发的方式下,表单的值一般是用value属性控制,但是进过测试动态绑定表单标签的value属性无法实现表单值的变化,这时我们需要使用v-model指令实现表单数据的动态绑定

1. v-model在文本域中的使用方法






注意:使用vue后,表单元素绑定数据就要使用v-model而不要再使用value属性了

1.v-model.lazy

效果:当填写完成,选中效果移除之后数据才更新

<input v-model.lazy="name"/>

2. v-model.number

效果:在填写文本时,只能填写数字

注意:只有填写文字是数字开头才有用,而且从数字开头截取字符直到出现第一个非数字位置结束,如:1a2b ===> 1

<input v-model.number="name"/>

推荐如果是纯数字校验,使用type=“number”

<input type="number" v-model.number="name"/>

v-model.trim

去除前后空格的方式

<input v-model.trim="name"/>

2. v-model在选择器中的使用方法


      <select v-model="name">
        
        <option :value="1">昆明option>
        
        <option :value="true">临沧option>
        <option value="3">蒙自option>
      select>

3. v-model 在单选和复选框中的使用方法

单选框






复选框






4. v-model使用在文本域中






10.过滤器

目的:可以改写插值表达式的显示内容








v-bind指令也能配合过滤器使用

点击查看用户信息

vue3.0已经弃用过滤器

11. 计算属性

计算属性使用场景:

和过滤器比较:

​ 过滤器:参数只能是插值表达式中|之前的值注入到过滤器的参数中,过滤器无法访问data绑定的数据

​ 计算属性:参数可以是在计算属性调用时的实参也可以访问data绑定的数据(this访问)

使用计算属性-无参的方法

{{ nameComputed }}

//计算属性
  computed:{
      //自定义计算属性
      nameComputed:function(){
          return this.userData.name.split('').reverse().join('');
      }
  }

使用计算属性-可以传递参数的方法

{{ nameComputed("1",1,3) }}

//计算属性
  computed:{
      //自定义计算属性
      nameComputed(){
         return function(value,value2,value3){
            console.dir(value);
            return this.userData.name.split('').reverse().join('');
         }
      }
  }

method方法能不能使用到插值表达式中

是可以的,但是推荐使用计算属性完成

method和computed的区别

计算属性:

​ 计算属性会使用浏览器缓存进行数据的存储和计算

​ 计算属性可以根据行为是读取还是参数赋值区分出get和set两种方法模式

mycomputed:{
        get:function(){// 无参调用计算属性时触发
          console.dir("get");
          return "get";
        },
        set:function(){// 有参调用计算属性触发
          console.dir("set");
          return "set";
        }
      }

而方法每次调用都需要经过函数执行的读写,没有任何缓存的实现,所以性能较差,当开发目的只是为了改变插值表达式的值内容的情景时,推荐使用计算属性完成

12.监听器

作用:监听data绑定数据的变化

注意:要监听的数据如果保存在对象中话写法有所区别








深度监听

多组件共用data值的时候会使用

"userData.data.data.age":{
      immediate:true,// 深度监听立即执行
      deep: true,//  开启深度监听
      handler(newVal,oldVal){
        console.dir(newVal+"-----"+oldVal);
      }
}

在昨天的学生信息列表功能下实现前端的:添加、编辑功能

  1. 添加功能:
    1. 在表格上方会有一个添加按钮
    2. 点击添加按钮弹出一个div,里面有学生信息添加内容的表单以及保存、重置表单按钮
    3. 填写完数据点击保存,弹窗关闭,表格数据刷新
  2. 编辑功能
    1. 表格中多一列操作列
    2. 操作列对应每一行中有编辑按钮
    3. 点击编辑弹出编辑div,里面有学生信息编辑内容的表单以及保存编辑
    4. 填写完数据点击保存,弹窗关闭,表格数据刷新
  3. 实现添加表单和编辑表单公用一个div和表单内容,通过判断实现

13. 动态样式绑定方法

动态修改class属性的方法实现样式变化

1.对象语法









2. 数据绑定实现class属性变化








3. 通过数组的方式控制class属性值内容








数组中可以使用表达式完成样式的选择








动态修改内联样式style属性的方法

1.嵌入对象的方法








2. 数据绑定style属性方法








14.组件开发方法

1.引入使用组件方法

子组件代码










父组件代码








2.子组件接收父组件数据

子组件要定义能接收的数据有些什么(组件参数)

props属性定义

注意:子父组件值传递是值的拷贝,不会传递地址

子组件写法










父组件传递方法








当子组件点击关闭按钮时,父组件要接收关闭事件的回调

需要子组件通知父组件,有事情发生,让父组件能够接收这个消息

3. 子组件与父组件回调方法

能实现子组件将数据传递到父组件

案例:点击子组件的关闭按钮,实现父组件div隐藏

子组件代码










父组件代码








  1. 定义一个子组件,功能是:通过父组件传递的列表数据实现一个动态下拉框
  2. 当下拉框选中数据时,要回调一个时间给父组件(change\selected)
  3. 实现下拉框清空功能,点击清空清空select选择的内容,然后回调一个事件给父组件(clear\qingkong)

在这里插入图片描述

4.子组件定义好后,父组件引入组件,试用是否正常

15. 路由

1. 路由是什么

2. 路由的三个对象

route:首先它是个单数,译为路由,即我们可以理解为单个路由或者某一个路由;( 单个路由信息 )

routes:它是个复数,表示多个的集合才能为复数;即我们可以理解为多个路由的集合,JS中表示多种不同状态的集合的形式只有数组和对象两种,事实上官方定义routes是一个数组;所以我们记住了,routes表示多个数组的集合;(整个项目中的所有路由信息)

router:译为路由器,上面都是路由,这个是路由器,我们可以理解为一个容器包含上述两个或者说它是一个管理者,负责管理上述两个;举个常见的场景的例子:当用户在页面上点击按钮的时候,这个时候router就会去routes中去查找route,就是说路由器会去路由集合中找对应的路由;(对象,可以实现路由的多种功能跳转)

3.如何配置路由

什么地址可以访问哪个组件,描述一下路由信息

  1. 编写组件页面

​ 2.打开路由配置文件

Vue从入门到精通课程超详细_第14张图片

import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
//1. 导入需要配置路由的组件
import Test2 from '@/components/Test2.vue';

Vue.use(Router)

export default new Router({
  // 所有路由信息-集合
  routes: [// 第一个路由记录就是欢迎页
    {
      path: '/',
      name: 'HelloWorld',
      component: HelloWorld,
      meta:{
        index:0,
        name:"首页"
      }
    },
    {// 2.编写路由
      path: '/test2',// 访问路径
      name: 'Test2', //路由组件名称
      component: Test2, //关联组件
      meta:{
        index:1, // 组件顺序-按照组件关系写
        name:"测试页面2" // 路由组件名称-中文描述-提供面包屑使用
      }
    }
  ]
})

改变路由访问的方法

export default new Router({
  mode: 'history',// 路由地址前面就不会有/#/

4. 路由跳转方法

1. router-link标签


        
        <router-link to="/test2">跳转到test2页面router-link>

2. $router对象

puish方法- 是会把路由跳转的记录添加到浏览器的缓存记录中的,就可以使用浏览器的前进和后退功能

replace方法-则不会将访问的数据添加到记录中

1.push方法- 直接传递路由地址字符串





2.push方法-传递一个路由信息对象




3.push-传递的路由信息对象-跳转的页面是通过name确定




4.replcae方法

和push用法相同

// 字符串
this.$router.replace('/home/first')
// 对象
this.$router.replace({ path: '/home/first' })
// 命名的路由
this.$router.replace({ name: 'home', params: { userId: wise }})

5. go方法

//前进一步 相当于history.forward()
this.$router.go(1) 
、
//后退一步 相当于history.back()
this.$router.go(-1) 

this.$router.go(10) 

3. 嵌套子路由

使用场景: 企业管理系统后端,左侧菜单右侧组件刷新的界面

主页:










路由配置

import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import Main from '@/components/main'
//1. 引入组件
import User from '@/components/user'
import Role from '@/components/role'

Vue.use(Router)

export default new Router({
  mode: 'history',// 路由地址前面就不会有/#/
  // 所有路由信息-集合
  routes: [// 第一个路由记录就是欢迎页
    {
      path: '/',
      name: 'HelloWorld',
      component: HelloWorld,
      meta:{
        index:0,
        name:"登录页面"
      }
    },
    {
      path: '/main',
      name: 'Main',
      component: Main,
      meta:{
        index:1,
        name:"首页"
      },
      children:[// 子路由!!!!!!!
        {
          path: '/user',
          name: 'User',
          component: User,
          meta:{
            index:1-1,
            name:"用户管理"
          }
        },
        {
          path: '/role',
          name: 'Role',
          component: Role,
          meta:{
            index:1-2,
            name:"角色管理"
          }
        }
      ]
    }
    
  ]
})

5.路由传参

1. 在路由路径上拼接参数- 刷新页面参数也不会丢失

路由配置文件中,在path属性上声明会出现参数的位置

{
      path: '/:id', // 在/ 路径之后 会传递一个 名字叫id的参数
      name: 'HelloWorld',
      component: HelloWorld,
      meta:{
        index:0,
        name:"登录页面"
      }
    },

调用路由跳转是传递参数

注意:只能传递简单的字符串和数值、boolean类型,不能传递对象

this.$router.push({ path:`/main/${this.param}`});

目标路由组件中获取参数

<!-- Dom页面 -->
<template>
  <div id="Main">

        <h1>主页</h1>
        <h1>{{ $route.params.id }}</h1>
  </div>
</template>

2.在调用路由方法时,添加params属性传递参数-刷新页面参数就丢失

路由配置文件就不用修改了

调用路由跳转方法

该方法是支持对象传递的

// 想要使用params传递参数,路由跳转的方法必须使用name指定路由页面才行
       this.$router.push({ name:"Main",params:this.param});

3.在调用路由方法是,添加query属性传递参数-刷新页面也不会丢失参数

路由配置文件就不用修改了

调用路由跳转方法

该方法是支持对象传递的

this.$router.push({ path:"/main",query:this.param});

路由目标页面取参数,要通过query参数取得

this.loginUser = this.$route.query.name;

总结路由传参3种方法:

1.路径拼接法: 如果面有必须要初始化或者必须传递参数才能使用的场景时在使用

​ 2.params方法:对传递的参数进行加密,但是数据传输是一次性的

​ 3.query方法:对参数没有进行加密,直接暴露在url中

routes对象访问

this.$router.options.routes

能够访问当前项目的所有路由信息

6.Vue路由跳转加载进度条

1. 使用Nprogress

在项目的窗口中执行

cnpm install nprogress

2.main.js中引入组件和样式

import NProgress from 'nprogress' 
import 'nprogress/nprogress.css'// nprogress样式文件

3.路由组件钩子函数配置

两个钩子:路由跳转前和跳转后

// 路由的钩子函数是main.js中配置的

// 路由跳转之前
router.beforeEach((to, from , next) => {
    // 开启进度条
    NProgress.start();
    // 这个一定要加,没有next()页面不会跳转的。这部分还不清楚的去翻一下官网就明白了
    next();
});


//当路由跳转结束后
router.afterEach(() => {  
    // 关闭进度条
    NProgress.done()
})


  1. 需要实现一个增删改查分页的表格组件

16. axios组件

作用: 与ajax一样,底层实现就是js-ajax,写法要比之前学习的JQuery、js的ajax都要简单

安装步骤

//1. 在项目窗口中执行
cnpm install axios


main.js中配置axios内容

import axios from 'axios'
Vue.prototype.$axios = axios //全局属性

全局属性的定义方法

在main.js中定义

// 定义全局属性的方法
// Vue.prototype.自定义属性名 = 组件对象
// 属性命名规则:$+属性名
// 在组件中使用全局属性: this.$axios   
Vue.prototype.$axios = axios //全局属性

跨域问题处理、请求服务地址配置

什么是跨域?

出于浏览器的同源策略限制。同源策略(Sameoriginpolicy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。同源策略会阻止一个域的javascript脚本和另外一个域的内容进行交互。所谓同源(即指在同一个域)就是两个页面具有相同的协议(protocol),主机(host)和端口号(port)

注意: 协议+主机+端口有一个不相同就会出现跨域问题

1.配置BaseUrl,在main.js文件中

axios.defaults.baseURL = '/api'  //关键代码,/api之后替换的就是 http://localhost:8090

2.配置代理,在config文件夹下的index.js文件中的proxyTable字段

module.exports = {
  dev: {

    // Paths
    assetsSubDirectory: 'static',
    assetsPublicPath: '/',
    proxyTable: { // 配置到这里!!!!
      '/api': {// 配置了一个静态地址代理
        target:'http://localhost:8090', // 后端服务地址以及端口号
        changeOrigin:true,  // 可以跨域
        pathRewrite:{
          '^/api': ''
        }
      }
    },
  1. main.js 修改 axios全局属性的创建方法
Vue.prototype.$axios = axios.create({
	baseURL:'/api',
	timeout:30000
})

  1. 把项目停止,执行cnpm install ,再启动项目
  1. 测试案例
getData() {
      console.dir(this);
      // 在axios代码中要使用this关键字访问data或者方法等等vue组件内容的话需要定一个别名变量
      let _this = this;
      this.$axios
        .get("goods/goods/getGoodsByID?id=101")
        .then(function(res) {
          _this.resData = res.data;
        })
        .catch(function(error) {
          // 请求失败处理
          console.log(error);
        });
    }

4种请求

GET请求

  1. 参数拼接在url后面
// 直接在 URL 上添加参数 ID=12345
axios.get('/user?ID=12345')
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

  1. 传入一个有params属性的参数
 this.$axios
        .get("goods/goods/getGoodsByID",{
          params:{// 写键值对参数内容
            id:101
          }
        })

POST请求

请求已经将数据封装为json数据发送后端了,所以在后端编写controller方法时,记得要使用@RequestBody注解接收参数

put\delete请求写法和post一致

this.$axios
        .post("goods/goods/testpost",{  // 参数传递的方法和GET不同
          name:"张三",
          price:18.9
        })

批量提交请求方法

需要使用的是axios组件对象的all方法,而以上案例中使用的$axios对象是通过组件对象.create创建的实例

所以我们需要从新定义一个全局的axios组件对象

main.js中定义组件对象全局属性

Vue.prototype.$VueAxios = axios;  // all 再用该对象    新配置的组件对象

Vue.prototype.$axios = axios.create({// get post delete put
	baseURL:'/api',
	timeout:30000
})

批量接口调用方法

getData1() {
       return  this.$axios
        .post("goods/goods/testpost",{
          name:"张三",
          price:18.9
        });
    },
    getData2() {
       return  this.$axios.get("goods/goods/getGoodsByID?id=101");
    },
    //合并提交方法
    getAllData(){
      let _this = this;
      console.dir(this.$axios);
      this.$VueAxios.all([_this.getData1(),_this.getData2()]) // 按照数组顺序调用
      .then(_this.$VueAxios.spread(function (res1, res2) { // 根据调用方法的数量定义接收对应方法返回的数据参数
        // 当所有的方法执行完成且都有返回值之后
          console.dir("请求完成");
          console.dir(acct);
          console.dir(perms);
       }));

    }

请求拦截器

请求拦截器的作用

在axios发送请求到后端之前进行拦截,可以修改请求的参数等内容

写在main.js中

// http request 请求拦截器
axios.interceptors.request.use(config => {
	// 在发送请求之前做些什么
	return config;
}, error => {
	// 对请求错误做些什么
	return Promise.reject(error);
});

响应拦截器

作用:

​ 所有的请求返回响应时都会进入改拦截器

// 响应拦截器
Vue.prototype.$axios.interceptors.response.use(response => {

  console.dir(response);
  if(response.data.code == "9999"){//系统异常
    // 统一错误提示弹窗
  }else if(response.data.code == "-1"){ // 登录会话失效
    // 使用路由返回到登录页面
  }

  return response;
},error => {
  if (error.response) {
   // 返回接口返回的错误信息
   return Promise.reject(error.response.data);
 }
});

17. 子组件自定义v-model

v-model: 只能在表单功能上出现

案例:子组件实现性别单选,v-model实现绑定性别的code值,子父组件修改v-model绑定的子父数据都会改变

子组件写法









父组件

<Test1 v-model="data" />

18.插槽

作用:能够将指定的标签放置在组件的插槽容器中,可以规范组件内容组成也可以灵活配置组件内容

插槽标签

<slot>。。slot>

插槽-默认插槽

也叫无具名插槽,一般用在父组件快速批量替换子组件默认内容时使用

子组件定义

<template>
  <div id="Test1">
    <div class="div1">
        
        <slot>默认插槽的文字1slot> 
    div>
    <div class="div2">
        <slot>默认插槽的文字2slot>
    div>
  div>
template>

父组件改变默认插槽方法

<Test1 v-model="sexCode" >
   
   <h1>XXXh1>
   <h1>XXX222h1>
Test1>

Vue从入门到精通课程超详细_第15张图片

具名插槽

子组件定义

<template>
  <div id="Test1">
    <div class="div1">
        <slot name="one">插槽的文字1slot>
    div>
    <div class="div2">
        <slot name="two">插槽的文字2slot>
    div>
  div>
template>

父组件

<Test1 v-model="sexCode" >
        
        <template v-slot:one>
         <h1>XXXh1>
        template>
      Test1>

slot属性赋值具名插槽方法


        <div slot="one">
          <h1>XXXh1>
        div>

对象作用域插槽

子组件

<template>
  <div id="Test1">
    <div class="div1">
        
        <slot :obj2="objData" :obj="objData">插槽的文字1slot>
    div>
  div>
template>

<script>
export default {
  name: "Test1",
  data() {
    return {
        objData:{
            name:"张三",
            age:18
        }
    };
  },
  methods:{
  }
};
script>

父组件

<Test1 v-model="sexCode" >
        
        <template v-slot="objData">
          
          <h1>{{ objData.obj2.name }}h1>
        template>
      Test1>

19. Vuex状态管理

1.安装方法

在项目cmd窗口中执行

cnpm install vuex

创建一个store.js的文件,

在src目录下创建vuex文件夹,在文件夹中创建store.js文件

import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

export default new Vuex.Store({
    state:{

    },
    getters:{

    },
    mutations:{

    },
    actions:{
        
    }
});

在main.js中导入组件

//导入vuex组件内容
import Vuex from 'vuex';
import store from './vuex/store'
Vue.use(Vuex);
Vue.prototype.$store = store;


// 修改原有的new Vue构造器
new Vue({
  el: '#app',
  router,
  store, // 添加到全局组件
  components: { App },
  template: ''
})

使用方法

1. 设置保存数据

在state对象中描述要保存的数据

export default new Vuex.Store({
    state:{// 共享的数据
        count:0
    },

2. 修改数据

1.action - 无参调用方法

actions:{// 操作state里的数据方法
        addCount(){// 每次调用让count数据+1
            this.state.count++;
        },

调用方法

// 调用了vuex中action中的addCount方法,无参调用
        this.$store.dispatch("addCount"); // 字符串的action方法名

2.action - 有参调用方法

// 形参1: vuex对象
// 形参2: 传入的数据(如果要传递多个参数,就封装到对象中---map、集合)
addCount2(obj,param){
    this.state.count += param;
}

调用的方法

this.$store.dispatch("addCount2",123);

3. mutations - 无参调用

mutations:{
        m_addCount(){
            this.state.count++;
        }
    },

调用方法

this.$store.commit("m_addCount");

4.mutations - 有参调用

// 形参1:  state对象 
// 形参2: 传入的数据(如果要传递多个参数,就封装到对象中---map、集合)
m_addCount2(obj,param){
            console.log(obj); // state对象 
            this.state.count += param;
        }

调用方法

this.$store.commit("m_addCount2",123);

3. 获取值

getters

getters:{// 获取值的操作
        getCount(obj){// 参数注入了当前vuex的state对象
            console.dir(obj.count); 
            return obj.count; // $store.getters.getCount
        }
    },

调用方法

this.$store.getters.getCount

mutations和action 方法使用选择

如果需要异步快速执行就使用action方法,如果是需要保证数据读写安全通过等待就使用mutations方法

action方法是会返回promise函数,可以使用then和catch描述方法调用成功或失败的节点

而 mutations方法没有,就只是一个简单的函数调用

推荐使用mutations方法,因为同步安全

20.ElementUI

1. 安装

项目cmd窗口执行

cnpm install element-ui

在main.js中导入el组件内容

//导入elementui
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
Vue.use(ElementUI);

测试el组件能否使用


你可能感兴趣的:(前端开发,vue.js,javascript,前端)