目录
前期知识点
事件函数
若使用事件对象,则在调用函数时传入第一个参数为:$event
.prevent:阻止链接默认行为
.stop:阻止冒泡
.once:事件触发一次
键盘事件:
@keyup.enter=
.tab:切换焦点,需要配合@keydown
特殊:ctrl、alt、shift、meat(win)
1:以上四个配合keyup按下修饰键同时,在按其他键随后释放其他键,事件才触发
2:以上四个配合keydown正常触发事件
监视属性watch:
数据对比,再做一些逻辑
handler(){} 函数传递两个参数,新值 和旧值
immediate:true,初始化时,先让handler函数调用一下
VM.$watch(‘监视名’,{处理的逻辑})
在watch中配置deep:true可检测对象多层级内部值改变
监视属性里面的函数里的定时器用箭头函数形式,箭头函数没有自己的this
computed和watch的区别
1、computed可完成的功能watch都可以完成
2、watch能完成的功能,computed不一定能完成,(watch可进行异步操作)
列表过滤
handler函数,只有一个形参,则该形参就是监听的最新值,
filter((x)=>)拿到陪陪项,将过滤出的值输出,返回一个数组
indexOf(xx)方法。监测在数组字符中是包含该项,有返回索引,无返回0。无论字符串或数组
v-model的三个修饰符
.lazy:失去焦点再搜集数据
.number:输入字符串转为有效的数字
.trim:输入首尾空格过滤
v-colak指令.
1:本质是一个特殊属性,Vue实例创建完毕并接管容器后,会删除v-cloak属性
2:使用css配合v-cloak可以解决网速慢时画面展示出{{xx}}问题
v-once:
所在节点在初次动态渲染后,就视为静态内容了。只解析一次
v-pre
跳过其所在节点的编译过程,可利用其跳过没有使用指令语法,没有使用插值语法的及覅,加快编译
常用的生命周期钩子
mounted:发送Ajax请求、启动定时器、绑定自定义事件、订阅信息等初始化操作
beforeDestroy:消除定时器、解绑事件、取消订阅等首尾工作
组件知识点
非单文件组件
使用Vue.extend(内容),内容与new vue(内容)几乎一样
区别:
1:不写el最终所有组件经一个vm管理,由vm中的el决定服务哪个容器
2:data必须写成函数,避免组件被复用时数据存在引用关系
3:使用template可配置组件结构
局部注册:new vue时传入 components
全局注册:Vue.component(‘组件名’,组件)
关于VueVomponents
定义的组件本质是一个名为VueComponents的构造函数,且不是程序员定义的,是Veu.extend生成
每次调用Vue.extend返回都是一个全新的VueComponent
关于this指向
在组件配置中:data函数、methods中的函数、watch中函数、等等,this指向VueComponent实例对象
在new vue配置中:data函数等等,this均指向Vue实例对象
内置关系
VueComponent . prototype . _ _proto _ _ === Vue.prototype
组件实例对象的隐式原型属性指向Vue的显示原型属性
单文件组件
App.vue文件,管理所有单文件组件
main.js文件,入口文件,绑定指定区域
index.html文件,html页面,先区域,再引vue源码,再引入口js文件f
脚手架关于不同版本的vue
vue.js与vue.runtine.xxx.js的区别
1:vue.js是完整版的vue,包含:核心功能+模板解析器
2:vue.runtine,xx.js是运行版的vue,只包含:核心功能,没有模板解析器
命令:vue inspect > output.js 输出/查看脚手架配置
ref属性
被用来给元素或子组件注册引用信息(id选择器的替代者)
打标识:<h2 ref="xxxx">。获取:this.$refs.xxx
配置项props
组件接收外部传过来的数据
传递数据:组件标签<Demo name="xxx"/>
接收数据:三种方法
props:['name'] 或者:{name:String} 或者
props:{name:{type:String类型,required:true必要性,default:‘xx’默认值 } }
混入
把多个组件共同的配置提取成一个混入对象
插件(自定义)
用于增强vue,建立一个plugins.js文件
本质:包含install方法的一个对象,install的第一个参数是vue,第二个以后的参数就是插件使用者传递的数据
定义插件:xx x.install={...} .。使用插件:Vue.use(插件名) 。在main.js中先引入再使用
scoped样式作用域
让样式在局部生效,防止冲突,在<style scoped>
WebStorage本地存储
存储内容一般支持5M左右,
浏览器通过Window.sessionStorage和Window.localStorage属性来实现本地存储机制
1:xxxStorage.setItem(‘key’,'value)该方法接收一个键值作为参数添加在存储中,若键名存在则更新对应值
2:xxxStorage.getItem(‘person’)接收一个键名作为参数,返回该键名对应的值
3:xxxStorage.removeItem(‘key’):接受一个键名作为参数,并把该键名从存储中删除
4:xxxStorage.clear():该方法会清空存储中的所有数据
备注:
1:SessionStorage存储的内容会随着浏览器窗口关闭而消失
2:LocalStorage存储的内容需要手动清除才会消失
3:xxxStorage.getItem(xxx) :若xxx对应的value获取不到,则getItem返回值为null
4:JSON.parse(null)的结果依然是null
若存储的值为对象,可使用JSON.Sreingify(xxx)转换后再存储
若获取得到的JSON格式字符串,可用JSON.parse(xxx)转为对象
组件的自定义事件
一种组件间通信方式,适用于:子组件=>父组件
使用:在父组件中给子组件绑自定义事件,事件回调留在父组件中
1:@自定义事件名=“”触发函数名" (触发一次可用once修饰符或$once方法)
2:ref=标识名',本组件内指定:this.$refs.标识名.$on(‘事件名’,this.函数名)
这种回调函数要么在methods中,要么使用箭头函数,否则this指向会出问题
触发自定义事件:this.$emit(‘事件名’,数据),子组件内使用
解绑自定义事件:this.$off(‘’事件名)
全局事件总线
一种组件通信方式,适用于任意组件间通信
总线安装:在main.js中的new vue内 beforeCrea(){Vue.prototype.$bus=this}
A接收数据:在A中个$bus绑定自定义事件,事件回调留在自身中
mounted(){ this.$bus.$on(‘自定义事件名’,自身函数名)}
B提供数据:this.$bus.$emit(‘自定义事件名’,数据)
消息订阅与发布
一种组件间通信方式,适用于任任意组件间通信
安装:pubsub:npm i pubsub-js
引入pubsub库:import pubsub from ‘pubsub-js’
接收数据:订阅信息,回调留在自身
methods:{回调函数}
mounted(){ this . pubId=pubsub . subscribe(事件名),this.回调}。 订阅
beforeDestroy(){ pubsub.unsubscribe(事件名)} 销毁
提供数据:pubsub.publish(‘事件名’,数据)
注:最好在beforeDestroy钩子中,用PubSub.unscribe(pubId) 取消订阅
$nextTick
语法: this.$nextTick(回调函数)
子按下一次DOM更新结束后这行指定的回调
何时用:当改变数据后,要基于更新后的新DOM进行某些操作时
vue封装的过渡与动画
准备样式:
元素进入:v-enter起点、v-enter-active过程、v-enter-to终点
元素离开:v-leave起点、v-leave-active过程、v-leave-to终点
1:用自定义动画:只使用“过程”指定类名即可
2:用传统过滤:用“起点和终点”或再配合过程
3:使用第三方库:安装、引入、再使用固定的类名指令
使用<transition>包裹要过渡的元素或标标签,并配置name属性(name是标识动画区域)
备:若有多个元素需要过程,则使用<transition-group>且每个元素指定key值,方便读取
vue脚手架配置代理(代理服务器)
编写vue.config.js配置具体的代理规则
优点:可配置多个代理,可灵活控制是否走代理
缺点:配置略微繁琐,请求资源时必须加前缀
devServer:{
poroxy:{
'/api':{//匹配以‘/api’开头的请求路径
target:'http://localhost:8080',//代理目标的基础路径,只写到端口号
changeOrigin:true,//控制请求头中的host
pathRewrite:{'^/api':''}//匹配到以'/api'开头替换为空字符
},
'/api2':{......}//第二条规则
}
}
changeOrgin设置为true,服务器收到请求头中host为自己的端口(欺骗)默认
changeOrgin设置为false,服务器收到请求头中host为代理的真实端口(不欺骗)
插槽:
让父组件向子组件指定位置掺入HTML结构,组件间通信,父=>子
1:默认插槽:子组件用<slot></slot>
2:具名插槽:
父组件在<template>中的slot属性定义名字
子组件中用<slot>中name属性使用具体名字插槽
3:作用域插槽:
父组件用scope属性或slot-scope定义作用域,
子组件用slot用 :名="作用域名"
数据在组件自身,但根据数据生成的结构需要组件的使用者决定,
vuex共享数据
初始配置
多个组件需要共享数据时.vuex3兼容vue2,vuex4兼容vue3
下载vuex:npm i vuex@3 @几就是几版本的
1:创建文件:src/store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const action={}//响应组件的动作
const mutation={}//执行动作
const state={}//初始化数据
export default new Vuex.Store({
actions.mutations.state
})
2:在main.js创建vm时传入stote配置项
import store from './store/index.js'
new Vue({
el:'App',
render:h=>(App),
store
})
3:基本使用:
const actions={
jia(context,value){
console.log('JIA',value)
}
},
const mutations={
JIA(state,value){//在数据基础上加传递来的数据
state.sum += value
}
},
const atate={
sum:0
}
export default new Vuex.Store({
actions,mutations,state
})
组件读取vuex的数据:$store.state.sum sum是数据名
组件修改vuex的数据,$store.dispatch('actions中的方法名,数据')
$store.commit('mutations中的方法名,数据')
备注:若无网络或其他业务逻辑,组件中可越过actions。直接用commit 联系mutations
getters的使用
当state中的数据需要经过加工后再使用时可以使用getters加工
在store.js中追加getters配置
const getters={
bigSum(state){
return state.sum * 10
}
}
export default new Vuex.store({
.....,getters//暴露配置
})
四个map方法的使用
1:mapState方法:帮助映射state中数据为计算属性
...mapState({sum'sum,.....})//对象写法
...mapState(['sum',.....])//数组写法,名字一致时使用
2:mapGetters方法:帮助映射greers中的数据的计算属性
...mapGetters({bigSum'bigSum',.....})//对象写法
...mapGetters(['bigSum',.....])//数组写法,名字一致时使用
3:mapActions方法:帮助生成与actions对话的方法,包含:$store.dispatch函数
mathods:{
...mapActions({incrementOdd:'jiaOdd',...})//对象形式
...mapActions({'jiaOdd',...})//数组形式
}
4:mapMuaations方法:帮助生成与Muaations对话的方法,包含:$store.commit函数
mathods:{
...mapMutations({incrementOdd:'JIA',...})//对象形式
...mapMutations({'jJIA',...})//数组形式
}
Vuex模块化+命名空间
让代码更容易维护,让多种数据分类更加明确
修改store.js
const countAbout={
namespaced:true,//开启命名空间
actions:{},
Mutations:{},
state:{},
getters:{},
}
const personAbout={....//同上}
const store =new Vuex.store({
modules:{//组件名注册
countAbout,
personAbout
}
})
1:命名空间开启后
读取state数据
直接读取:this.$store.state.模块名.lxxxx
借助mapState:...mapState('vuex模块名',['sum','....'] )
组件读取getters数据
直接读取:this.$store.getters[ '模块名/操作名' ]
借助mapGetters:...mapGetters(' 模块名',[ '操作名' ])
2:开启命名空间,组件中调用dispatch
直接dispatch:this.$stpre.dispatch('模块名 / 操作名',数据或数据对象)
借助mapActions:...mapActions('模块名',{本组件内事件名: actions中的操作名})
3:开启命名空间,组件中调用commit
直接commit:this.$store.commit('模块名 / 操作名,数据或数据对象)
借助mapMutations:...mapMutations('模块名'.{本组件事件名: mutations中的操作名})
优化文件:模块可以分成js文件分别放在store文件夹下,便于管理,但需要分别暴露和在index.js文件中都引入即可
vue-router
基本了解
vue的一个插件库,专门用来实现SPA应用
单页面Web应用,整个应用只有一个完整的页面
点击页面中的导航、链接,不刷新页面,只做页面的局部更新
是一对映射关系:(key:value)
后端路由:value是函数,用于处理客户端提交的请求
前端路由:value是组件,用于展示页面内容
路由
安装:npm i vue-router@3 默认版本为4
应用插件:Vue.use(VueRouter)
引入插件:import VueRouter from ‘vue-router’
编写router配置项,' router / index.js'
import VueRouter from 'vue-router'//引入VueRouter
import About form './components/About'//引入组件
import Home form './components/Home'//引入组件
export default new VueRouter({
routes:[
{path:'/about',component:About},
{path:'/home,component:Home}
]
})
指定展示位置:<router-view></router-view>
实现切换样式:<router-view acttive-class='xxx'></router-view>
注意:
1:路由组件通常放在pages文件夹下,一般组件通常放在components文件夹下
2:通过切换“隐藏”了的路由组件,默认是销毁,需要时再挂载
3:每个组件都有自己的$routes属性,里面存放着自己的路由信息
4:整个应用只有一个router路由管理,可通过组件的$router属性获取到
多级路由(嵌套路由)
配置路由规则,使用children配置项
roets:[
{path:'/about',component:About},
{path:'/home',component:Home,children:[
{prth:'news',component:News}//在子路由中不加 /
]}
]
跳转:要写完整路径,在 to=""内,并且加上父级路径
<router-link to='/home/news'></router-link>
路由的query参数
1:传递参数
<router-link to='/home...deta?id=6&title=7'>跳转</router-link>//字符串
<router-link :to=" `/home...deta?${id=xx.id} & ${title=x.title}`">跳转</router-link>//模板字符串,解析js
<router-link :to='{
path:'/home.....',
query:{id:x.id,title:x.title}
}'>跳转
</router-link>//to的对象写法
2:接收参数
(this).$route.query.xxx 在插值语法中,this可省略
命名路由
在router文件夹下的index.js文件内,使用一项name命名来简化路由的舔砖
1:name命名路由配置
{
path:'/home',component:Home,children:[
path:'/test',components:Test,children:[{
name:'hello',path:'welcome',component:Hello
}]
}]
}
2:简化跳转
<router-link to='home/test/welcome'>跳转</router-link >//简化前
<router-link to='{name:'hello'}'>跳转</router-link >//简化后
<router-link to='{name:'hello',query:{id:xx,title:xxx}}'>跳转</router-link >//搭配传参
路由的params参数
1:配置路由,声明接收params参数
{
name:'xiangqinag',path:'date / :id / :title',component:'xxxx'//使用占位符声明接收的params参数
}
2:传递参数
<router-link to='home/test/welcome/666/你好'>跳转</router-link >//to字符串写法
<router-link :to='{
name:'xiangqing',
params:{
id:xxx,
title:xxxx
}
}'>跳转</router-link >//to字符串写法
注意:路由携带paiams参数,使用to对象写法,不能使用path配置项,必须使用name配置
接收参数:$toute.params.xxxx 写在展示组件内
路由的props配置
让路由组件更方便接收参数
{name:'xx',path:'xxxx',component:'xx',
1:props:{a:99}//该对象中所有的key-value通过props传给组件
2:props:true//布尔值,把路由收到的所有值由props传给组件
3:props:($route){//返回值每一组key-value由props传给组件
retuen {
id:$route.query.id,
title:$route.query.title
}
}
历史记录replace属性
控制路由跳转时操作浏览器历史记录的模式。浏览器有两种模式:push和replace
push:追加历史记录 replace:替换当前记录,不可返回 路由默认为push
<router-link replace>跳转<router-link>//开起replace模式
编程式路由导航
作用:不借助<router-;link>实现路由跳转,让路由跳转更加灵活
在按钮、图片等事件内:
push(){//跳转有历史记录
this.$router.push({
name:'路由名',
params:{...}
})
},
replace(){//跳转无历史记录
this.$router.replace({
。。。。。
})
}
历史记录进退的API:
this.$router.forward()
this.$router.back()
this.$router.go()//正数前进,负数后退
缓存路由组件
让不展示的路由组件保持挂载,不被销毁,可以缓存前进后退不消失
<keep-alive></keep-alive>
<keep-alive include="组件名"></keep-alive>
<keep-alive include="['xxx','xxx']"></keep-alive>
要包裹<router-view>这个标签