Skip to content

Vue

Vue生命周期

Vue指令

名称解释完全写法示例简写示例子属性
v-bind单向绑定v-bind<input v-bind:value />:<input :value />-
v-model双向绑定v-model<input v-model:value />

Vue组件通信

全局事件总线

消息订阅/发布

VueX

store.js内容

js
//该文件用于创建vuex中最为微信的store

//引入Vuex
import Vuex from 'vuex'
//引入Vue
import Vue from 'vue'
Vue.use(Vuex)

//准备actions——用于响应组件中的动作
const actions = {
    'jia':function(context,value){
        context.commit('JIA',value)
    },
    'jian':function(context,value){
        context.commit('JIAN',value)
    },
    'jiaOdd':function(context,value){
        if(context.state.sum % 2){
            context.commit("JIA",value)
        }
    },
    'jiaWait':function(context,value){
        setTimeout(() => {            
            context.commit("JIA",value)
        }, 2)
    }
}
//准备mutations——用于操作数据(state)
const mutations = {
    'JIA':function(state,value){
        state.sum +=value
    },
    'JIAN':function(state,value){
        state.sum -=value
    }
}
//准备state——用于存储数据
const state={
    sum:0
}
//准备getters——用于将state中的数据进行加工
const getters = {
    bigSum(state){
       return  state.sum *10
    }
}
//创建store
//暴露store
export default new Vuex.Store({
    actions,
    mutations,
    state,
    getters
})
//该文件用于创建vuex中最为微信的store

//引入Vuex
import Vuex from 'vuex'
//引入Vue
import Vue from 'vue'
Vue.use(Vuex)

//准备actions——用于响应组件中的动作
const actions = {
    'jia':function(context,value){
        context.commit('JIA',value)
    },
    'jian':function(context,value){
        context.commit('JIAN',value)
    },
    'jiaOdd':function(context,value){
        if(context.state.sum % 2){
            context.commit("JIA",value)
        }
    },
    'jiaWait':function(context,value){
        setTimeout(() => {            
            context.commit("JIA",value)
        }, 2)
    }
}
//准备mutations——用于操作数据(state)
const mutations = {
    'JIA':function(state,value){
        state.sum +=value
    },
    'JIAN':function(state,value){
        state.sum -=value
    }
}
//准备state——用于存储数据
const state={
    sum:0
}
//准备getters——用于将state中的数据进行加工
const getters = {
    bigSum(state){
       return  state.sum *10
    }
}
//创建store
//暴露store
export default new Vuex.Store({
    actions,
    mutations,
    state,
    getters
})

mapState

用于帮助我们映射state中的数据为计算属性

js
mapState({})
mapState({})
js
mapState([])
mapState([])
js
computed:{
    //借助mapState生成计算属性:sum、school、subject(对象写法)
    ...mapState({sum:'sum',school:'school'}),
    //借助mapState生成计算属性:sum、school、subject(数组写法)
    ...mapState(['sum','school']),
}
computed:{
    //借助mapState生成计算属性:sum、school、subject(对象写法)
    ...mapState({sum:'sum',school:'school'}),
    //借助mapState生成计算属性:sum、school、subject(数组写法)
    ...mapState(['sum','school']),
}

mapGetters

js
mapGetters({})
mapGetters({})
js
mapGetters([])
mapGetters([])
js
computed:{
    //借助mapGetters生成计算属性:sum、school、subject(对象写法)
    ...mapGetters({sum:'sum',school:'school'})
    //借助mapGetters生成计算属性:sum、school、subject(数组写法)
    ...mapGetters(['sum','school'])
}
computed:{
    //借助mapGetters生成计算属性:sum、school、subject(对象写法)
    ...mapGetters({sum:'sum',school:'school'})
    //借助mapGetters生成计算属性:sum、school、subject(数组写法)
    ...mapGetters(['sum','school'])
}

mapActions

用于帮助生成与actions对话的方法,即:包含$store.dispatch(xxx)的函数

js
mapActions({})
mapActions({})
js
mapActions([])
mapActions([])
js
methods:{
    //借助mapActions生成:increamentOdd、decrementWait(对象写法)
    ...mapGetters({increamentOdd:'jiaOdd',decrementWait:'jiaWait'})
    //借助mapActions生成:increamentOdd、decrementWait(数组写法)
    ...mapGetters(['increamentOdd','decrementWait'])
}
methods:{
    //借助mapActions生成:increamentOdd、decrementWait(对象写法)
    ...mapGetters({increamentOdd:'jiaOdd',decrementWait:'jiaWait'})
    //借助mapActions生成:increamentOdd、decrementWait(数组写法)
    ...mapGetters(['increamentOdd','decrementWait'])
}

mapMutations

用于帮助生成与mutations对话的方法,即:包含$store.commit(xxx)的函数

js
mapMutations({})
mapMutations({})
js
mapMutations([])
mapMutations([])
js
methods:{
    //借助mapMutations生成:increment、decrement(对象写法)
    ...mapMutations({increment:'JIA',decrement:'JIAN'})
    //借助mapMutations生成:increamentOdd、decrementWait(数组写法)
    ...mapMutations(['JIA','JIAN'])
}
methods:{
    //借助mapMutations生成:increment、decrement(对象写法)
    ...mapMutations({increment:'JIA',decrement:'JIAN'})
    //借助mapMutations生成:increamentOdd、decrementWait(数组写法)
    ...mapMutations(['JIA','JIAN'])
}

WARNING

mapActions与mapMutations使用时,若需要传递参数,需要在模板绑定事件时传递好参数,否则参数是对象事件

Vuex模块化

store写法

TIP

注意这里使用了命名空间namespaced,为开启状态

如果不写默认为false

未配置命名空间时,组件使用中...mapState('countAbout',{'sum':'sum'})段中的'countAbout就不能使用了,会报错'

只能在模板中加上[模块名].调用

js
//该文件用于创建vuex中最为微信的store
//引入Vuex
import Vuex from 'vuex'
//引入Vue
import Vue from 'vue'
Vue.use(Vuex)

//模块1
const countAbout = {
    namespaced:true,
    //准备actions——用于响应组件中的动作
    actions:{
        'jiaOdd': function (context, value) {
            if (context.state.sum % 2) {
                context.commit("JIA", value)
            }
        },
        'jiaWait': function (context, value) {
            setTimeout(() => {
                context.commit("JIA", value)
            }, 2000)
        }
    },
    //准备utations——用于操作数据(state)
    mutations : {
        'JIA': function (state, value) {
            state.sum += value
        },
        'JIAN': function (state, value) {
            state.sum -= value
        }
    },
    //准备state——用于存储数据
    state:{
        sum: 9
    },
    //准备getters——用于将state中的数据进行加工
    getters : {
        bigSum(state) {
            return state.sum * 10
        }
    }
}

//模块2
const personAbout = {
    namespaced:true,
    actions:{

    },
    mutations:{

    },
    state:{

    },
    getters:{

    },
}
//创建store
//暴露store
export default new Vuex.Store({
    //模块化引入
    modules:{
        countAbout,
        personAbout
    }
})
//该文件用于创建vuex中最为微信的store
//引入Vuex
import Vuex from 'vuex'
//引入Vue
import Vue from 'vue'
Vue.use(Vuex)

//模块1
const countAbout = {
    namespaced:true,
    //准备actions——用于响应组件中的动作
    actions:{
        'jiaOdd': function (context, value) {
            if (context.state.sum % 2) {
                context.commit("JIA", value)
            }
        },
        'jiaWait': function (context, value) {
            setTimeout(() => {
                context.commit("JIA", value)
            }, 2000)
        }
    },
    //准备utations——用于操作数据(state)
    mutations : {
        'JIA': function (state, value) {
            state.sum += value
        },
        'JIAN': function (state, value) {
            state.sum -= value
        }
    },
    //准备state——用于存储数据
    state:{
        sum: 9
    },
    //准备getters——用于将state中的数据进行加工
    getters : {
        bigSum(state) {
            return state.sum * 10
        }
    }
}

//模块2
const personAbout = {
    namespaced:true,
    actions:{

    },
    mutations:{

    },
    state:{

    },
    getters:{

    },
}
//创建store
//暴露store
export default new Vuex.Store({
    //模块化引入
    modules:{
        countAbout,
        personAbout
    }
})

组件使用:

vue
<template>
  <div>
    <h1>当前计数为:{{ sum}}</h1>
    <h1>当前计数为:{{ $store.state.countAbout.sum }}</h1>
    <h1>当前计数10倍为:{{ bigSum }}</h1>
    <select v-model.number="n">
        <option value="1">1</option>
        <option value="2">2</option>
        <option value="3">3</option>
    </select>
    <button @click="increment(n)">+</button>
    <button @click="decrement(n)">-</button>
    <button @click="incrementOdd(n)">当前求和为奇数再+</button>
    <button @click="incrementWait(n)">等一等再+</button>
  </div>
</template>

<script>
import { mapActions, mapGetters, mapMutations, mapState } from 'vuex';
export default {
    name:'Count-',
    data(){
        return{
            count:this.$store.state.sum,
            n:1,
        }
    },
    computed:{
        ...mapState('countAbout',{'sum':'sum'}),
        ...mapGetters('countAbout',{bigSum:'bigSum'})
    },
    methods:{
        ...mapMutations('countAbout',{increment:'JIA',decrement:'JIAN'}),
        ...mapActions('countAbout',{incrementOdd:'jiaOdd',incrementWait:'jiaWait'})
    }
}
</script>
<template>
  <div>
    <h1>当前计数为:{{ sum}}</h1>
    <h1>当前计数为:{{ $store.state.countAbout.sum }}</h1>
    <h1>当前计数10倍为:{{ bigSum }}</h1>
    <select v-model.number="n">
        <option value="1">1</option>
        <option value="2">2</option>
        <option value="3">3</option>
    </select>
    <button @click="increment(n)">+</button>
    <button @click="decrement(n)">-</button>
    <button @click="incrementOdd(n)">当前求和为奇数再+</button>
    <button @click="incrementWait(n)">等一等再+</button>
  </div>
</template>

<script>
import { mapActions, mapGetters, mapMutations, mapState } from 'vuex';
export default {
    name:'Count-',
    data(){
        return{
            count:this.$store.state.sum,
            n:1,
        }
    },
    computed:{
        ...mapState('countAbout',{'sum':'sum'}),
        ...mapGetters('countAbout',{bigSum:'bigSum'})
    },
    methods:{
        ...mapMutations('countAbout',{increment:'JIA',decrement:'JIAN'}),
        ...mapActions('countAbout',{incrementOdd:'jiaOdd',incrementWait:'jiaWait'})
    }
}
</script>

疑问

  1. 为什么data中存在一个

    count : this.$store.state.sum

    并且使用插值语法,无法在页面中显示,但是数据确实改变了?

    有数据代理方法,但是页面未解析?

    具体如下:

    vue
    <template>
      <div>
        <h1>当前计数为:{{ count}}</h1> 
        <h1>当前计数为:{{ $store.state.sum }}</h1>
        <h1>当前计数10倍为:{{ $store.getters.bigSum }}</h1>
        <select v-model.number="n">
            <option value="1">1</option>
            <option value="2">2</option>
            <option value="3">3</option>
        </select>
        <button @click="increment">+</button>
        <button @click="decrement">-</button>
        <button @click="incrementOdd">当前求和为奇数再+</button>
        <button @click="incrementWait">等一等再+</button>
      </div>
    </template>
    
    <script>
    export default {
        name:'Count-',
        data(){
            return{
                count:this.$store.state.sum,
                n:1,
            }
        },
        methods:{
            increment(){
                // this.count+=this.n
                console.log(this);
                this.$store.commit('JIA',this.n)
            },
            decrement(){
                // this.count-=this.n
                this.$store.commit('JIAN',this.n)
    
            },
            incrementOdd(){
                this.$store.dispatch('jiaOdd',this.n)
            },
            incrementWait(){
                setTimeout(()=>{
                    this.$store.dispatch('jiaWait',this.n)
                },1000)
            },
        }
    }
    </script>
    <template>
      <div>
        <h1>当前计数为:{{ count}}</h1> 
        <h1>当前计数为:{{ $store.state.sum }}</h1>
        <h1>当前计数10倍为:{{ $store.getters.bigSum }}</h1>
        <select v-model.number="n">
            <option value="1">1</option>
            <option value="2">2</option>
            <option value="3">3</option>
        </select>
        <button @click="increment">+</button>
        <button @click="decrement">-</button>
        <button @click="incrementOdd">当前求和为奇数再+</button>
        <button @click="incrementWait">等一等再+</button>
      </div>
    </template>
    
    <script>
    export default {
        name:'Count-',
        data(){
            return{
                count:this.$store.state.sum,
                n:1,
            }
        },
        methods:{
            increment(){
                // this.count+=this.n
                console.log(this);
                this.$store.commit('JIA',this.n)
            },
            decrement(){
                // this.count-=this.n
                this.$store.commit('JIAN',this.n)
    
            },
            incrementOdd(){
                this.$store.dispatch('jiaOdd',this.n)
            },
            incrementWait(){
                setTimeout(()=>{
                    this.$store.dispatch('jiaWait',this.n)
                },1000)
            },
        }
    }
    </script>

Vue路由

  1. 路由就是一组key-value的对应关系

  2. 多个路由,需要经过路由器的管理

vue-router的理解

vue的一个插件库,专门用来实现SPA应用

对SPA应用的理解

  1. 单页面web应用(single page web application,SPA)
  2. 整个应用只有一个完整的页面
  3. 点击页面中的导航链接不会刷新页面,只会做页面的局部更新
  4. 数据需要通过ajax请求获取

路由的理解

  1. 一个路由就是一组映射关系(key-value)
  2. key为路径,value可能是function或component

路由的分类

  1. 后端路由:

    1. 理解:value是function,用户处理客户端提交的请求
    2. 工作过程:服务器接收到一个请求时,根据请求路径找到匹配的函数来处理请求,返回响应数据
  2. 前端路由:

    1. 理解:value是component,用于展示页面内容
    2. 工作过程:当浏览器的路径改变时,对应的组件就会显示

基本使用

  1. 安装vue-router 注意,vue2使用@3,vue3使用@4

    js
    npm install vue-router
    npm install vue-router
  2. 应用插件:

    js
    import VueRouter from 'vue-router'
    Vue.use(VueRouter)
    import VueRouter from 'vue-router'
    Vue.use(VueRouter)
  3. 编写router配置项

    js
    //该文件专门用于创建应用的路由器
     import VueRouter from 'vue-router'
    
     //引入组件
     import About from '../components/About'
     import Home from '../components/Home'
    
    
     //创建一个路由器,并暴露
     export default new VueRouter({
         routes: [
             {
                 path:'/about',
                 component:About
             },
             {
                 path:'/home',
                 component:Home
             }
         ]
     })
    //该文件专门用于创建应用的路由器
     import VueRouter from 'vue-router'
    
     //引入组件
     import About from '../components/About'
     import Home from '../components/Home'
    
    
     //创建一个路由器,并暴露
     export default new VueRouter({
         routes: [
             {
                 path:'/about',
                 component:About
             },
             {
                 path:'/home',
                 component:Home
             }
         ]
     })
  4. 实现切换 active-class可配置高亮样式

    html
     <!-- 借助vue-router实现组件跳转 -->
     <router-link class="list-group-item"active-class="active" to="/about">About</router-link>
     <router-link class="list-group-item"active-class="active" to="/home">Home</router-link>
     <!-- 借助vue-router实现组件跳转 -->
     <router-link class="list-group-item"active-class="active" to="/about">About</router-link>
     <router-link class="list-group-item"active-class="active" to="/home">Home</router-link>
  5. 指定展示位置

    html
    <!-- 指定组件的呈现位置 -->
    <router-view></router-view>
    <!-- 指定组件的呈现位置 -->
    <router-view></router-view>

嵌套路由

TIP

  1. 路由组件通常存放在pages文件夹,一般组件通常存放在components文件夹
  2. 通过切换,"隐藏"了的路由组件,默认是被销毁掉的,需要的时候再去挂载
  3. 每个组件都有自己的$route属性,里面存储着自己的路由信息
  4. 整个应用只有一个router,可以通过组件的$router属性获取到
js
//该文件专门用于创建应用的路由器
import VueRouter from 'vue-router'

//引入组件
import About from '../pages/About'
import Home from '../pages/Home'
import News from '../pages/News'
import Message from '../pages/Message'


//创建一个路由器,并暴露
export default new VueRouter({
    routes: [
        {
            path:'/about',
            component:About
        },
        {
            path:'/home',
            component:Home,
            children:[
                {
                    //注意这里不要加["/"]
                    path:'news',//即不能写成'/news'
                    component:News,
                },
                {
                    path:'message',
                    component:Message,
                }
            ]
        }
    ]
})
//该文件专门用于创建应用的路由器
import VueRouter from 'vue-router'

//引入组件
import About from '../pages/About'
import Home from '../pages/Home'
import News from '../pages/News'
import Message from '../pages/Message'


//创建一个路由器,并暴露
export default new VueRouter({
    routes: [
        {
            path:'/about',
            component:About
        },
        {
            path:'/home',
            component:Home,
            children:[
                {
                    //注意这里不要加["/"]
                    path:'news',//即不能写成'/news'
                    component:News,
                },
                {
                    path:'message',
                    component:Message,
                }
            ]
        }
    ]
})

路由传参

传递参数query

html
<!-- 跳转并携带query参数,to的字符串写法 -->
<router-link to="/home/message/detail?id=666&title=你好">{{info.id}}</router-link>
<!-- 跳转并携带query参数,to的字符串写法 -->
<router-link to="/home/message/detail?id=666&title=你好">{{info.id}}</router-link>
html
<!-- 跳转并携带query参数,to的字符串写法 -->
<router-link :to="`/home/message/detail?id={{info.id}}&title={{info.title}}`">{{info.id}}</router-link>
<!-- 跳转并携带query参数,to的字符串写法 -->
<router-link :to="`/home/message/detail?id={{info.id}}&title={{info.title}}`">{{info.id}}</router-link>
html
<!-- 跳转并携带query参数,to的对象写法 -->
<router-link :to="{
        path:'/home/message/detile',
        query:{
            id:info.id,
            title:info.title
        }
    }"
>{{ info.title }}</router-link>
<!-- 跳转并携带query参数,to的对象写法 -->
<router-link :to="{
        path:'/home/message/detile',
        query:{
            id:info.id,
            title:info.title
        }
    }"
>{{ info.title }}</router-link>

传递参数params

html
<!-- 跳转并携带params参数,to的字符串写法 -->
<router-link :to="`/home/message/detail/{{info.id}}/{{info.title}}`">{{info.id}}</router-link>
<!-- 跳转并携带params参数,to的字符串写法 -->
<router-link :to="`/home/message/detail/{{info.id}}/{{info.title}}`">{{info.id}}</router-link>
html
<!-- 跳转并携带params参数,to的对象写法 -->
<router-link :to="{
        //这里必须是命名写法,否则会出错
        name:'xiangqing'
        params:{
            id:info.id,
            title:info.title
        }
    }"
>{{ info.title }}</router-link>
<!-- 跳转并携带params参数,to的对象写法 -->
<router-link :to="{
        //这里必须是命名写法,否则会出错
        name:'xiangqing'
        params:{
            id:info.id,
            title:info.title
        }
    }"
>{{ info.title }}</router-link>

WARNING

注意:此时的路由配置需要占位:

js
{
    path:'detile/:id/:title',//占位符写法
    component:Detile,
}
{
    path:'detile/:id/:title',//占位符写法
    component:Detile,
}

接收参数query

js
$route.query.id
$route.query.title
$route.query.id
$route.query.title

接收参数params

js
$route.params.id
$route.params.title
$route.params.id
$route.params.title

路由命名

只需要name配置

js
{
    name:'随意写,在写路径时可以作为表达式传递',
    path:'/about',
    component:About
},
{
    name:'随意写,在写路径时可以作为表达式传递',
    path:'/about',
    component:About
},

Vue注意事项