vue -【nextTick】-【过度与动画】-【插槽】-【配置代理服务器】-【vuex】-【路由】

目录

  • nextTick
  • 过度与动画
  • vue脚手架配置代理服务器
  • 插槽
    • 默认插槽
    • 具名插槽
    • 作用域插槽
  • vuex
    • 搭建vuex环境
    • 基本使用:
    • getters的使用
    • 四个map方法的使用
      • mapState方法
      • mapGetters方法
      • mapMutations方法
      • mapActions方法
    • 模块化+命名空间
  • 路由
    • 基本使用
    • 多级路由/嵌套路由
    • 路由的query参数
    • 命名路由
    • 路由的params参数
    • 路由的props配置
    • router-link标签的replace属性
    • 编程式路由导航
    • 缓存路由组件
    • 路由守卫
      • 全局守卫
      • 独享守卫
      • 组件内路由守卫
    • 路由器的两种工作模式

nextTick

一、语法:this.$nextTick(回调函数)
二、作用:在下一次DOM更新结束后执行其指定的回调。
三、什么时候用:当改变数据后,要基于更新后的新DOM进行某些操作时,要在nextTick所指定的回调函数中执行。
四、需求:点击【编辑】按钮后,出现编辑输入框,并且输入框已经获焦。
五、思路:由todo.isEdit变量来控制输入框的展示和隐藏:,点击【编辑】按钮后,执行handleEdit函数,todo.isEdit变量变为true,并让输入框获焦,其余情况todo.isEdit变量为false,隐藏输入框,handleEdit函数代码如下:

handleEdit(todo){
	if(todo.hasOwnProperty('isEdit')){// 看todo对象上有没有isEdit属性,有的话置true
		todo.isEdit = true
	}else{// 没有的话,添加并置true
		this.$set(todo,'isEdit',true)
	}
	this.$refs.inputTitle.focus()
}

这样写代码根本无法实现点击【编辑】按钮后,出现编辑输入框,此时编辑输入框已经获焦这一需求。因为vue并不是像我们想的那样,发现你改数据了,立马帮你重新解析模板,他会等handleEdit中的代码都执行完了,再去重新解析模板。如果每次改了数据都去重新解析模板会拉低效率,所以vue等handleEdit中的代码都执行完了,再一起去更改数据,解析模板,所以上面执行了todo.isEdit = true后,页面上并没有出现input框,然后就执行this.$refs.inputTitle.focus()获取焦点,你现在压根拿不到input框,你也无法实现聚焦。
下面使用nextTick来解决这一问题

handleEdit(todo){
	// 对象.hasOwnProperty('属性名'):对象身上是否有某个属性
	if(todo.hasOwnProperty('isEdit')){// 有isEdit这个属性,改变它的值
		todo.isEdit = true
	}else{// 没有isEdit这个属性,新增
		this.$set(todo,'isEdit',true)
	}
    //组件.$nextTick(回调函数):回调函数会在DOM节点更新后调用
	this.$nextTick(function(){
		this.$refs.inputTitle.focus()// 获取焦点
	})
},

过度与动画

一、作用:在插入、更新或移除 DOM元素时,在合适的时候给元素添加样式类名。
二、写法:

  1. 准备好样式:
    元素进入的样式:
    (1)v-enter:进入的起点
    (2)v-enter-active:进入过程中
    (3)v-enter-to:进入的终点
    元素离开的样式:
    (1)v-leave:离开的起点
    (2)v-leave-active:离开过程中
    (3)v-leave-to:离开的终点
  2. 使用包裹要过度的元素,也就是说,你想让谁发生动画效果,你就把谁用transition包裹起来,并为标签配置name属性:
<transition name="hello">
	<h1 v-show="isShow">你好啊!h1>
transition>

如果不指定name="hello"属性,那么vue会在合适的时机给transition中的元素添加类名:.v-enter-active;如果指定了,那么vue会在合适的时机给transition中的元素添加类名:.hello-leave-active等。如果有多个元素有动画效果,那么一定要指定name属性,不然两个元素的动画就一样了

  1. 备注:若有多个元素需要过度,则需要使用:,且每个元素都要指定key值。

三、将transition标签的appear设为true:表明出现时就激活动画

 <transition appear="true">transition>:transition标签中有个appear属性,其值为`"true"`(字符串类型)
<transition appear>transition>:让transition标签有appear属性

四、transition中的元素最终不会形成真正的元素,vue编译时会把transition标签去掉
五、transition其实就只是在特定时候给标签添加类名,该类名具体做什么过度/动画,都是程序员决定的

<template>
	<div>
		<button @click="isShow = !isShow">显示/隐藏button>
		<transition name="hello" appear>
			<h1 v-show="isShow">你好啊!h1>
		transition>
	div>
template>

<script>
	export default {
		name:'Test',
		data() {
			return {
				isShow:true
			}
		},
	}
script>

<style scoped>
	h1{
		background-color: orange;
	}

	.hello-enter-active{// 进入时要激活的样式
		animation: atguigu 0.5s linear;
	}

	.hello-leave-active{// 离开时要激活的样式
		animation: atguigu 0.5s linear reverse;
	}

    //动画要使用@keyframes定义个关键帧
	@keyframes atguigu {//@keyframes 动画名
    //动画过程
		from{
			transform: translateX(-100%);
		}
		to{
			transform: translateX(0px);
		}
	}
style>

标签只能用在单个元素上,如果你有多个元素要实现动画效果,使用标签,标签中的每个元素都要有个唯一的key值

<template>
	<div>
		<button @click="isShow = !isShow">显示/隐藏button>
		<transition-group name="hello" appear>
			<h1 v-show="!isShow" key="1">你好啊!h1>
			<h1 v-show="isShow" key="2">尚硅谷!h1>
		transition-group>
	div>
template>

<script>
	export default {
		name:'Test',
		data() {
			return {
				isShow:true
			}
		},
	}
script>

<style scoped>
	h1{
		background-color: orange;
	}
	/*
	进入的起点、离开的终点
	只在进入的起点(第一帧)加.hello-enter,第二帧.hello-enter就被移除了,这个过程很快,我们很难捕捉到
	*/
	.hello-enter,.hello-leave-to{
		transform: translateX(-100%);
	}
  	//整个进入过程、整个离开过程
	.hello-enter-active,.hello-leave-active{
		transition: 0.5s linear;
	}
	/*
	进入的终点、离开的起点
	只在离开的起点(第一帧)加.hello-leave,第二帧.hello-leave就被移除了,这个过程很快,我们很难捕捉到
	*/
	.hello-enter-to,.hello-leave{
		transform: translateX(0);
	}
style>

在vue中可以使用第三方成型的样式库/动画库来辅助我们快速实现炫酷的动画效果,如animate.css

  1. 在项目终端安装:npm install animate.css
  2. 引入:import 'animate.css'//因为引入的是样式,不是JS模块,所以直接在组件中写:import 路径
  3. 标签添加:name="animate__animated animate__bounce"
  4. 标签添加:
    (1)进入的动画:enter-active-class="animate__swing"
    (2)离开的动画:leave-active-class="animate__backOutUp"
    其中,animate__swing、animate__backOutUp都是在animate.css中找的
<template>
	<div>
		<button @click="isShow = !isShow">显示/隐藏button>
		<transition-group 
			appear
			name="animate__animated animate__bounce" 
			enter-active-class="animate__swing"
			leave-active-class="animate__backOutUp"
		>
			<h1 v-show="!isShow" key="1">你好啊!h1>
			<h1 v-show="isShow" key="2">尚硅谷!h1>
		transition-group>
	div>
template>

<script>
	import 'animate.css'//引入,因为引入的是样式,不是JS模块,所以直接写:import 路径
	export default {
		name:'Test',
		data() {
			return {
				isShow:true
			}
		},
	}
script>

<style scoped>
	h1{
		background-color: orange;
	}
style>

vue脚手架配置代理服务器

一、方法一:在vue.config.js中添加如下配置:

devServer:{
  proxy:"http://localhost:5000"
}

说明:

  1. 优点:配置简单,请求资源时直接发给前端(8080)即可。
  2. 缺点:不能配置多个代理,不能灵活的控制请求是否走代理。
  3. 工作方式:若按照上述配置代理,当请求了前端不存在的资源时,那么该请求会转发给服务器 (优先匹配前端资源)

二、方法二:编写vue.config.js配置具体代理规则:

module.exports = {
	devServer: {
      proxy: {
      '/api1': {// 匹配所有以 '/api1'开头的请求路径
        target: 'http://localhost:5000',// 代理目标的基础路径
        changeOrigin: true,
        pathRewrite: {'^/api1': ''}
      },
      '/api2': {// 匹配所有以 '/api2'开头的请求路径
        target: 'http://localhost:5001',// 代理目标的基础路径
        changeOrigin: true,
        pathRewrite: {'^/api2': ''}
      }
    }
  }
}

说明:

  1. 优点:可以配置多个代理,且可以灵活的控制请求是否走代理。
  2. 缺点:配置略微繁琐,请求资源时必须加前缀。

vue.config.js中代码如下:

//本文件用于修改脚手架工作模式
//vue最终会把vue.config.js输送给webpack,webpack是基于Node的,所以vue.config.js中使用commonJS。
//配置方式参考:https://cli.vuejs.org/zh/config/
module.exports = {
  pages: {
    index: {
      entry: 'src/main.js',//入口
    },
  },
	lintOnSave:false, //关闭语法检查
	/*
	参考:https://cli.vuejs.org/zh/config/#devserver-proxy
	开启代理服务器(方式一)
	缺点:
	    1.不能配置多个代理;
	    2.不能灵活的控制代理是否转发请求,
	        你请求的资源是:http://localhost:8080/students,public是本服务器的根文件夹,即http://localhost:8080,
            如果public/students存在,那么代理服务器会直接返回该资源,而不会发起请求。
            但是如果我们希望代理服务器转发请求,这种配置方式无法做到。当你请求的资源不存在时,
            无法控制他是否转发请求,他一定会转发请求。
	 */
	/* devServer: {
    proxy: 'http://localhost:5000'//一会儿把请求转发给谁
  }, */

	//开启代理服务器(方式二)
	devServer: {
    proxy: {
      /*
      '/atguigu'和'/demo'代表请求前缀,请求前缀不匹配(没有/atguigu或/demo)则不转发请求
      前缀紧跟在端口号后面
       */
      '/atguigu': {// 请求前缀为/atguigu,即http://localhost:8080/atguigu/students,则配置如下:
        target: 'http://localhost:5000',//一会儿把请求转发给谁
                /*
                 代理服务器和浏览器都在http://localhost:8080,
                 假设现在App.vue中发起的请求为http://localhost:8080/atguigu/students,
                 这个请求是发给代理服务器的,代理服务器收到后,发现前缀是/atguigu,
                 会把这个请求转发给http://localhost:5000,
                 即代理服务器发起的请求是:http://localhost:5000/atguigu/students,会带上前缀,
                 如果我们不希望他带上前缀,则需要配置pathRewrite
                 */
				pathRewrite:{'^/atguigu':''},//把所有以atguigu开头的路径变成''
        // ws: true, //用于支持websocket,默认为true,在react中默认为false
        // changeOrigin: true //用于控制请求头中的host值(请求来自于哪里),默认为true,在react中默认为false。
          // 为false则暴露自己(代理服务器)真实的url(http://localhost:8080),
          // 为true则隐藏自己(代理服务器)真实的url,显示服务器的url(http://localhost:5000)
      },
      '/demo': {
                target: 'http://localhost:5001',
				pathRewrite:{'^/demo':''},
        // ws: true, //用于支持websocket
        // changeOrigin: true //用于控制请求头中的host值
      }
    }
  }
}

使用axios发送网络请求

  1. 在项目终端安装axios:npm i axios
  2. 在使用的组件中引入:import axios from 'axios'

插槽

作用:让父组件可以向子组件指定位置插入html结构,也是一种组件间通信的方式,适用于 父组件 => 子组件
分类:默认插槽、具名插槽、作用域插槽

默认插槽

子组件中:

<template>
    <div>
       
       <slot>插槽默认内容...slot>
    div>
template>

父组件(使用者)中:

<Category>
    
	<img src="https://s3.ax1x.com/2021/01/16/srJlq0.jpg" alt="">
Category>

具名插槽

子组件中:

<template>
	<div>
    	
        <slot name="center">插槽默认内容...slot>
        <slot name="footer">插槽默认内容...slot>
    div>
template>

父组件(使用者)中:

  1. 方法一:通过slot属性指定放入哪个插槽
<Category title="美食" >
	<img slot="center" src="https://s3.ax1x.com/2021/01/16/srJlq0.jpg" alt="">
	<a slot="footer" href="http://www.atguigu.com">更多美食a>
	Category>
  1. 方法二:在