【vue2.0-脚手架】

目录

    • 创建脚手架
    • 修改默认配置
    • ref属性
    • props配置
    • minx混入(合)
    • 插件
    • scoped
    • 组件化编码流程(通用)
    • 浏览器本地存储
    • 通信
      • 兄弟传值=全局事件总线
      • 子传父
      • 父传子
      • 全局事件总线
    • 消息订阅与发布
    • $nextTick
    • 过渡动画
      • 多个元素过渡
      • 动画插件
    • 配置代理
    • vue-resource
    • 插槽
      • 默认插槽
      • 具名插槽
      • 作用域插槽
    • vuex
      • mapState和mapGetters
      • mapActions和mapMutations
      • 模块化
    • 路由
      • 路由的使用
        • router-link的其他配置
      • 嵌套路由
      • 路由参数
        • query
        • params
      • 命名路由
      • props配置
      • 编程式路由导航
      • 缓存路由组件
      • 两个新的声明周期钩子
      • 路由守卫
        • 全局前置
        • 全局后置
        • 独享路由
        • 组件内路由守卫
      • history模式和hash模式
      • keep-alive
      • 组件引入(动态组件写法)

创建脚手架

vue create 项目名称

修改默认配置

//vue.config.js
modules.exports = {
	pages:{
		index:{
			//入口
			entry:'/src/main.js'
		},
	},
	lintOnSave:false,//关闭语法
}

更多修改默认配置:https://cli.vuejs.org/zh/config/

ref属性

被用来给元素或子组件注册引用信息(id的替代者)
引用的html标签上虎丘的是真实DOM元素,应用在组件标签上是组件实例对象(vc)

<div v-ref="b1">div>
console.log(this.refs.b1)

props配置

//父组件
<Student  :name="name"/>
data(){
	return{
		name:'张三'
	}
}
//子组件
<div>{{name}}</div>
props:['name']//简单接收
props:{
	name:'String'
}
props:{
	name:{
		type:'String',
		required:true,//必要的
		default:'李四',//默认值
	}
}

场景需求:如果想要修改props里面的值,做法如下:
props的优先级比data的优先级高

//父组件
<Student  :age="age"/>
data(){
	return{
		age:18
	}
}
//子组件
<div>{{age}}</div>
props:['age'],//简单接收
data(){
	return{
		myage:this.age
	}
},
methods:{
	addage(){
		this.myage++
	}
}

功能:让组件接收外部传过来的数据
备注:props是只读的,vue底层会检测你对props的修改。如果进行了修改,就会发出警告,若业务需求需要修改,那么请赋值props的内容到data中一份。然后去修改data中的数据
props适用于:父传子+子传父(要求父先给子一个函数)

minx混入(合)

功能:可以把多个组件共有的配置提取成一个混入对象

【vue2.0-脚手架】_第1张图片
【vue2.0-脚手架】_第2张图片
用处一:假设父组件和子组件公用一个接口请求数据
官方推荐Minxin应该用于插件开发,不建议应用使用
【vue2.0-脚手架】_第3张图片

插件

功能:用于挣钱vue
本质:包含install方法的一个对象,install的第一个参数是vue,第二个以后的参数是插件使用者传递的数据
【vue2.0-脚手架】_第4张图片
【vue2.0-脚手架】_第5张图片
【vue2.0-脚手架】_第6张图片

scoped


app.vue 不适用
作用:让样式在局部生效,防止冲突

组件化编码流程(通用)

  1. 拆分静态组件:组件要按照功能点拆分,命名不要与html元素冲突
  2. 实现动态组件:考虑好数据的存放位置,数据是一个组件再用,还是一些组件再用:
    1. 一个组件再用:放在组件自身即可
    2. 一些组件再用:放在他们共同的父组件上(状态提升)
  3. 实现交互:从绑定事件开始

使用v-model时要切记:v-model绑定的值不能是props传过来的值,因为props是不可以修改的
props传过来的若是对象类型的值,修改对象中的属性时vue不会报错,但不推荐这样做

浏览器本地存储

两者统称为webStorage

//localStorage:本地存储
//保存
let p = {name:'jery'}
localStorage.setItem('person',JSON.stringify(p))
//读取
//如果要是读取的值获取不到则返回null
localStorage.getItem('person')
//删除
localStorage.removeItem('person')
//清空
localStorage.clear()
//localStorage特点:关闭浏览器不会清除数据-用户点击按钮清除会清除数据/清除缓存也会清除数据

//sessionStorage:会话存储
//保存
let p = {name:'jery'}
sessionStorage.setItem('person',JSON.stringify(p))
//读取
//如果要是读取的值没有则返回null
sessionStorage.getItem('person')
//删除
sessionStorage.removeItem('person')
//清空
sessionStorage.clear()
//sessionStorage特点:关闭浏览器会清除数据

通信

兄弟传值=全局事件总线

数据在哪里,操作的数据方法就在哪里

  1. 把用的值放在app.vue下面通过vue去传给需要用的子级(data和方法都可以传)
    【vue2.0-脚手架】_第7张图片
    【vue2.0-脚手架】_第8张图片

子传父

  1. props(父组件要先给子组件一个函数)
//父组件
<school :getSchoolName="getSchoolName"/>
getSchoolName(name){
	console.log('父组件收到',name)
}
//子组件
props:['getSchoolName']
getname(value){
	this.getSchoolName(value)
}
  1. 通过父组件给子组件绑定一个自定义事件实现(@/v-on:)
//父组件
//点击触发
<school @getName="getSchoolName"/>
//只能点击一次
<school @getName.once="getSchoolName"/>
getSchoolName(name){
	console.log('父组件收到',name)
}
//子组件
<div @click="getbutton">name</div>
data(){
	return{
		name:''
	}
}
getbutton(){
	this.$emit('getName',this.name)
}
  1. 通过父组件给子组件绑定一个自定义事件实现 (ref)——灵活性强
//父组件
<school ref="student"/>
methods:{
	getschoolname(){
	}
},
mounted(){
	//点击触发
	this.$refs.student.$on('getname',this.getschoolname)
	//只能点击一次
	this.$refs.student.$once('getname',this.getschoolname)
	this.$refs.student.$once('getname',((name)=>{
		this.searchname = name
	}))//必须写箭头函数
}
//子组件
<div @click="getbutton">name</div>
data(){
	return{
		name:''
	}
}
getbutton(){
	this.$emit('getschoolname',this.name)
}

解绑事件:给谁绑定就去谁那解绑

//子组件
unbind(){
	this.$off('getschoolname')//解绑一个自定义事件
	this.$off(['getschoolname','第二个'])//解绑多个自定义事件
	this.$off()//解绑所有自定义事件
}
death(){
	this.$destroy()//销毁了当前student组件的实例,销毁后所有student的自定义事件全部不奏效
}

父传子

props

//父组件
<school :getname="getname"/>
//子组件
props:[getname]

全局事件总线

任意组件间通信

//main.js
new Vue({
	el:'#app',
	render:h=>h(App),
	beforeCreate(){
		Vue.prototype.$bus = this //安装全局事件总线,$bus就相当于当前应用的vm
	}
})
//兄弟1
mounted(){
	this.$bus.$on('hello',(data)=>{
		console.log('我是组件1,收到了数据',data)
	})
},
beforeDestroy(){
	this.$bus.$off('hello')
}
//兄弟2
methods:{
	send(){
		this.$bus.$emit('hello',666)
	}
}

最好在beforeDestroy钩子中,用$off去解绑当前组件所用到的事件

消息订阅与发布

一种组件间通信的方式,适用于任意组件间通信

  1. 安装: npm i pubsub-js
  2. 使用:
//收数据的人
import pubsub from 'pubsub-js'
mounted(){
	this.pubId = pubsub.subscribe('hello',(消息名称,传的数据)=>{
		console.log('有人发布了消息')
	})
}
//如果不用参数可以用_占位
beforeDestroy(){
	pubsub.unsubscribe(this.pubId)
}
//传数据的
import pubsub from 'pubsub-js'
methods:{
	send(){
		pubsub.publish('hello',666)
	}
}

$nextTick

  1. 语法:this.$nextTick(回调函数)
  2. 作用:在下一次DOM更新结束后执行其指定的回调
  3. 什么时候用:当改变数据后,要基于更新后的新DOM进行某些操作时,要在nextTick所指定的回调函数中执行

过渡动画

作用:在插入、更新或移除dom元素时,在合适的时候给元素添加样式类名

【vue2.0-脚手架】_第9张图片

<transition name="hello" appear>
	<h1 v-show="isShow">h1>
transition>
//第一种写法
.hello-enter-active{
	animation:atguigu .5s liner
}
.hello-leave-active{
	animation:atguigu .5s liner reverse
}
@keyframes atguigu{
 from{
	transform:translateX(-100%)
	}
	to{
		transform:translateX(0px)
	}
}
//第二种写法
.hello-enter{
	transform:translateX(-100%)
}//进入的起点
.hello-enter-to{
	transform:translateX(0)
}//进入的终点
.hello-leave-active,.hello-enter-active{
	transiton:.5s liner;
}
.hello-leave{
	transform:translateX(0)
}//离开的起点
.hello-leave-to{
	transform:translateX(-100%)
}//离开的终点

多个元素过渡

transition标签内部只能有一个元素
如果多个元素过渡transition-group
需要注意的是transition-group里面的每一个元素都需要有一个key值

<transition-group>
	<div key="1">div>
	<div key="2">div>
transition-group>

动画插件

animate.css
https://animate.style/

import 'animate.css'

【vue2.0-脚手架】_第10张图片

//animate__shakeY这个是复制过来的
<transition-group 
	name="animate__animated animate__bounce" 
	enter-active-class="animate__shakeY" 
	leave-active-class="animate__headShake">
transition-group>

【vue2.0-脚手架】_第11张图片

配置代理

【vue2.0-脚手架】_第12张图片

【vue2.0-脚手架】_第13张图片

【vue2.0-脚手架】_第14张图片
在这里插入图片描述

如果引入的第三方插件里面有没有用到的东西就不能用import引入 因为import是严格检查 直接在index.html里面引入即可

【vue2.0-脚手架】_第15张图片

vue-resource

了解即可vue1.0的时候用的多

  1. 安装 npm i vue-resource
  2. 使用
    【vue2.0-脚手架】_第16张图片
    【vue2.0-脚手架】_第17张图片

插槽

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

默认插槽

【vue2.0-脚手架】_第18张图片
【vue2.0-脚手架】_第19张图片
【vue2.0-脚手架】_第20张图片
【vue2.0-脚手架】_第21张图片

具名插槽

【vue2.0-脚手架】_第22张图片
【vue2.0-脚手架】_第23张图片
【vue2.0-脚手架】_第24张图片

作用域插槽

理解:数据在组件的自身,但根据数据生成的结构需要组件的使用者来决定

【vue2.0-脚手架】_第25张图片
【vue2.0-脚手架】_第26张图片
简写:结构赋值
【vue2.0-脚手架】_第27张图片
slot-scope=“{game}”

vuex

【vue2.0-脚手架】_第28张图片

概念:专门在vue中实现集中式状态(数据)管理的一个vue插件,对vue应用中多个组件的共享状态进行集中式的管理(读/写),也是一种组件间通信的方式,且适用于任意组件间通信
什么时候用vuex:

  1. 多个组件依赖同一个状态
  2. 来自不同组件的行为需要变更同一个状态

版本:

  1. vue2中要用vuex3版本
  2. vue3中要用vuex4版本
  • 下载:npm i vuex
  • 使用
//main.js
import Vue from 'vue'
import store from './store/index'
new Vue({
	store
})
//index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const actions = {//做业务逻辑处理
	jisOdd(context,value){
		if(context.state.sum%2){
			context.comit('JIA',value)
		}
	}
}
const mutations = {//直接根开发者工具交流
//如果无业务逻辑可以直接写在mutations里面
	JIA(state,value){
		state.sum+=value
	}
}
const state = {
	sum:0
}
const getter = {//对state修改---类似计算属性
	bigsum(state){
		return state.sum*10
	}
	//获取this.$store.getters.bigsum
}
export default new Vuex.store({
	actions,
	mutations,
	state ,
	getter 
})
//用的组件
data:{
	return(){
		n:1
	}
}
methods:{
	jia(){
		this.$store.commit('jia',this.n)
		//commit---mutations 
	},
	jisOdd(){
		this.$store.dispatch('jisOdd',this.n)
		//dispatch----actions 
	}
}

mapState和mapGetters

//mapGetters写法和mapState同样

import {mapState,mapGetters} from 'vuex'
computed:{
	...mapState({sum:'sum'})//借助mapstate生成计算属性,从state中读取数据(对象写法)
	...mapState(['sum']})//(数组写法)
}
<div>{{sum}}=={{$store.state.sum}}div>

mapActions和mapMutations

//mapActions与mapMutations写法一样

import {mapActions,mapMutations} from 'vuex'
methods:{
	...mapMutations({increment:'JIA'})//借助mapMutations生成对应的方法,方法中会调用commit去练习mutations(对象写法)
	...mapMutations(['JIA']})//(数组写法)
}
<div @click="increment(n)">对象写法div>
<div @click="JIA(n)">数组写法div>

模块化

//index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)

const countOptions = {
	namespaced:true,//写这个属性可以在mapstate里面写成以下
	//格式:...mapState('countAbout',['sum','school','subject'])
	actions : {//做业务逻辑处理
		jisOdd(context,value){
			if(context.state.sum%2){
				context.comit('JIA',value)
			}
		}
	}
	mutations : {//直接根开发者工具交流
	//如果无业务逻辑可以直接写在mutations里面
		JIA(state,value){
			state.sum+=value
		}
	}
	state : {
		sum:0
	}
	getter : {//对state修改---类似计算属性
		bigsum(state){
			return state.sum*10
		}
		//获取this.$store.getters.bigsum
	}
}
const person = {
	namespaced:true,
	state:{},
	mutations:{
		ADD_PERSON(state,value){
			state.personList.unshift(value)
		}
	},
	actions:{
		addPersonWang(context,value){
			if(value.name.indexOf('王')===0){
				context.commit('ADD_PERSON',value)
			}
		}
	},
	state:{
		personList:[]
	},
	getters:{
		firstPersonName(state){
			return state.personList[0].name
		}
	}
}

export default new Vuex.store({
	modules:{
		countAbout:countOptions ,
		personAbout:person 
	}
})
//组件
import {mapState} from 'vuex'
computed:{
	...mapState('countAbout',['sum'])//如果有多个就再写个
	...personAbout('personAbout',['personList'])
	personStateFirst(){
		return this.$store.$getters['personAbout/firstPersonName']
	}
},
methods:{
	...mapMutations('personAbout',{increment:'JIA'})//
	add(){
		this.$store.commit('personAbout/ADD_PERSON',personObj)
	}
	addWang(){
		this.$store.dispatch('personAbout/addPersonWang',personObj)
	}
}
<div>{{sum}}div>
<div>{{personList.length}}div>

【vue2.0-脚手架】_第29张图片
【vue2.0-脚手架】_第30张图片
【vue2.0-脚手架】_第31张图片

路由

  1. vue-router的理解:
    vue的一个插件库,专门用来实现SPA应用
  2. 对SPA应用的理解
    1. 单页Web应用(single page web application,SPA)
    2. 整个应用只有一个完整的页面
    3. 点击页面中的导航链接不会刷新页面,只会做页面的局部更新
    4. 数据需要通过ajax请求获取
  3. 什么是路由
    1. 一个路由就是一组映射关系(key-value)
    2. key为路径,value可能是function或component
  4. 路由分类
    1. 后端路由:
      1. 理解:value是function,用于处理客户端提交的请求
      2. 工作过程:服务器接收到一个请求时,根据请求路径找到匹配的函数来处理请求,返回响应数据
    2. 前端路由:
      1. 理解:value是component,用于展示页面内容
      2. 工作过程:当浏览器的路径改变时,对应的组件就会显示

路由的使用

  1. 安装:npm i vue-router

vue-router默认版本是4只能在vue3中应用
所以用vue2的时候下载vue-router版本应为3

  1. 引入
    【vue2.0-脚手架】_第32张图片
    【vue2.0-脚手架】_第33张图片
  2. 使用
    【vue2.0-脚手架】_第34张图片
  1. 路由组件通常存放在pages文件夹,一般组件通常存放在components文件夹
  2. 通过切换,隐藏了的路由组件,默认是被销毁掉的,需要的时候再去挂载
  3. 每个组件都有自己的$route属性,里面存储着自己的路由信息
  4. 整个应用只有一个router,可以通过组件的$router属性获取到
router-link的其他配置
  1. 作用:控制路由跳转时操作浏览器历史记录模式
  2. 浏览器的历史记录有两种写入方式:分别为push和replace,push是追加历史记录,replace是替换当前记录,路由跳转时候默认为push
  3. 如何开始replace模式
<router-link replace to="">router-link>

嵌套路由

【vue2.0-脚手架】_第35张图片

路由参数

query

【vue2.0-脚手架】_第36张图片

params

【vue2.0-脚手架】_第37张图片
【vue2.0-脚手架】_第38张图片
【vue2.0-脚手架】_第39张图片

命名路由

作用:可以简化路由的跳转

【vue2.0-脚手架】_第40张图片
【vue2.0-脚手架】_第41张图片

props配置

【vue2.0-脚手架】_第42张图片

对象写法:死数据,一般不用
【vue2.0-脚手架】_第43张图片
【vue2.0-脚手架】_第44张图片
第二种方法 只能params query不允许
【vue2.0-脚手架】_第45张图片
【vue2.0-脚手架】_第46张图片
第三种写法
【vue2.0-脚手架】_第47张图片
【vue2.0-脚手架】_第48张图片
【vue2.0-脚手架】_第49张图片

编程式路由导航

作用:不借助router-link实现路由跳转,让路由跳转更加灵活

【vue2.0-脚手架】_第50张图片

缓存路由组件

保留页面的记录

作用:让步暂时的路由组件保持挂载,不被销毁
注意:include写的是组件名的name

在这里插入图片描述
多个写法
在这里插入图片描述

两个新的声明周期钩子

作用:路由组件所独有的两个钩子,用于捕获路由组件的激活状态

  1. activated:路由组件被激活时触发
  2. deactivated路由组件失活时触发

路由守卫

  1. 作用:对路由进行权限控制
  2. 分类:全局守卫、独享守卫、组件内守卫
全局前置

【vue2.0-脚手架】_第51张图片
在这里插入图片描述

全局后置

前置守卫走完之后再走后置
【vue2.0-脚手架】_第52张图片

独享路由

只对一个路由做限制

独享路由只有前置首页
【vue2.0-脚手架】_第53张图片

组件内路由守卫

【vue2.0-脚手架】_第54张图片

history模式和hash模式

  1. 对于一个url来说,什么是hash值——#及后面的内容就是hash值
  2. hash值不会包含在HTTP请求中,即:hash值不会带给服务器
  3. hash模式:
    1. 地址中永远呆着#号,不美观
    2. 若以后将地址通过第三方手机app分享,若app校验严格,则地址会被标记为不合法
    3. 兼容性较好
  4. history模式:
    1. 地址干净、美观。
    2. 兼容性和hash模式相比略差
    3. 应用部署上线时需要后端人员支持,解决刷新页面服务端404问题

keep-alive

酌情使用KeepAlive缓存组件状态过度使用会造成内存泄漏
什么时候使用呢?
默认情况下,一个组件实例在被替换掉后会被销毁。这会导致它丢失其中所有已变化的状态——当这个组件再一次被显示时,会创建一个只带有初始状态的新实例。
也就是说,当你想要切换时,再回到这个页面的时候依然保留切换时的状态(例如分页)的时候使用

<keep-alive>
	<router-view v-if=“$route.meta.keepAlive”>router-view>
keep-alive>

另外KeepAlive还支持配置最大缓存实例数来限制最大可以缓存的组件实例数。 如果缓存实例的数量即将超过指定的最大数量,则最长时间未访问的缓存实例将被销毁,以便为新实例腾出空间。

<KeepAlive :max=“10”>
	<component :is=“activeComponent” />
KeepAlive>

组件引入(动态组件写法)

当if-else逻辑过于复杂时,可以使用动态组件来实现,避免代码臃肿和可读性下降。 使用动态组件可以使代码组织得更清晰,组件重用,避免代码冗余。 这是示例代码:

<template>
	<component :is=“componentName”>component>
template>
import Foo from “./Foo.vue”;
import Bar from “./Bar.vue”;
export default {
	data() {
		return {
			componentName: “”,
		};
	},
	mounted() {
		if (condition) {
			this.componentName = “Foo”;
		} else {
			this.componentName = “Bar”;
		}
	},
	components: {
		Foo,
		Bar,
	},
};

你可能感兴趣的:(#,Vue2.0笔记,javascript,前端,vue.js)