Vue2简写笔记

此篇文章主要适用于有vue2基础的,用于回看复习巩固的哦

1.初识Vue

使用Vue:

  • 创建实例
  • 实例中传入配置对象
  • 配置对象的属性:
    • el: 模板容器
    • data:模板里可以直接使用的数据
      • {{ XXX }} :XXX为js表达式 且数据实时动态更新(一边改变另一边也跟着改变)

js表达式:会产生一个值 (可以作为赋值等式的右边)

2.模板语法

  • 插值语法
    {{XXX}}
  • 指令语法
    • 单向数据绑定:v-bind:value=“xxx” 简写: :value=“xxx” (其中xxx也为js表达式)
    • 双向数据绑定: v-model:value=“xxx” 简写: v-model=“xxx” (只用于表单类元素 输出类元素)

3. el和data的两种写法

el

  • 创建Vue实例的时候就指定el属性
  • 实例的$mount()方法指定
//第二种写法:
const vm = new Vue({
	data:{
			name:'尚硅谷'
		}
})
vm.$mount('#root')

data

  • 对象
  • 函数:返回对象

4. MVVM模式

Model-View-ViewModel:模型-视图-视图模型

  • 模型指的是后端传递的数据
  • 视图指的是所看到的页面
  • 视图模型是mvvm模式的核心,它是连接view和model的桥梁。
    • 两个方向 :
      • 模式转化为视图(后端数据–>页面) 通过数据绑定
      • 视图转化为模型 (页面–> 后端数据) 通过DOM事件监听
      • 而这两个方向都实现的 称为:数据的双向绑定
  • Vue管理的函数this指向? 一旦为箭头函数 其this不再指向Vue实例了???

什么是DOM BOM JS???

5. vm

vm作为Vue的实例

  • 在配置对象传入的参数最后都会出现在vm之中
    vm身上的属性以及Vue原型上的所有属性 最后再Vue模块中都可以直接访问
    在这里插入图片描述

6. 数据代理

1)Object.defineproperty

用来定义对象的某个属性的特性的
除了属性值 是否可修改 可删除等几种属性 还有get和set方法 用于监视属性值改变之后所调用的函数

Object.defineProperty(person,'age',{
				// value:18,
				// enumerable:true, //控制属性是否可以枚举,默认值是false
				// writable:true, //控制属性是否可以被修改,默认值是false
				// configurable:true //控制属性是否可以被删除,默认值是false

				//当有人读取person的age属性时,get函数(getter)就会被调用,且返回值就是age的值
				get(){
					console.log('有人读取age属性了')
					return number
				},
				//当有人修改person的age属性时,set函数(setter)就会被调用,且会收到修改的具体值
				set(value){
					console.log('有人修改了age属性,且值是',value)
					number = value
				}

			})

2) 数据代理

什么是数据代理?

通过一个对象1代理对另一个对象2属性的操作 (读or写)
也就是原来想更改使用对象1 结果再定义函数里面去更改使用了另一个对象的属性

3)Vue中的数据代理

通过上面我们知道data的数据最后是跑到了vm实例上了
使用的时候 我们是使用了了vm中的数据 那么如何实现通过改变vm中的数据的意图 让data中的数据有所改变呢?

这就涉及到了数据代理
通过vm对象代理data中属性的读和写

基本原理

  • 先通过Object.defineProperty()把data对象属性要添加到vm上
  • 然后为每一个vm上的属性指定getter 和setter
  • 在指定的getter和setter中修改data对象的属性

阶段性总结1

  • 初识Vue(怎么使用

    • 创建实例 传入配置对象
    • 配置对象指定Vue模板(el)和传入数据(data
  • el指定:配置对象 实例的$mount方法

  • data: 对象式和函数式

  • 模板语法

    • 插值语法
    • 数据绑定 (单向v-bind 双向 v-model
  • MVVM
    

    模型

    • 后端数据和渲染页面之间的传递关系
    • 通过VM实现双向数据绑定
  • vm
    
    • Vue的实例
    • data中的数据随后会在存在vm的属性中
    • 模板中可以直接访问vm的属性以及Vue原型上的属性
  • 数据代理

    • Obejct.defineProperty()方法
    • 通过vm对象来为data中的属性进行代理

7. 事件的基本使用

Vue实例中的methods属性进行设置

  • 普通函数这里的this指向 vm实例
  • 若写为箭头函数则为 window
  • 函数参数:
    • param (传递的数据 可选值)
    • event事件对象
 methods:{
            /* 参数为event事件对象  
             * 属性有target 
             * this指向为vm实例 如果写为箭头函数 则this为window */
            /* 函数无需数据代理 */
            showParams(param, event){
                alert(param);
                console.log(event.target.innerHTML);
            }
        }

标签中绑定

  • @click = “xxx”
  • @click = “xxx(param)”

2)事件修饰符

  • .stop 阻止冒泡 (即子元素触发的事件不会传递到父元素)
  • .capture
    通常嵌套事件的发生分为捕获和冒泡阶段 一般在冒泡阶段才会执行事件
    要是想在捕获的时候执行 则加上capture事件修饰符即可(在父元素上加即可)
  • .wheel :鼠标滚轮滚一次就触发一次(到底部滚动鼠标滚轮仍然可触发)
  • .scroll:不管以什么方法(上下键 鼠标滚轮 鼠标拖动)
    使得滚动条滚动即可触发 到底部不能滚动了则不触发
  • .once 事件只触发一次
  • .prevent:阻止默认行为
  • self:只有event.target是当前操作的元素时才触发事件
  • passive:事件的默认行为立即执行,无需等待事件回调执行完毕;

细致的点 等待二刷 self passive

3)键盘事件

二刷

8. 计算属性

  • 定义:需要已有属性进行获得
  • 属性
  • 简写

9. 监视属性

  • 定义 监视属性 改变时候调用回调函数
  • 属性
  • 深度监视
  • 简写
  • 和computed区别 (异步)

10. 绑定样式

  • :class = "xxx"xxx为:
    • 字符串
    • 对象
    • 数组(true false)
  • :style = “xxx” xxx为:
    • 对象
    • 数组(元素为对象)

11. 条件渲染

  • v-if
    • v-else-if=“xxx” v-else
    • template
    • 直接无
  • v-show
    • 只是隐藏了

12. 列表渲染

  • 基本语法
  • 指定key
    • 虚拟DOM的id
    • 通过这个进行比对
    • 如果用index出错:
      • 逆序添加
      • 输出类元素
  • 数据监测
    • 深度监测
    • 对于对象后添加的元素
    • 数组后添加应该用:
      • 方法
      • Vue.set vm.$set()

13. 收集表单数据

  • type为text
    • v-model收集到的就是value
  • type为radio
    • v-model收集到的:value(其需要设置value属性)
  • type为 checkbox
    • 没有配置value属性 收集到的就是checked布尔值
    • 配置了
      • 数组: value组成的数组
      • 非数组:checked
  • 三个修饰符
    • lazy
    • number
    • trim
//阻止点击a标签跳转页面
	<a href="www.baidu.com" @click.prevent="show">点我提示信息哦</a>

14. 过滤器

  • 作用:格式化显示一些数据
  • 配置:
    • 全局Vue.filter(“xx”,fn);
    • filters属性
      • {{xx | 过滤器名}}
      • v-bind:“xx | 过滤器名 ”

15. 内置指令

  • v-text
  • v-html
  • v-cloak 接管之后消失
  • v-html 安全问题
  • v-pre 加快编译

16. 自定义属性

  • 定义
    • 全局 Vue.directive
    • directives
      • 函数
      • 对象 (三个参数 bind inserted update)

17. 生命周期

  • 配置data methods方法 --》 解析模板 --》【更新数据】 --》销毁
  • mouted:Vue编译过 操作DOM有效
    • 发送ajax 开启定时器 订阅消息 自定义事件等
  • beforeDestroy : 关闭定时器 取消订阅消息 解绑自定义事件等

阶段性总结2

  • 事件处理
    • 绑定事件
    • 事件修饰符
    • 有关键盘
  • 绑定样式
  • 条件渲染
  • 列表渲染
  • 过滤器
  • 获取表单数据
  • 内置指令
  • 自定义指令
  • 生命周期

18. 非单组件

  • 创建
    • vue.extend(options对象)
    • 两点注意点
      • el
      • data
  • 注册
    • 局部注册
    • 全局注册
  • 使用
    • 标签
  • 组件的嵌套

19. 单文件组件

将相关组件拆成文件形式 然后通过export导出 import引入

20. 脚手架

  • 定义
    • 构建工具
    • 生成项目模板
  • 搭建
    • 下载 npm install -g @vue/cli
    • 创建项目 vue create xxx
    • 启动 npm run serve
  • 使用细节
    • webpack相关配置:

21. ref

ref=“xx”
获取:this.$refs.xx

<template>
	<div>
		<h1 v-text="msg" ref="title"></h1>
		<button ref="btn" @click="showDOM">点我输出上方的DOM元素</button>
		<School ref="sch"/>
	</div>
</template>



//引用
	console.log(this.$refs.title) //真实DOM元素
	console.log(this.$refs.btn) //真实DOM元素
	console.log(this.$refs.sch) //School组件的实例对象(vc)

22.props

  • 父组件给子组件传数据
  • attr=“xx”(子组件标签)
    • 前面加冒号 引号里面就变成了js表达式(数)
  • props属性进行引用(子组件文件中)
    • 数组
    • 对象
      • 可以是对象嵌套(类型 默认值 必要性的进一步设定)

App.vue

<template>
	<div>
		<Student name="李四" sex="女" :age="18"/>
	</div>
</template>

student.vue

//student.vue
//简单声明接收
		// props:['name','age','sex'] 

		//接收的同时对数据进行类型限制
		/* props:{
			name:String,
			age:Number,
			sex:String
		} */

		//接收的同时对数据:进行类型限制+默认值的指定+必要性的限制
		props:{
			name:{
				type:String, //name的类型是字符串
				required:true, //name是必要的
			},
			age:{
				type:Number,
				default:99 //默认值
			},
			sex:{
				type:String,
				required:true
			}
		}

有关babel介绍:链接
babel:JS编译器

23. mixin混入

  • 提取公共数据
  • 定义mixin.js
  • 引入
  • 重名的处理

24. plugins

  • 功能:增强Vue
  • 定义
    • plugins.js
    • 参数:
      • Vue
      • params
    • 全局filter(格式化显示数据)
    • 全局directive(自定义指令)
    • Vue原型上添加数据
    • 定义混入
  • 引入
    • main.js
    • import
    • Vue.use(plugin, params)

25. scoped

  • 私有化
  • style标签的属性 避免重名设置css样式
  • 可以出现的问题 加上不可以为body设置样式了

26.vuex

  • vuex是一个插件 一种组件间通信的方式(多个组件共享数据时使用)
  • vue2 需要下载vuex@3(指定版本3)
  • 基本使用
  • 创建文件store/index.js
    • 引入Vue 和 Vuex 插件使用(Vue.use(Vuex))
    • 定义三个对象
      • actions
        • 响应动作
        • 方法参数:context(有commit方法来提交给mutations)和传入data)
      • mutations(其中)
        • 普通方法
        • 方法参数:state 和 传入data
      • state对象
        • 存放公共对象
      • getters对象
        • 对state再加工(相当于computed)
      • 创建并暴露store(new Vuex.store({对象传入}))
  • 在main.js引入store 且作为创建vm时配置对象的属性
  • 组件中使用
    • state: (vm.)$store.state.xx
    • mutations: (vm.)$store. commit(方法,data)
    • actions:(vm.)$store.dispatch(方法, data)
  • 可见上面使用时候前缀很多 使用起来很麻烦 所以引入map
  • 使用
    • 在组件中引入各个方法(import {} from “vuex”)
    • state和getter数据在compued中
    • …mapState(xx) / …mapGetters(xx)
      • xx为对象形式或者数组(更简便)
    • mutations和actions在methods里面配置
    • …mapActions(xx) …mapMutations
    • 同样为对象和数组形式

store/index.js

//该文件用于创建Vuex中最为核心的store
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
//应用Vuex插件
Vue.use(Vuex)

//准备actions——用于响应组件中的动作
const actions = {
	/* jia(context,value){
		console.log('actions中的jia被调用了')
		context.commit('JIA',value)
	},
	jian(context,value){
		console.log('actions中的jian被调用了')
		context.commit('JIAN',value)
	}, */
	jiaOdd(context,value){
		console.log('actions中的jiaOdd被调用了')
		if(context.state.sum % 2){
			context.commit('JIA',value)
		}
	},
	jiaWait(context,value){
		console.log('actions中的jiaWait被调用了')
		setTimeout(()=>{
			context.commit('JIA',value)
		},500)
	}
}
//准备mutations——用于操作数据(state)
const mutations = {
	JIA(state,value){
		console.log('mutations中的JIA被调用了')
		state.sum += value
	},
	JIAN(state,value){
		console.log('mutations中的JIAN被调用了')
		state.sum -= value
	}
}
//准备state——用于存储数据
const state = {
	sum:0 //当前的和
}

//创建并暴露store
export default new Vuex.Store({
	actions,
	mutations,
	state,
})

main.js

//创建vm
new Vue({
	el:'#app',
	render: h => h(App),
	store,
	beforeCreate() {
		Vue.prototype.$bus = this
	}
})

组件使用(原始)

	<h1>当前求和为:{{$store.state.sum}}</h1>
	methods: {
			increment(){
				this.$store.commit('JIA',this.n)
			},
			decrement(){
				this.$store.commit('JIAN',this.n)
			},
			incrementOdd(){
				this.$store.dispatch('jiaOdd',this.n)
			},
			incrementWait(){
				this.$store.dispatch('jiaWait',this.n)
			},
		}

组件使用(map)

computed:{
			//靠程序员自己亲自去写计算属性
			/* sum(){
				return this.$store.state.sum
			},
			school(){
				return this.$store.state.school
			},
			subject(){
				return this.$store.state.subject
			}, */

			//借助mapState生成计算属性,从state中读取数据。(对象写法)
			// ...mapState({he:'sum',xuexiao:'school',xueke:'subject'}),

			//借助mapState生成计算属性,从state中读取数据。(数组写法)
			...mapState(['sum','school','subject']),

			/* ******************************************************************** */

			/* bigSum(){
				return this.$store.getters.bigSum
			}, */

			//借助mapGetters生成计算属性,从getters中读取数据。(对象写法)
			// ...mapGetters({bigSum:'bigSum'})
			
			//借助mapGetters生成计算属性,从getters中读取数据。(数组写法)
			...mapGetters(['bigSum'])

		},
		methods: {
			increment(){
				this.$store.commit('JIA',this.n)
			},
			decrement(){
				this.$store.commit('JIAN',this.n)
			},
			incrementOdd(){
				this.$store.dispatch('jiaOdd',this.n)
			},
			incrementWait(){
				this.$store.dispatch('jiaWait',this.n)
			},
		}
  • 模块化+命名空间
  • 将四个对象分别定义在不同js文件中 再统一引入在Vuex.store()配置对象的modules属性
  • 注意在不同js文件中需要加入namespaced属性(开启命名空间)
  • 使用的时候在原先的数组前再加一个为模块名即可

index.js
在这里插入图片描述
person.js
在这里插入图片描述

store/index.js

//该文件用于创建Vuex中最为核心的store
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
import countOptions from './count'
import personOptions from './person'
//应用Vuex插件
Vue.use(Vuex)

//创建并暴露store
export default new Vuex.Store({
	modules:{
		countAbout:countOptions,
		personAbout:personOptions
	}
})

组件内使用
1)原始形式

computed:{
			personList(){
				return this.$store.state.personAbout.personList
			},
			sum(){
				return this.$store.state.countAbout.sum
			},
			firstPersonName(){
				return this.$store.getters['personAbout/firstPersonName']
			}
		},
		methods: {
			add(){
				const personObj = {id:nanoid(),name:this.name}
				this.$store.commit('personAbout/ADD_PERSON',personObj)
				this.name = ''
			},
			addWang(){
				const personObj = {id:nanoid(),name:this.name}
				this.$store.dispatch('personAbout/addPersonWang',personObj)
				this.name = ''
			},
			addPersonServer(){
				this.$store.dispatch('personAbout/addPersonServer')
			}
		},

2)简化形式

computed:{
			//借助mapState生成计算属性,从state中读取数据。(数组写法)
			...mapState('countAbout',['sum','school','subject']),
			...mapState('personAbout',['personList']),
			//借助mapGetters生成计算属性,从getters中读取数据。(数组写法)
			...mapGetters('countAbout',['bigSum'])
		},
		methods: {
			//借助mapMutations生成对应的方法,方法中会调用commit去联系mutations(对象写法)
			...mapMutations('countAbout',{increment:'JIA',decrement:'JIAN'}),
			//借助mapActions生成对应的方法,方法中会调用dispatch去联系actions(对象写法)
			...mapActions('countAbout',{incrementOdd:'jiaOdd',incrementWait:'jiaWait'})
		},

27.自定义事件

  • 实现子组件给父组件传递数据
  • 父组件(接收数据)
    • 子组件标签中
      • fnName=“fatherFn”
      • v-on:fnName=“fatherFn”
      • 通过$ refs.xxx.$ on(fnName, fatherFn);
        • fatherFn为methods里的函数
        • 或者为箭头函数
    • 定义fatherFn函数
      • 参数 : 为传递过来的数据
  • 子组件(发送数据)
    • this.$emit(“sonfn”,params)
    • this.$off()
      • 解绑自定义事件
      • 参数:
      • 字符串(“sonfn”)
      • 数组(多个自定义事件的名字)
      • 不传 解绑所有
    • this.$destroy
      • 销毁组件的实例 之后自定义事件 也不奏效了

接受数据的组件
1)

<template>
	<div class="app">
		<h1>{{msg}},学生姓名是:{{studentName}}</h1>

		<!-- 通过父组件给子组件传递函数类型的props实现:子给父传递数据 -->
		<School :getSchoolName="getSchoolName"/>

		<!-- 通过父组件给子组件绑定一个自定义事件实现:子给父传递数据(第一种写法,使用@或v-on) -->
		<Student @atguigu="getStudentName" @demo="m1"/>

		<!-- 通过父组件给子组件绑定一个自定义事件实现:子给父传递数据(第二种写法,使用ref) -->
		<Student ref="student" @click.native="show"/>
	</div>
</template>
mounted(){
   this.$refs.xxx.$on('atguigu',this.test)
}

2)

getSchoolName(name){
				console.log('App收到了学校名:',name)
			},
			getStudentName(name,...params){
				console.log('App收到了学生名:',name,params)
				this.studentName = name
			},

发送数据的组件

<template>
	<div class="student">
		<button @click="sendStudentlName">把学生名给App</button>
		<button @click="unbind">解绑atguigu事件</button>
		<button @click="death">销毁当前Student组件的实例(vc)</button>
	</div>
</template>
methods: {
			sendStudentlName(){
				//触发Student组件实例身上的atguigu事件
				this.$emit('atguigu',this.name,666,888,900)
				// this.$emit('demo')
				// this.$emit('click')
			},
			unbind(){
				this.$off('atguigu') //解绑一个自定义事件
				// this.$off(['atguigu','demo']) //解绑多个自定义事件
				// this.$off() //解绑所有的自定义事件
			},
			death(){
				this.$destroy() //销毁了当前Student组件的实例,销毁后所有Student实例的自定义事件全都不奏效。
			}
		},

28. 全局事件总线

  • 任意组件间通信
  • main.js
    • beforecreate里面再Vue原型上创建$bus (vm)
  • 组件(接收数据)
    • mounted钩子 this.$ bus.$ on("name, 回调)
    • beforeDestroy钩子中 $off
  • 组件(发送数据)
    • this.$ bus.$ emit(“name”, params)

main.js

//创建vm
new Vue({
	el:'#app',
	render: h => h(App),
	beforeCreate() {
		Vue.prototype.$bus = this //安装全局事件总线
	},
})

接受数据的组件

mounted() {
			// console.log('School',this)
			this.$bus.$on('hello',(data)=>{
				console.log('我是School组件,收到了数据',data)
			})
		},
		beforeDestroy() {
			this.$bus.$off('hello')
		},

发送数据的组件

	methods: {
			sendStudentName(){
				this.$bus.$emit('hello',this.name)
			}
		},

29. 消息订阅与发布

  • 任意组件间通信
  • 下载:npm i pubsub-js
    引入: import pubsub from ‘pubsub-js’
  • 组件(接收数据)
    • mouted钩子中 this.pubId = pubsub.subscribe("name, parmas)
    • beforeDestroy钩子 pubsub.unsubscribe(this.pubId)
  • 组件(发送数据)
    • pubsub.publish("name, fn)

接受数据的组件

	mounted() {
			// console.log('School',this)
			/* this.$bus.$on('hello',(data)=>{
				console.log('我是School组件,收到了数据',data)
			}) */
			this.pubId = pubsub.subscribe('hello',(msgName,data)=>{
				console.log(this)
				// console.log('有人发布了hello消息,hello消息的回调执行了',msgName,data)
			})
		},
		beforeDestroy() {
			// this.$bus.$off('hello')
			pubsub.unsubscribe(this.pubId)
		},

发送数据的组件

methods: {
			sendStudentName(){
				// this.$bus.$emit('hello',this.name)
				pubsub.publish('hello',666)
			}
		},

阶段性总结3

  • ref

    属性

    • 标签
    • 获取
  • props

    属性

    • 组件标签传递
    • 子组件中props属性获取
  • mixin

    混入

    • mixin.js定义export
    • import mixins属性 引入
  • plugin

    插件

    • plugin.js
    • 引入Vue.use
  • 自定义事件

    @
    `
    
    - 接收数据组件
    - 发送数据组件
    
    
  • 全局事件总线

    $bus

    • main.js
    • 接收数据组件
    • 发送数据组件
  • 消息订阅与发布

    pubsub

    • 下载引入
    • 接受数据组件
    • 发送数据组件

nextTick函数

  • 下一次更新DOM结束后调用该回调函数
  • 参数:回调函数

30. vue的过渡和动画

  • 单个元素
    • transition标签包含动画标签 指定name属性
    • 指定.xx-enter-active xx-leave-active 样式的animation属性( transition)
    • 设定选择器keyframe
  • 多个元素
    • transition-group标签包含动画标签 指定name属性
    • 指定类名的animation或者transition属性
  • 引入animate.css
    • 为transition标签指定 name enter-active-class leave-active-class即可

单个元素

<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 atguigu {
		from{
			transform: translateX(-100%);
		}
		to{
			transform: translateX(0px);
		}
	}
</style>

多个元素

<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-leave-to{
		transform: translateX(-100%);
	}
	.hello-enter-active,.hello-leave-active{
		transition: 0.5s linear;
	}
	/* 进入的终点、离开的起点 */
	.hello-enter-to,.hello-leave{
		transform: translateX(0);
	}

</style>

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'
	export default {
		name:'Test',
		data() {
			return {
				isShow:true
			}
		},
	}
</script>

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

</style>

配置代理服务器

  • 解决请求跨域问题(开启代理服务器进行请求 改变请求路径)
  • vue.config.js(devServer对象的proxy属性)
    • proxy属性为字符串
      • 代理一个
    • proxy属性为对象
      • 对象下的属性名:请求路径头(端口后的路径)
      • 值:对象(target pathRewrite changeOrigin属性)

vue.config.js

module.exports = {
  pages: {
    index: {
      //入口
      entry: 'src/main.js',
    },
  },
	lintOnSave:false, //关闭语法检查
	//开启代理服务器(方式一)
	/* devServer: {
    proxy: 'http://localhost:5000'
  }, */
	//开启代理服务器(方式二)
	devServer: {
    proxy: {
      '/atguigu': {
        target: 'http://localhost:5000',
				pathRewrite:{'^/atguigu':''},
        // ws: true, //用于支持websocket
        // changeOrigin: true //用于控制请求头中的host值
      },
      '/demo': {
        target: 'http://localhost:5001',
				pathRewrite:{'^/demo':''},
        // ws: true, //用于支持websocket
        // changeOrigin: true //用于控制请求头中的host值
      }
    }
  }
}

代理细节补充

31. vue路由

  • main.js
    • 引入vue-route(npm的时候要指定安装VueRouter@3 否则不兼容vue2 --> 使用插件应用
      Vue.use(VueRouter);
    • 引入router( route/index.js ) -->作为创建Vue实例的配置对象的属性
  • router / index.js
    • 引入vue-route
    • export vueRouter实例
      • 创建实例时传配置对象(routes属性 是一个数组 放着一个个对象 又包含着name path component children)
  • 组件使用
    • router-link标签
      • 类比a标签
      • to属性:跳转的页面路径
      • active
    • router-view标签
      • 组件显示的位置
        main.js
//引入VueRouter
import VueRouter from 'vue-router'
//引入路由器
import router from './router'
Vue.use(VueRouter)

//创建vm
new Vue({
	el:'#app',
	render: h => h(App),
	router:router
})

router/index.js

// 该文件专门用于创建整个应用的路由器
import VueRouter from 'vue-router'
//引入组件
import About from '../components/About'
import Home from '../components/Home'

//创建并暴露一个路由器
export default new VueRouter({
	routes:[
		{
			path:'/about',
			component:About
		},
		{
			path:'/home',
			component:Home
		}
	]
})

组件

<!-- Vue中借助router-link标签实现路由的切换 -->
<router-link class="list-group-item"  active-class="active" to="/about">About</router-link>
<router-link class="list-group-item" active-class="active" to="/home">Home</router-link>

1)多级路由

  • children属性(对象数组)
  • 特殊点
    • 只有一级路由path有/ 其余path属性不包含
    • 跳转二级路由 to属性要加上一级路由

一级路由

<li>
	<router-link class="list-group-item" active-class="active" to="/home/news">News</router-link>
</li>

route/index.js

//创建并暴露一个路由器
export default new VueRouter({
	routes:[
		{
			path:'/about',
			component:About
		},
		{
			path:'/home',
			component:Home,
			children:[
				{
					path:'news',
					component:News,
				},
				{
					path:'message',
					component:Message,
				}
			]
		}
	]
})

2)query参数

  • to属性(前面加冒号 引号才能为js表达式)
    • 字符串写法 :to = “ xxxxxx”(引号里面还有反引号)
    • 对象写法 引号里面为对象
      • 对象属性有:path query对象
  • 使用 vm.$router.query.xx
    • 模板里面就省略vm.啦
    • 实例配置对象里面vm为this
<!-- 跳转路由并携带query参数,to的字符串写法 -->
	<!-- <router-link :to="`/home/message/detail?id=${m.id}&title=${m.title}`">{{m.title}}</router-link>&nbsp;&nbsp; -->

	<!-- 跳转路由并携带query参数,to的对象写法 -->
	<router-link :to="{
		path:'/home/message/detail',
		query:{
			id:m.id,
			title:m.title
		}
	}">
<template>
	<ul>
		<li>消息编号:{{$route.query.id}}</li>
		<li>消息标题:{{$route.query.title}}</li>
	</ul>
</template>

<script>
	export default {
		name:'Detail',
		mounted() {
			console.log(this.$route)
		},
	}
</script>

3)命名路由

  • 创建vueRouter实例的配置对象 里面的name属性来命名
  • 在query参数的to的对象写法 就可以将path替换为name(更方便)
<!-- 跳转路由并携带query参数,to的对象写法 -->
				<router-link :to="{
					name:'xiangqing',
					query:{
						id:m.id,
						title:m.title
					}
				}">

4)params参数

  • 跳转路由并携带参数
  • to两种写法
    • 字符串写法 直接在路径后面添加 参数之间通过/隔开
    • 对象写法 name属性(不能用path)和params属性(对象)
  • 创建vueRouter实例配置对象需要在path进行占位
  • 组件使用
    • vm.$router.params.xx
{
					path:'message',
					component:Message,
					children:[
						{
							name:'xiangqing',
							//占位
							path:'detail/:id/:title',
							component:Detail,
						}
					]
				}
	<!-- 跳转路由并携带params参数,to的字符串写法 -->
				<!-- <router-link :to="`/home/message/detail/${m.id}/${m.title}`">{{m.title}}</router-link>&nbsp;&nbsp; -->

				<!-- 跳转路由并携带params参数,to的对象写法 -->
				<router-link :to="{
					name:'xiangqing',
					params:{
						id:m.id,
						title:m.title
					}
				}">

组件使用

<template>
	<ul>
		<li>消息编号:{{$route.params.id}}</li>
		<li>消息标题:{{$route.params.title}}</li>
	</ul>
</template>

<script>
	export default {
		name:'Detail',
		mounted() {
			// console.log(this.$route)
		},
	}
</script>

不同:
query参数类似get请求 地址栏会显示
params参数类似post请求 地址栏不会显示

5) 路由中的props属性

  • 更方便使用query参数和params参数 (简写 没有那么多的前缀)
  • 创建vueRouter实例的配置对象中设置props属性
    • 对象(其中key-value就会以props形式传递给组件)
    • 布尔值 (params参数~)
    • 函数
      • 参数为$router 这样就可以获取到id和params
//用props属性则可以直接用 this.id取值,而可以不用 this.$route.params.id 取值
							
							//props的第一种写法,值为对象,该对象中的所有key-value都会以props的形式传给Detail组件。
							// props:{a:1,b:'hello'}

							//props的第二种写法,值为布尔值,若布尔值为真,就会把该路由组件收到的所有params参数,以props的形式传给Detail组件。
							// props:true

							//props的第三种写法,值为函数
							props($route){
								return {
									id:$route.query.id,
									title:$route.query.title,
									a:1,
									b:'hello'
								}
							}

组件使用:

<template>
	<ul>
		<li>消息编号:{{id}}</li>
		<li>消息标题:{{title}}</li>
	</ul>
</template>

<script>
	export default {
		name:'Detail',
		props:['id','title'],
		computed: {
			// id(){
			// 	return this.$route.query.id
			// },
			// title(){
			// 	return this.$route.query.title
			// },
		},
		mounted() {
			// console.log(this.$route)
		},
	}
</script>

6)router-link标签的replace属性

  • 历史记录有两种模式
    • 两种模式回退上一个页面都是从栈顶取对应地址
    • push模式 进栈
    • replace模式 不如栈(直接替换) 此种情况在下次跳转其他页面就回不到这个路由了(还是栈顶)

7)编程式路由导航

  • 替代router-link标签
  • 利用vm.$router下的push方法 和 replace方法
methods: {
			pushShow(m){
				this.$router.push({
					name:'xiangqing',
					query:{
						id:m.id,
						title:m.title
					}
				})
			},
			replaceShow(m){
				this.$router.replace({
					name:'xiangqing',
					query:{
						id:m.id,
						title:m.title
					}
				})
			}
		},

8) 缓存组件

  • 不让组件销毁 保持挂载状态
  • 在router-link标签外面套一个keep-alive标签
    • keep-alive标签中指定include属性
    • include属性:
      • 字符串:指定一个
      • 数组:指定多个
<!-- 缓存多个路由组件 -->
<!-- <keep-alive :include="['News','Message']"> -->
	
<!-- 缓存一个路由组件 -->
<keep-alive include="News">
	<router-view></router-view>
</keep-alive>

9)两个生命周期钩子

  • 作用:路由组件所独有的两个钩子,用于捕获路由组件的激活状态。
  • 具体名字:
    • activated路由组件被激活时触发。
    • deactivated路由组件失活时触发。

10) 全局路由守卫

  • 在router/index.js中添加两个方法
  • router.beforeEach
    • 每次路由切换之前会被调用(身份验证功能等…)
    • 参数:to from next(放行)
  • router.afterEach()
    • 每次路由切换之后执行
    • 修改title等
  • router为创建实例返回的变量
//全局前置路由守卫————初始化的时候被调用、每次路由切换之前被调用
router.beforeEach((to,from,next)=>{
	console.log('前置路由守卫',to,from)
	if(to.meta.isAuth){ //判断是否需要鉴权
		if(localStorage.getItem('school')==='atguigu'){
			next()
		}else{
			alert('学校名不对,无权限查看!')
		}
	}else{
		next()
	}
})

//全局后置路由守卫————初始化的时候被调用、每次路由切换之后被调用
router.afterEach((to,from)=>{
	console.log('后置路由守卫',to,from)
	document.title = to.meta.title || '硅谷系统'
})

export default router

11)独享路由守卫

  • router/index.js
  • 在配置对象添加beforeEnter属性指定
  • 可以在每个组件中都添加mata属性
    • 存放一些信息
    • 比如用来判断是否可以授权通过token
//创建并暴露一个路由器
const router =  new VueRouter({
	routes:[
		{
			name:'guanyu',
			path:'/about',
			component:About,
			meta:{title:'关于'}
		},
		{
			name:'zhuye',
			path:'/home',
			component:Home,
			meta:{title:'主页'},
			children:[
				{
					name:'xinwen',
					path:'news',
					component:News,
					meta:{isAuth:true,title:'新闻'},
					beforeEnter: (to, from, next) => {
						console.log('独享路由守卫',to,from)
						if(to.meta.isAuth){ //判断是否需要鉴权
							if(localStorage.getItem('school')==='atguigu'){
								next()
							}else{
								alert('学校名不对,无权限查看!')
							}
						}else{
							next()
						}
					}
				},
				{
					name:'xiaoxi',
					path:'message',
					component:Message,
					meta:{isAuth:true,title:'消息'},
				}
			]
		}
	]
})

12)组件守卫

  • 在组件配置对象添加两个函数
  • beforeRouteEnter(to, from ,next)
    • 进入该组件时调用
  • beforeRouteLeave(to, from, next)
    • 离开该组件时调用
//通过路由规则,进入该组件时被调用
		beforeRouteEnter (to, from, next) {
			console.log('About--beforeRouteEnter',to,from)
			if(to.meta.isAuth){ //判断是否需要鉴权
				if(localStorage.getItem('school')==='atguigu'){
					next()
				}else{
					alert('学校名不对,无权限查看!')
				}
			}else{
				next()
			}
		},

		//通过路由规则,离开该组件时被调用
		beforeRouteLeave (to, from, next) {
			console.log('About--beforeRouteLeave',to,from)
			next()
		}

13)history

14)element-ui

  • 引入
//完整引入
//引入ElementUI组件库
// import ElementUI from 'element-ui';
//引入ElementUI全部样式
// import 'element-ui/lib/theme-chalk/index.css';

//按需引入
import { Button,Row,DatePicker } from 'element-ui';

//关闭Vue的生产提示
Vue.config.productionTip = false

//应用ElementUI
// Vue.use(ElementUI);
Vue.component('atguigu-button', Button);
Vue.component('atguigu-row', Row);
Vue.component('atguigu-date-picker', DatePicker);
  • 使用
<template>
  <div>
		<button>原生的按钮</button>
		<input type="text">
		<atguigu-row>
			<el-button>默认按钮</el-button>
			<el-button type="primary">主要按钮</el-button>
			<el-button type="success">成功按钮</el-button>
			<el-button type="info">信息按钮</el-button>
			<el-button type="warning">警告按钮</el-button>
			<el-button type="danger">危险按钮</el-button>
		</atguigu-row>
		<atguigu-date-picker
      type="date"
      placeholder="选择日期">
    </atguigu-date-picker>
		<atguigu-row>
			<el-button icon="el-icon-search" circle></el-button>
			<el-button type="primary" icon="el-icon-s-check" circle></el-button>
			<el-button type="success" icon="el-icon-check" circle></el-button>
			<el-button type="info" icon="el-icon-message" circle></el-button>
			<el-button type="warning" icon="el-icon-star-off" circle></el-button>
			<el-button type="danger" icon="el-icon-delete" circle></el-button>
		</atguigu-row>
  </div>
</template>

<script>
	export default {
		name:'App',
	}
</script>

阶段性总结4

  • nextTick
    
    • 下一次更新DOM值周调用
  • 过渡与动画

    • 一个元素 transition标签配置name属性 设置css样式

    • 多个元素 transition-group标签包裹 name属性 设置css样式 (六种 有重合)

    • animate.css
      
      • import引入
      • 设置对应的name class属性
  • 路由

    • 基本使用

      • 引入路由器 创建路由 使用
    • 嵌套路由

      • children属性
      • to属性
      • path属性
    • query
      

      参数

      • to属性的两种方式
      • 使用 $router下的query属性
    • 命名路由

      • query to的第二种写法取代path属性
    • params
      

      参数

      • 路由中要占位
      • to的两种写法
      • 只能用name 不能用path
    • props
      

      属性

      • 更方便使用参数
      • 路由中指定的三种方式
    • router-link 的

      replace
      

      属性

      • 历史记录的回退
    • 编程式路由

      • vm.$router下的push和replace方法
    • 两个生命钩子

    • 全局路由守卫

      • 在router/index.js中 router.beforeEach()router.afterEach()
    • 独享路由守卫

      • 在分别路由配置中 beforeEnter属性配置
    • 组件内路由守卫

      • 组件中配置beforeRouterEnter()beforeRouterLeave()
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值