vue笔记
Vue笔记
#笔记
vue监视属性原理
1.vue会监视data中所有层次的数据
2.检测对象中的数据:
通过setter实现监视,且要在new Vue时就传入要检测的对象
a.对象中后追加的属性,vue是不做响应式处理的。需要使用set()方法进行添加。如 Vue.set(目标对象,key,value)或是 vm.$set(目标对象,key,value)
3.监测数组中的数据:
通过包裹数组更新元素的方式实现,本质就是做两件事:
a.调用原生对应的方法对数组进行更新
b.重新解析模板,进而更新页面
4.在Vue修改数组中某个元素一定要用如下方法:
a.push()//添加,pop()//删除,shift()//拿第一个,unshift()//拿最后一个,splice(替换),sort,reverse() 或者
b.Vue.set() 或 vm.$set()
注意: Vue.set() 或 vm.$set()不能给Vue根数据对象或vm添加属性
自定义指令总结
一定义语法:
1.局部指令:
new Vue({
directives:{指令名:配置对象} 或
})
new Vue({
directives{指令名:回调函数}
})
2.全局指令:
Vue.directive(指令名,配置对象) 或Vue.directive(指令名,回调函数)
二、配置对象中常用的三个回调:
bind:指令与元素成功绑定时调用
inserted:指令所在元素被插入页面时调用
update:指令所在模板结构被重新解析时调用。
指令名如果是多个单词要使用kebab-case命名方式
ref属性:
1.被用来给元素和子组件注册引用信息(id的替代者)
2.应用在html标签上获取的是真实DOM元素,应用在组件标签上获取到的是组件实例vc
3.
或使用this.$refs.xxx
props属性:
让组件接收外部传过来的数据
1:传递数据
2.接收数据3种方式:a.props:['name'] 只接受。b.props:{name:String} 限制类型 c.props:{name:{type:String,required:true,default:''}} 限制类型、限制必要性、指定默认值。
props是只读的,Vue底层会监视你对props的修改,如果进行了修改,就会发出警告,如果需要该数据。则复制props中的数据到data中一份,然后对data中的数据进行修改。
mixin混入:
可以把多个组件共用的配置提取出一个混入对象
使用方式:1.定义混入。可以单独在js文件中。export const xx = {data(){......},methods:{......}}。2.第二步使用 两种方式:
a.全局混入:Vue.mixin(xxx)。b.局部混入:mixins:[xxx]。
插件:
用于增强Vue
本质:包含install方法的一个对象,install的第一个参数是Vue,后面的参数是插件使用者传递的数据。
定义插件:export default {
install(){
.......,
.......
}
}
使用插件,在main.js中Vue.use(插件的名称)
##使用v-model时要切记:v-model绑定的值不能是props传过来的值,因为props的值是不可以修改的。
全局事件总线:
1.一种组件间的通信方式,适用于任意组件间通信
2.安装全局事件总线:
new Vue({
......
beforeCreate(){
Vue.prototype.$bus = this;//全局事件总线,$bus相当于当前应用vm
},
})
3.使用数据总线:
1.接收数据,A组件想要接收数据,则在A组件中给$bus绑定自定义事件,事件的回调留在A组件内
methods:{
demo(data){
......
}
mounted:{
this.$bus.$on('事件名',this.demo)
}
}
2.B组件提供数据:
this.$bus.$emit('事件名',data);
4.最好在beforDestroy函数中,用$off将当前组件用到的事件解绑。
nextTick
1.语法:
this.$nextTick(function(){
.......
})
2.在下一次DOM更新结束后执行其指定的回调。
3.当改变数据后,要基于更新后的新DOM进行某些操作时,要在$nextTick指定的回调函数中执行
Vue-cli配置代理
编写vue.config.js配置具体代理规则:
module.exports = {
devServer:{
proxy:{
'api1':{//匹配所有以api1开头的请求路径
target:'http://ip:port', //代理目标的基础路径
changeOrigin:true,//让目标服务器认为代理服务器和它同端口,默认是true
ws:true,//是否支持websocket
pathRewrite:{'^/api1':''}//将匹配到路径上的/api1全部替换为空,因为目标服务器上没有这个路径
},
'api2':{//匹配所有以api2开头的请求路径
target:'http://ip:port',
changeOrigin:true,
pathRewrite:{'^/api2':''}
}
}
}
}
插槽
1.作用:让父组件可以向子组件指定位置插入html结构,也是一种组件间通信的方式,类似于 父组件 ===》 子组件
2.分类:默认、具名、作用域
3.使用方式:
1.默认插槽:
//父组件中
<Child>
<div>html结构</div>
</Child>
//子组件中
<template>
<div>
//定义插槽内容
<slot></slot>
</div>
</template>
2.具名插槽:
//父组件中
<Child>
<template slot="center">
<div>html结构</div>
</template>
<template v-slot:footer>
<div>html结构</div>
</template>
</Child>
//子组件
<template>
<div>
<slot name="center">插槽内容</slot>
<slot name="footer">插槽内容</slot>
</div>
</template>
3.作用域插槽:
理解:数据在组件自身,但根据数据的结构需要组件的使用者来决定
//父组件中
<Child>
<template slot-scope="scopeData">
<div>{{scopeData.games}}</div>
</template>
</Child>
//子组件
<template>
<div>
<slot :games="games"></slot>
</div>
</template>
<script>
export default {
data(){
return {
//数据在子组件中
games:[xxx,xxx]
}
}
}
</script>
Vuex
1.工作原理图:
2.基本使用:
a.初始化数据,配置actions,mutations,state
操作store.js
import Vue from 'vue'
//引入vuex
import Vuex from 'vuex'
//使用vuex
Vue.use(Vuex)
const actions = {
//响应组件中动作
add(context,value){
context.commit('Add',value);
}
},
const mutations = {
//真正的执行动作,
Add(state,value){
state.sum += value
}
}
const state = {
sum :0// 指定初始值
}
//创建并暴露store
export default new Vuex.Store({
actions,
mutations,
state
})
b.组件中读取vuex中的数据:$store.state.sum
c.组件中修改vuex的数据:$store.dispatch('actions中的方法名',数据)或$store.commit('mutations中的方法名',数据) 备注:若没有网络请求或其他业务逻辑,组件中也可以越过actions,即不写dispatch,直接写commit
3.映射函数
mapState(帮助映射state数据,即帮助生成$store.state)、mapGetters(帮助映射getters中的数据):
computed:{
//借助mapState生成计算属性。对象写法
...mapState({sum:'sum'})//生成的函数名叫sum,去state中找的数据也叫sum。...属于js扩展语法,指在 对象A中加入对象B,对象B中全部属性加入到A中
//数组写法
...mapState(['sum'])//函数名和属性名须一致
}
mapActions(帮助映射生成actions方法,即包含$store.dispatch(xxx)的函数)、mapMutations(帮助映射生成mutations方法,即包含$store.commit(xx)的函数)
methods:{
//对象形式
...mapActions({increment:'jia'})
//数组形式
...mapActions(['jiaAdd','jiaWait'])//这里函数名要和action中的函数名一致
//对象形式
...mapMutations({increment:'Jia'})
//数组形式
...mapMutations(['Jia'])//这里函数名要和mutations中的函数名一致
}
路由Route
3.多级路由
1.配置路由规则,使用children配置项
routes:[
{path:'/about',component:About},
{
path:'/home',
component:Home,
children:[//配置子级路由
{path:'news',component:News}//此处不需要在路径前加/
]
}
]
2.跳转(要写完整路径):
<route-link to="/home/news">News</route-link>
4.路由的query/params参数
1.传递参数
<!--跳转并携带query参数,to的字符串带拼接变量写法-->
<route-link :to="`/home/message/detail?id=${m.id}&title=${m.title}`">跳转</route-link>
<!--跳转并携带query参数,to的对象带拼接变量写法-->
<route-link to="{
path:'/home/message/detail',
query:{
id:m.id,
title:m.title
}
}">
跳转
</route-link>
<!--params参数方式-->
//配置路由时:
path:'/home/message/detail/:id/:title' //要使用占位符
//传递参数时:
<route-link :to="`/home/message/detail/${m.id}/${m.title}`">跳转</route-link>
或者
<route-link to="{
name:'myDetail',//此处必须用name属性,否则会解析失败
params:{
id:m.id,
title:m.title
}
}">
跳转
</route-link>
2.接收参数:
$route.query.id
$route.query.title
----------------------------
$route.params.id
$route.params.title
5.路由的props配置
让路由组件更方便的收到参数
{
name:'myDetail',
path:'detail',
component:Detail,
props(route){
return {
id:route.query.id,
title:route.query.title
}
}
}
//在组件中注入
props:['id','title']
6.编程式路由
1.作用不借助route-link实现页面自由跳转
2.具体编码:
this.$router.push({
name:'xx',
params:{
id:'xx',
title:'xx'
}
})
this.$router.replace({
name:'xx',
params:{
id:'xx',
title:'xx'
}
})
this.$router.forward();//前进
this.$router.back();//后退
this.$route.go(num);//num值为正数,则是前进num步,负数则为后退num步
7.缓存路由组件
1.作用:让不展示的路由组件保持挂载,不被销毁
2.具体代码:
//单个的
<keep-alive include="组件名">
<router-view></router-view>
</keep-alive>
//多个的
<keep-alive :include="[组件名,组件名]">
<router-view></router-view>
</keep-alive>
8.激活、失活钩子
1.作用:用于捕获路由组件的激活状态
2.具体代码:
activated(){//路由组件被激活时触发
.....
}
deactivated(){//路由组件失活时触发
.....
}
9.路由守卫
1.作用:对路由进行一些权限的控制
2.分类:全局守卫、独享守卫、组件内守卫
3.1全局守卫
//全局前置守卫,初始化时执行、每次路由切换前执行一次
//在路由的index.js中配置
const router = new VueRouter({....})
router.beforeEach((from,to,next)=>{//to:要去的组件,from:从哪个组件来,next:放行
if(to.meta.isAuth){//判断当前路由是否需要鉴权。在路由配置中,设置meta属性对象,里面添加isAuth属性值为true.
if(xxxx){//鉴权的具体规则
next()
}
}else{
next()
}
})
//全局后置守卫,初始化时执行、每次路由切换后执行一次
router.afterEach((from,to)=>{//to:要去的组件,from:从哪个组件来
if(xx){//验证规则
.....
}
})
3.2独享路由守卫
beforeEnter(from,to,next){
.....//鉴权规则逻辑
}
3.3组件内守卫
//进入守卫,通过路由规则,进入该组件时被调用
//在组件里写
beforeRouteEnter(to,from,next){
....
}
//离开守卫,通过路由规则,离开该组件时被调用
beforeRouteLeave(to,from,next){
....
}
10.路由器的两种工作模式
1.hash:
及其后面的路径内容都是hash值,hash值不会包含在http请求中,不会带给服务器
优点:兼容性好。缺点:1.不美观。2.手机app校验严格的,容易被标记为不合法
2.history:
项目部署上线后,一般用这种模式,
优点:美观,缺点:相较于hash兼容性略差
浙公网安备 33010602011771号