vue属性的用法
elementUI
1、form表单
:inline=”true”
定义搜索栏时,利用form表单的inline属性,可以让表单内部变成行内元素自动为一行,同时缩小屏幕宽度会自动换行
2、input输入框
clearable
可以将选择器清空,仅适用于单选
style scoped
让样式在局部生效,防止冲突
vue.js
v-model
v-model双向绑定,需要data中有这个属性,最初先是为空
子组件给父组件传值
1、通过父组件给子组件传递函数类型的props实现
2、通过父组件给子组件绑定一个自定义事件实现,使用@或者v-on
- 使用点击事件触发组件实例上的自定义事件this.$emit()
3、通过父组件给子组件绑定一个自定义事件实现,使用ref
- 使用钩子函数绑定自定义事件this.$refs.student.$on
全局事件总线
是组件间通信的方式,适用于任意组件间通信
1、在main.js安装全局消息总线
new Vue({
....
beforeCreate() {
Vue.prototype.$bus = this
}
}).$mount('#app')
2、A组件接收数据,则在A组件中给$bus绑定自定义事件,事件的回调函数在A组件
methods(){
demo(data){...}
},
mounted(){
this.$bus.$on('xxxx',this.demo)
}
B组件发送数据this.$bus.$emit('xxxx',data)
3、最好在beforeDestory钩子函数中,用$off解绑当前组件所使用的事件
消息订阅与发布
组件间通信的方式,适用于任意组件间通信
1、安装pubsub:
npm i pubsub-js
2、引入
import pubsub from 'pubsub-js'
3、接收数据:
methods(){
demo(data){}
}
mounted(){
this.pid = pubsub.subscribe('xxxx',this.demo)
}
4、提供数据
pubsub.publish('xxxx',数据)
5、最好在beforeDestory钩子函数中,用unsubscribe
取消订阅
插槽
- 作用:让父组件给子组件指定位置插入html结构,也是一种组件间通信的方式
- 分类:默认插槽、具名插槽、作用域插槽
- 使用方式:
1、默认插槽:
父组件:
<Category>
<div>html结构</div>
</Category>
子组件:
<template>
<div>
<slot>插槽内容</slot>
</div>
</template>
2、具名插槽
父组件:
<Category>
<template slot="center">
<div>html结构1</div>
</template>
<template v-slot:footer>
<div>html结构2</div>
</template>
</Category>
子组件:
<template>
<div>
<slot name="center">插槽内容</slot>
<slot name="footer">插槽内容</slot>
</div>
</template>
3、作用插槽
数据在组件的自身,但是根据数据生成的结构需要组件的使用者来决定
父组件:
<Category>
<template scope="scopeData">
<ul>
<li v-for="(g,index) in scopeData.games" :key="index">{{g}}</li>
</ul>
</template>
新的写法es6
<template scope="{games}">
<ul>
<li v-for="(g,index) in games" :key="index">{{g}}</li>
</ul>
</template>
<template slot-scope="scopeData">
<ul>
<li v-for="(g,index) in scopeData.games" :key="index">{{g}}</li>
</ul>
</template>
</Category>
子组件:
<template>
<div>
<slot :games="games">插槽内容</slot>
</div>
</template>
<script>
export default {
name: "Category",
data(){
return {
games:['a','b','c']
}
}
}
</script>
多组件共享数据
多个组件的共享状态进行集中式的管理,用vuex实现
vuex的实现原理
state:存放组件的数据
vue component
mutations:用于操作数据
actions:用于响应组件中的动作,可以添加相应的逻辑;如果在actions操作数据也可以成功,但是vuex捕获不到,属于一种不是标准的写法
1、初始化数据,配置actions、配置mutations,操作文件是router文件夹下的index.js
//引入vue核心库
import Vue from 'vue'
//引入vuex
import Vuex from 'vuex'
//引用vuex
Vue.use(Vuex)
const actions = {
//响应组件中的动作
add(context,value){
console.log('actions的add被调用了',miniStore,value);
context.commit('addNum',value);
}
}
const mutations = {
//操作数据
addNum(state,value){
console.log('mutations中的addNum被调用了',state,value);
state.sum+=value
}
}
//初始化数据
const state = {
sum:0
}
//创建并暴露store
export default new Vuex.Store({
actions,
mutations,
state,
})
2、组件中读取vuex中的数据:在模板中$state.state.sum
,在js脚本中加this
3、组件中修改vuex中的数据:$state.dispatch('actions中的方法名',数据)
或者 直接$state.commit('mutations中的方法名',数据)
getters
1、当state中的数据需要加工后再使用,可以使用getters
2、添加配置
//对数据进行加工
const getters = {
//对数据进行具体的操作,减少代码冗余
bigSum(state){
return state.sum*10;
}
}
//创建并暴露store
export default new Vuex.Store({
actions,
mutations,
state,
getters
})
3、组件读取数据:$store.getters.bigSum
mapState与mapGetters
1、解除mapState生成计算属性,从state中读取数据
computed:{
...mapState({//...表示将对象依次取出放在这个位置相当于多个计算属性函数
he:'sum',
xuexiao:'school',
xueke:'subject'
})//对象写法
...mapState(
['sum','school','subject']
)//数组写法(需要生成的计算属性的名称和state中读取的名称一致)
...mapGetters({//对象写法
bigNum:'bigNum'
})
...mapGetters(
['bigNum']
)
}
2、钩子函数可以在初始化之前查看mapState的属性
mounted(){
const x = mapState{{
he:'sum',
xuexiao:'school',
xueke:'subject'
}}
console.log(x)
}
mapActions和mapMutations
mapMutations绑定Mutations中的方法生成对应的方法,方法中会调用commit去联系
1、绑定事件需要参数,否则MouseEvent
<button @click="increment(n)">+</button>
2、在methods中
methods:{
...mapMutations({jia:'addNum'})//对象写法
...mapMutations(['addNum','subNum'])//数组写法
//必须methods生成的方法名和mutations中的方法一致
}
或者不需要参数
methods:{
increment(){
this.Jia(this.n);
},
decrement(){
this.jian(this.n);
},
...mapMutations({Jia:'addNum',jian:'subNum, '})
}
vuex模块化
1、作用:让代码更好维护,让多组件数据分类更加明确
2、修改store.js
const countAbout = {
namespaced:true,//开启命名空间
state:{x:1},
mutations:{...},
actions:{....},
getters:{
bigSum(state){
return state.sum*10;
}
},
}
const personAbout = {
namespaced:true;
state:{...},
mutations:{....},
actions:{....},
}
const store = new Vuex.Store({
modules:{
countAbout,
personAbout,
}
})
3、组件中读取state数据
计算属性中
1、直接读取
this.$store.state.personAbout.list
2、借助mapSate读取
...mapState('countAbout',['sum','school','subject']),
4、组件中读取getters数据
1、直接读取
this.$store.getters['personAbount/firstPersonNames']
2、记住mapGetters读取
...mapGetters('countAbout',['bigNum'])
5、组件中调用dispatch
1、直接dispatch获取
this.$store.dispatch('personAbount/addPersonWang',person)
2、借助mapActions读取
...mapActions('countAbout',{incrementOdd:'jiaOdd',incrementWait:'jiaWait'})
6、组件中调用commit
1、直接commit
this.$store.commit('personAbount/AddPersonWang',person)
2、借助Mutations
...mapMutations('countAbount',{increment:'JIA',decrement:'JIAN'})
路由
就是一组key-value的对应关系,多个路由,需要经过路由器的管理
注意:
1、通过切换页面,隐藏了的路由组件,默认是被销毁的,需要的时候再去挂载
2、每一个组件都有自己的$route属性,里面存储着自己的路由信息
3、整个应用只有一个router,通过组件的$router属性获取
params参数
{
path:'/home',
component:Home,
children:{
path:'news',
component:News,
},
{
component:Message,
children:{
name:'xiangqing',
path:'detail/:id/:title',//使用占位符声明接收params参数
component:Detail
}
}
}
2、传递参数
<router-link :to="/home/message/detail/666/你好"></router-link>
//to的字符串写法
//to的对象写法
<router-link
:to="{
name:'xiangqing',
params:{
id:666,
title:'你好'
}
}"
>
</router-link>
路由携带params参数时,使用的是to的对象写法,不能使用path配置项,必须使用name配置
{
path:'/home',
component:Home,
children:{
path:'news',
component:News,
},
{
component:Message,
children:{
name:'xiangqing',
path:'detail/:id/:title',//使用占位符声明接收params参数
component:Detail,
//1、值为对象,对象中的所有key-value会以props的形式传给Detail组件
props:{a:1,b:'hello'}
//2、值为布尔值,若布尔值为真,就会把路由组件收到的所有params参数以props形式传给Detail组件
props:true
3、值为函数
props(){
return {id:'666',title:'你好啊'}
}或者
props(route){
return {
id:route.query.id,
title:route.query.title
}
}
}
}
}
Detail组件
//值为对象
props:['a','b']
//值为布尔值
computed:{
id(){
return this.$route.query.id;
},
title(){
return this.$route.query.title;
}
}
//值为函数
props:['id','title']
router-link的replace属性
1、作用:控制路由跳转时操作浏览器记录的模式
2、浏览器的历史记录有两种写入方式:push和replace,push是追加历史记录,replace是替换历史记录,默认为push
About、Home是push
News、Message是replace
如果现在回退,则回退到about
编程式路由导航
1、作用:不借助
2、具体编码:
this.$router.push({
name:'xiangqing',
params:{
id:xxx,
title:xxx
}
})
this.$router.replace({
name:'xiangqing',
params:{
id:xxx,
title:xxx
}
})
this.$router.forward()//前进
this.$router.back()//后退
this.$router.go()//可前进可后退
缓存路由组件
1、作用:让不显示的路由组件保持挂载,不被销毁
<keep-alive include="News">
<Route-view></Route-view>
</keep-alive>
新的生命周期钩子
路由组件所独有的两个钩子,用于捕获路由组件的激活状态
activated路由组件被激活时触发
deactivated路由组件失活时转发
路由守卫
1、作用:对路由进行权限控制
2、分类:全局守卫,独享守卫,组件内守卫
//全局守卫。初始化时执行、每次路由切换时执行
router.beforEach((to.from.next)=>{
next()
if(to.meta.isAuth){//判断当前路由是否需要激进型权限控制
if(localStorage.getItem('school')==='atguigu'){
next();
}else{
alert('暂无权限查看');
}
}else{
next();//放行
}
})
//全局后置守卫,初始化执行,两次路由切换后执行
router.afterEach((to,from)=>{
if(to.meta.title){
document.title=to.meta.title;//修改网页的title
}else{
document.title='vue_test'
}
})
独享路由守卫:beforeEnter没有afterEnter后置独享守卫,可以和全局后置守卫配合使用
组件内守卫:beforeRouteEnter(通过路由规则,进入该组件时被调用)和beforeRouteLeave(通过路由规则,离开该组件时被调用)