组件与数据通信
| 组件关系 | 数据通信 |
|---|---|
| 父子关系 | 子传父:props;父传子:$emit |
| 非父子关系 | eventBus:emit |
| 非父子关系 | vuex |
$bus
- 对$bus的要求:
所有的组件可以关联(就是看得见,看不见怎么关联)
要能够调用$on,$off,$emit(不能绑定关系怎么控制组件)
分析:能让所有的组件关联,必须是全局的(vm,vc,window),当然window就大材小用了,那选vm还是vc呢?
关于vc(vueComponent):
1.App组件是本质是一个名为*vueComponent*的构造函数,且不是程序员定义的
是*vue.extend*生成的
2.我们只需要写<App/>,vue解析时会帮我们创建App组件的实例对象,
即vue会帮我们执行:new VueComponent(options)
3.特别注意:每次调用Vue.extend.*返回的都是一个全新的VueComponent*
4.this指向:
(1)组件配置中:
data函数,methods中的函数,watch中的函数,computed中的函数
它们的this均是*VueComponent实例对象*
(2)new vue(options)配置中:
data函数,methods中的函数,watch中的函数,computed中的函数
它们的this均是*Vue实例对象*
5.一个重要的内置关系:
vueComponent.prototype.__proto__===Vue.prototype
即:组件实例对象可以访问vue原型上的属性,方法
标准写法
注册:
beforeCreate(){
vue.prototype.$bus=this
}
使用:
mounted(){
this.$bus.$on('xxx',(data)=>{})
}
销毁:
beforeDestroy(){
this.$bus.$off('xxx')
}
vuex
- 定义:Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式, 采用集中式存储管理应用的所有组件的状态,解决多组件数据通信。
- 要点:
- vue官方搭配,专属使用 (类似于:vue-router),有专门的调试工具
- 集中式管理数据状态方案 (操作更简洁)
data() { return { 数据, 状态 }} - 数据变化是可预测的 (响应式)
属性:
state:保存公共数据
定义:
state(){
return {
数据1:值1
}
}
使用:this.$store.state.数据1
mutations:修改数据
定义:
mutation:{
m名字(state,参数){}
}
使用:this.$store.commit(m名字,实参)
getters:计算属性
定义:
getters:{
g名字(state){
return 计算结果
}
}
使用:this.$store.getters.g名字
actions : 异步请求
定义:
actions:{
a名字(context,参数){
axios...
context.commit('m名字')
}
}
使用:this.$store.dispatch('a名字',实参)
modules:拆分模块
定义:
store
-index.js//引入模块1.js
-modules
-模块1.js
使用:
import 模块1 from './modules/模块1.js'
modules:{
模块1
}
模块1:
export default{
namespaced.true,
state,
mutations,
getters,
actions
}
调用:
getters: this.$store.getters['模块1/g名字']
state: this.$store.state.模块1/数据名字
mutations: this.$store.commit{'模块1/g名字',参数}
actions: this.$store.dispatch{'模块1/g名字',参数}
辅助函数(map)
定义 import {mapState} from 'vuex'
模块 computed:{...mapState('模块名',['xxx'])}
全局 computed:{...mapState(['xxx'])}
重命名 computed:{...mapState('新名字',['xxx'])}
路由守卫(前置)
- 定义:路由跳转之前, 会触发一个函数(做一个拦截校验)
- 语法:router.beforeEach((to, from, next) => {}) 代码实例
在router/index.js 路由对象上使用固定方法beforeEach
// 路由守卫
// 每次页面跳转,都会执行这个回调
router.beforeEach((to, from, next) => {
console.log(to, from)
// to代表要跳转到哪个路径去, to的值是个对象可以打印看到
// from代表从哪个路径跳过去
// next是一个函数。
// next() 放行;
// next('路由地址') 跳到指定的位置
// 判断,是否有权限去访问页面,如果没有权限,跳转到登录页
const token = localStorage.getItem('token') // 假设token
// 访问login不要token,其他都要
if(to.path === '/login'){
next()
} else {
// 不去login,就要检查一下证件
if(token){
next() // 有token就正常访问
} else {
next('/login')
}
}
})
路由守卫(后置)
- 定义:路由跳转后, 触发的函数
- 语法:router.afterEach((to, from) => {}) 代码实例
router.afterEach((to, form) => {
console.log(to);
console.log(form);
console.log("路由发生了跳转");
})
路由模式设置
- 作用: 修改路由在地址栏的模式 代码实例
const router = new VueRouter({
routes,
mode: "history" // 打包上线后需要后台支持
})
history和hash模式对比
- 功能一样(跳转页面)
- history模式的path路径不带#号,hash有#号
- hash模式兼容性好 示例:
hash路由例如: <http://localhost:8081/#/home>
history路由例如: <http://localhost:8081/home>