vue属性的用法


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的实现原理

image-20221009172721469

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

image-20221019102444288

如果现在回退,则回退到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(通过路由规则,离开该组件时被调用)


Author: baiwenhui
Reprint policy: All articles in this blog are used except for special statements CC BY 4.0 reprint policy. If reproduced, please indicate source baiwenhui !
  TOC