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">&#123;&#123;g&#125;&#125;</li>
    </ul>
  </template>
    新的写法es6
  <template scope="&#123;games&#125;">
    <ul>
      <li v-for="(g,index) in games" :key="index">&#123;&#123;g&#125;&#125;</li>
    </ul>
  </template>
  <template slot-scope="scopeData">
    <ul>
      <li v-for="(g,index) in scopeData.games" :key="index">&#123;&#123;g&#125;&#125;</li>
    </ul>
  </template>
</Category>
子组件:
  <template>
    <div>
      <slot :games="games">插槽内容</slot>
    </div>
  </template>
<script>
export default &#123;
  name: "Category",
  data()&#123;
    return &#123;
      games:['a','b','c']
    &#125;
  &#125;
&#125;
</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 = &#123;
    //响应组件中的动作
    add(context,value)&#123;
        console.log('actions的add被调用了',miniStore,value);
        context.commit('addNum',value);
    &#125;
&#125;

const mutations = &#123;
    //操作数据
    addNum(state,value)&#123;
        console.log('mutations中的addNum被调用了',state,value);
        state.sum+=value
    &#125;
&#125;

//初始化数据
const state = &#123;
    sum:0
&#125;

//创建并暴露store
export default new Vuex.Store(&#123;
    actions,
    mutations,
    state,
&#125;)

2、组件中读取vuex中的数据:在模板中$state.state.sum,在js脚本中加this

3、组件中修改vuex中的数据:$state.dispatch('actions中的方法名',数据)或者 直接$state.commit('mutations中的方法名',数据)

getters

1、当state中的数据需要加工后再使用,可以使用getters

2、添加配置

//对数据进行加工
const getters = &#123;
    //对数据进行具体的操作,减少代码冗余
    bigSum(state)&#123;
        return state.sum*10;
    &#125;
&#125;

//创建并暴露store
export default new Vuex.Store(&#123;
    actions,
    mutations,
    state,
    getters
&#125;)

3、组件读取数据:$store.getters.bigSum

mapState与mapGetters

1、解除mapState生成计算属性,从state中读取数据

computed:&#123;
    ...mapState(&#123;//...表示将对象依次取出放在这个位置相当于多个计算属性函数
       he:'sum',
       xuexiao:'school',
       xueke:'subject'
    &#125;)//对象写法
    ...mapState(
        ['sum','school','subject']
    )//数组写法(需要生成的计算属性的名称和state中读取的名称一致)
    
    ...mapGetters(&#123;//对象写法
        bigNum:'bigNum'
    &#125;)
    
    ...mapGetters(
        ['bigNum']
    )
&#125;

2、钩子函数可以在初始化之前查看mapState的属性

mounted()&#123;
    const x = mapState&#123;&#123;
       he:'sum',
       xuexiao:'school',
       xueke:'subject'
    &#125;&#125;
    console.log(x)
&#125;

mapActions和mapMutations

mapMutations绑定Mutations中的方法生成对应的方法,方法中会调用commit去联系

1、绑定事件需要参数,否则MouseEvent

<button @click="increment(n)">+</button>

2、在methods中

methods:&#123;
    ...mapMutations(&#123;jia:'addNum'&#125;)//对象写法
    
    ...mapMutations(['addNum','subNum'])//数组写法
    //必须methods生成的方法名和mutations中的方法一致
&#125;

或者不需要参数

methods:&#123;
    increment()&#123;
        this.Jia(this.n);
    &#125;,
    decrement()&#123;
        this.jian(this.n);
    &#125;,
    ...mapMutations(&#123;Jia:'addNum',jian:'subNum, '&#125;)
&#125;

vuex模块化

1、作用:让代码更好维护,让多组件数据分类更加明确

2、修改store.js

const countAbout = &#123;
    namespaced:true,//开启命名空间
    state:&#123;x:1&#125;,
    mutations:&#123;...&#125;,
    actions:&#123;....&#125;,
    getters:&#123;
        bigSum(state)&#123;
            return state.sum*10;
        &#125;
    &#125;,
&#125;
    
const personAbout = &#123;
    namespaced:true;
    state:&#123;...&#125;,
    mutations:&#123;....&#125;,
    actions:&#123;....&#125;,
&#125;

const store = new Vuex.Store(&#123;
    modules:&#123;
        countAbout,
        personAbout,
    &#125;
&#125;)

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',&#123;incrementOdd:'jiaOdd',incrementWait:'jiaWait'&#125;)

6、组件中调用commit

1、直接commit
this.$store.commit('personAbount/AddPersonWang',person)
2、借助Mutations
...mapMutations('countAbount',&#123;increment:'JIA',decrement:'JIAN'&#125;)

路由

就是一组key-value的对应关系,多个路由,需要经过路由器的管理

注意:

1、通过切换页面,隐藏了的路由组件,默认是被销毁的,需要的时候再去挂载

2、每一个组件都有自己的$route属性,里面存储着自己的路由信息

3、整个应用只有一个router,通过组件的$router属性获取

params参数

&#123;
    path:'/home',
    component:Home,
    children:&#123;
        path:'news',
        component:News,
    &#125;,
    &#123;
        component:Message,
        children:&#123;
            name:'xiangqing',
            path:'detail/:id/:title',//使用占位符声明接收params参数
            component:Detail
        &#125;
    &#125;
&#125;

2、传递参数

<router-link :to="/home/message/detail/666/你好"></router-link>
//to的字符串写法

//to的对象写法
<router-link
     :to="&#123;
          name:'xiangqing',
          params:&#123;
              id:666,
              title:'你好'
          &#125;
      &#125;"
>
</router-link>

路由携带params参数时,使用的是to的对象写法,不能使用path配置项,必须使用name配置

&#123;
    path:'/home',
    component:Home,
    children:&#123;
        path:'news',
        component:News,
    &#125;,
    &#123;
        component:Message,
        children:&#123;
            name:'xiangqing',
            path:'detail/:id/:title',//使用占位符声明接收params参数
            component:Detail,
            //1、值为对象,对象中的所有key-value会以props的形式传给Detail组件
            props:&#123;a:1,b:'hello'&#125;
            
            //2、值为布尔值,若布尔值为真,就会把路由组件收到的所有params参数以props形式传给Detail组件
            props:true
            
            3、值为函数
            props()&#123;
                return &#123;id:'666',title:'你好啊'&#125;
            &#125;或者
            props(route)&#123;
                return &#123;
                    id:route.query.id,
                    title:route.query.title
                &#125;
            &#125;
        &#125;
    &#125;
&#125;
    
    
Detail组件
//值为对象
props:['a','b']

//值为布尔值
computed:&#123;
    id()&#123;
        return this.$route.query.id;
    &#125;,
    title()&#123;
        return this.$route.query.title;
    &#125;
&#125;
    
//值为函数
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(&#123;
    name:'xiangqing',
    params:&#123;
        id:xxx,
        title:xxx
    &#125;
&#125;)

this.$router.replace(&#123;
    name:'xiangqing',
    params:&#123;
        id:xxx,
        title:xxx
    &#125;
&#125;)

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)=>&#123;
    next()
    if(to.meta.isAuth)&#123;//判断当前路由是否需要激进型权限控制
        if(localStorage.getItem('school')==='atguigu')&#123;
               next();
        &#125;else&#123;
            alert('暂无权限查看');
        &#125;
    &#125;else&#123;
        next();//放行
    &#125;
&#125;)

//全局后置守卫,初始化执行,两次路由切换后执行
router.afterEach((to,from)=>&#123;
    if(to.meta.title)&#123;
           document.title=to.meta.title;//修改网页的title
       &#125;else&#123;
           document.title='vue_test'
       &#125;
&#125;)
  • 独享路由守卫: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