Vue CLI + Vue-router + Vuex

Vue CLI

什么是CLI?

Command-Line Interface 命令行界面,俗稱腳手架
vue-cli 可以快速搭建Vue開(kāi)發(fā)環(huán)境以及對(duì)應(yīng)的webpack配置

  • 腳手架依賴webpack,而webpack運(yùn)行需要node,所以要安裝NodeJs
  • NPM : Node Package Manager 為node的包管理工具
    安裝全局的Webpack
npm install webpack -g

安裝Vue CLI

npm install @vue/cli -g

Vue CLI3 初始化

vue create 項(xiàng)目名

Vue Router

  1. vue-router 基本使用
  2. vue-router 嵌套路由
  3. vue-router 參數(shù)傳遞
  4. vue-router 導(dǎo)航守衛(wèi)
  5. keep-alive
  6. https://router.vuejs.org/zh/

vue-router 基本使用

  1. 安裝vue-router

    npm install vue-router --save
    
  2. 在模塊工程中使用它

    2.1 導(dǎo)入路由對(duì)象,并調(diào)用Vue.use(VueRouter)
    2.2 創(chuàng)建路由實(shí)例,傳入路由映射配置
    2.3 在Vue實(shí)例中掛載創(chuàng)建的路由實(shí)例
    
  3. 使用vue-router的步驟

    3.1 創(chuàng)建路由組件
    3.2 配置路由映射(組件和路徑映射關(guān)系)
    3.3 使用路由(router-link,router-view)
    
/* src/router/index.js */
import Vue from 'vue'
import VueRouter from 'vue-router'

// 懶加載
const Home = () => import('../components/home')
const About = () => import('../components/about')

// 1.注入插件
Vue.use(VueRouter)

// 2.定義路由
const routes = [
    {
        path:'/',
        redirect:'/home'
    },
    {
        path:'/home',
        component:Home
    },
    {
        path:'/about',
        component:About
    }
]

// 3.創(chuàng)建router實(shí)例,默認(rèn)使用URL的hash
const router = new VueRouter({
    routes,
    mode:'history',     // 使用HTML5的history模式 (localhost:8080/home)
    linkActiveClass:'active'    // 修改路由激活添加的類名
})

// 4.導(dǎo)出router實(shí)例
export default router



/* src/main.js */
import Vue from 'vue'
import App from './App'
import router from './router'

new Vue({
    el:'#app',
    router,  // 掛載到Vue實(shí)例中
    render:h=>h(App)
})



/* src/components/home.vue */
// 創(chuàng)建路由組件
<template>
    <div>home</div>
</template>

<script>
    export default {
        name:'home'
    }
</script>

<style scoped>   
</style>



/* src/App.vue */
<template>
    <div id='app'>
        <div>App start</div>
        <router-link to='/home'>home</router-link>
        <router-link to='/about'>about</router-link>
        <router-view></router-view>
        <div>App end</div>
    </div>
</template>

<script>
export default {
    name:'App'
}
</script>

<style>
</style>

router-link 補(bǔ)充

to:指定跳轉(zhuǎn)路徑

tag:指定渲染成什么元素

replace:replace不會(huì)留下history記錄,所以在指定replace的情況下,后退鍵返回不能返回到上一個(gè)頁(yè)面中

active-class:當(dāng) router-link對(duì)應(yīng)的路由配對(duì)成功,會(huì)自動(dòng)給當(dāng)前元素設(shè)置一個(gè)router-link-active的class,設(shè)置active-class可以修改默認(rèn)的名稱

通過(guò)代碼跳轉(zhuǎn)路由

/* src/App.vue */
<template>
    <div id='app'>
        <div>App start</div>
      <div @click='toHome'>home</div>
      <div @click='toAbout'>about</div>
      <router-view></router-view>
      <div>App end</div>
    </div>
</template>

<script>
export default {
    name:'App',
    methods:{
        toHome(){
            this.$router.push('/home')
        },
        toAbout(){
            this.$router.push('/about')
        }
    }
}
</script>

<style>
</style>

動(dòng)態(tài)路由

/* src/router/index.js */
{
    path: '/user/:aid',
    component: User
}



/* src/App.vue */
<router-link to='/user/abc'>user</router-link>



/* src/components/user.vue */
<div>{{$route.params.aid}}</div>    /* abc */

嵌套路由

/* src/components/new1.vue */
<div>new1</div>

/* src/components/new2.vue */
<div>new2</div>



/* src/router/index.js */
const New1 = () => import('../components/new1')
const New2 = () => import('../components/new2')

{
        path:'/home',
        component:Home,
        children:[
            {
                path:'',
                redirect:'new1'
            },
            {
                path:'new1',
                component:New1 
            },
            {
                path:'new2',
                component:New2 
            }
        ]
},


/* src/components/home.vue */
<template>
    <div id='home'>
        <div>Home start</div>
        <router-link to='/home/new1'>new1</router-link>
        <router-link to='/about/new2'>new2</router-link>
        <router-view></router-view>
        <div>Home end</div>
    </div>
</template>


傳遞參數(shù)

params:(/router/abc)

配置路由的格式:/router/:id

傳遞的方式:在path后面跟上對(duì)應(yīng)的值

query:(/router/id=123)

配置路由的格式:/router

傳遞的方式:query的key作為傳遞方式

/* src/App.vue */
// 兩種傳參方式
<template>
    <div id='app'>
        <div>App start</div>
        <router-link
            :to="{
                path:'/home/' + 'abc',
                query:{name:'kevin',age:18}
            }"
        >home</router-link>
        <router-link to='/about'>about</router-link>
        <router-view></router-view>
        <div>App end</div>
    </div>
</template>

/* 代碼傳參 */
<script>
export default {
    name:'App',
    methods:{
        toHome(){
            this.$router.push({
                path:'/home/' + 'abc',
                query:{name:'kevin',age:18}
            })
        },
        toAbout(){
            this.$router.push('/about')
        }
    }
}
</script>

<style>
</style>

獲取參數(shù)

  • 使用了vue-router的應(yīng)用中,路由對(duì)象會(huì)被注入到每個(gè)組件中,賦值為this.$route,并且當(dāng)路由切換時(shí),路由對(duì)象會(huì)被更新
/* src/components/home.vue */
<template>
    <div id='home'>
        <div>params:{{$route.params}}</div>     // params:{"id":"abc"}
        <div>query:{{$route.query}}</div>       // query:{"name":"kevin","age":18}
    </div>
</template>


導(dǎo)航守衛(wèi)

vue-router 提供的導(dǎo)航守衛(wèi)用于監(jiān)聽(tīng)路由的進(jìn)入和離開(kāi)

全局守衛(wèi)(鉤子函數(shù))

beforeEach:路由即將改變前觸發(fā)(前置鉤子)

afterEach:路由改變后觸發(fā)(后置鉤子)

https://router.vuejs.org/zh/guide/advanced/navigation-guards.html#%E8%B7%AF%E7%94%B1%E7%8B%AC%E4%BA%AB%E7%9A%84%E5%AE%88%E5%8D%AB

/* 使用beforeEach修改標(biāo)題 */
/* src/router/index.js */
const routes = [
    {
        path:'/home',
        compontent:Home,
        meta:{
            title:'首頁(yè)'
        }
    },
    {
        path:'/about',
        compontent:About,
        meta:{
            title:'關(guān)于'
        }
    }
]

const router = new VueRouter({...})
                              
/**
 * to:即將要進(jìn)入的目標(biāo)對(duì)象
 * from:當(dāng)前導(dǎo)航即將要離開(kāi)的路由對(duì)象
 * next:調(diào)用該方法,才能進(jìn)入下一個(gè)鉤子,
 * afterEach不需要調(diào)用next方法
 */                     
router.beforeEach((to,from,next)=>{
    window.document.title = to.meta.title
    next()
})                              

補(bǔ)充

keep-alive 是 Vue 內(nèi)置組件,可以使被包含的組件保留狀態(tài),或避免重新渲染

include:字符串/正則表達(dá)式,只有匹配的組件會(huì)被緩存

exclude:字符串/正則表達(dá)式,匹配的組件不會(huì)被緩存

<keep-alive>
    <router-view>
        <!-- 所有路徑匹配到的組件都會(huì)緩存 -->
    </router-view>
</keep-alive>

Vuex

Vuex 是一個(gè)專為 Vue.js 應(yīng)用程序開(kāi)發(fā)的狀態(tài)管理模式

單頁(yè)面的狀態(tài)管理

State:狀態(tài)數(shù)據(jù)集合

View:視圖層,針對(duì)State的變化,顯示不同的信息

Actions:提交數(shù)據(jù),更改State

/* src/store/index.js */

import Vuex from 'vuex'
import Vue from 'vue'

Vue.use(Vuex)

const store = new Vuex.Store({
    state:{
        publicData:{name:'liang',age:18}
    },
    mutations:{
        showData(state){
            console.log(state.publicData)
        }
    }
})

export default store



/* main.js */

import store from './store'

new Vue({
    el: '#app',
    store,
    render: h => h(App)
})

  • 其他組件,通過(guò) this.store.state.屬性** 的方式來(lái)訪問(wèn)狀態(tài),通過(guò) **this.store.commit('mutation中方法') 來(lái)修改狀態(tài)
  • 注意:我們通過(guò)提交mutation的方式,而非直接改變store.state.count。這樣Vuex可以更準(zhǔn)確的追蹤狀態(tài)的變化,所以不要直接改變store.state.count的值。
image.png
  • state:存儲(chǔ)狀態(tài)
  • getters:可以理解為state的計(jì)算屬性,在組件中使用$sotre.getters.fun()
  • mutations:修改狀態(tài),同步的,在組件中使用$store.commit('fname',params),和自定義事件類似。
  • actions:異步操作。在組件中使用是$store.dispath('')
  • modules:store的子模塊,方便狀態(tài)管理而使用的。用起來(lái)和上面的一樣。

Getters

const store = mew Vue.Store({
    state:{
        numArr = [1,2,3,4,5,6,7,8,9]
    },
    getters:{
        getany: state => {
            return state.numArr.filter(num=>num > 3)   
       }
    }
})


// 利用callback傳遞參數(shù)
getters:{
    getany: state => {
        return (a,b) =>{
            state.numArr.filter(num=>(num + a) * b)   
        }
    }
}


Mutation

注意:只能通過(guò) 提交Mutation 來(lái)更新store的狀態(tài)

Mutation 不建議使用異步方法: (如果異步,devtools將不能很好的追蹤這個(gè)操作什么時(shí)候會(huì)被完成)

const store = mew Vue.Store({
    state:{
        numArr = [1,2,3,4,5,6,7,8,9]
    },
    mutations:{
        // 1. 定義函數(shù)
        change(state){
            state.numArr = ['a','b','c','d','e']
        }
    }
})


// 2. 其他組件, 提交函數(shù)
changArr(){
    this.$store.commit('change')
}



/*------------------傳遞參數(shù)(payload)------------------*/
mutations:{
    // 1. 定義函數(shù)
    change(state,payload){
        console.log(payload)
        state.numArr = ['a','b','c','d','e']
    }
}

// 2. 其他組件, 提交函數(shù)
changArr(){
    // 1.提交方式1
    this.$store.commit('change',something)
    // 2.提交方式2
    this.$store.commit({
        type: 'change',
        key: value
    })
}



/*------------------store添加新屬性------------------*/
// 1.使用 Vue.set(obj,'addKey',value)
// 2.用新對(duì)象給舊對(duì)象重新賦值
const store = new Vue.Store({
    state:{
        numArr = [1,2,3,4,5,6,7,8,9],
        info:{
            name: 'zhangsan',
            age: '18'
        }
    },
    mutations:{
        addInfo(state,payload){
            //0.錯(cuò)誤的賦值方法(使用該方法頁(yè)面做不到響應(yīng)式)
            // state.info['hobby'] = payload.hobby    錯(cuò)誤
            //1.使用 Vue.set(obj,'addKey',value)
            Vue.set(state.info,'hobby',payload.hobby)
            // 2.用新對(duì)象給舊對(duì)象重新賦值
            state.info = {...state.info,'hobby': payload.hobby}
        }
    }
})


Action

用于Vuex 處理異步操作,類似 Mutation

其他組件通過(guò) dispatch 提交 action,也支持payload

使用 Promise 進(jìn)行異步操作

const store = mew Vue.Store({
    state:{
        numArr = [1,2,3,4,5,6,7,8,9],
        info:{
            name: 'zhangsan',
            age: '18'
        }
    },
    mutations:{
        addInfo(state,payload){
            //0.錯(cuò)誤的賦值方法(使用該方法頁(yè)面做不到響應(yīng)式)
            // state.info['hobby'] = payload.hobby    錯(cuò)誤
            //1.使用 Vue.set(obj,'addKey',value)
            Vue.set(state.info,'hobby',payload.hobby)
            // 2.用新對(duì)象給舊對(duì)象重新賦值
            state.info = {...state.info,'hobby': payload.hobby}
        }
    },
    actions:{
        /* add(context.payload){
            // context 是和 store對(duì)象具有相同方法和屬性的對(duì)象
            setTimeout(()=>{
                context.commit('change',payload)
            },2000)
        }*/
        add(content){
            return new Promise((resolve,reject) => {
                setTimeout(()=>{
                    context.commit('change',payload)
                    resolve()
                },2000)
            })
        }
    }
})



// 其他組件
addInfo(){
    // this.$store.dispatch('add',{'hobby' : "coding"})
    this.$store.dispatch('add',{'hobby' : "coding"}).then(res =>{
        console.log("更新成功")
    }).catch(err =>{
        console.log(err)
    })
}

Module

使用 Module 來(lái)管理store(將store分成幾個(gè)模塊進(jìn)行管理)

const moduleA = {
    state:{...},
    getters:{...},
    mutations:{...},
    actions:{...}
}
               
const moduleB = {
    state:{...},
    getters:{...},
    mutations:{...},
    actions:{...}
}
               
const store = new Vuex.Store({
    modules:{
        a:moduleA,
        b:moduleB
    }        
})
             
             
// 參數(shù)

const moduleA = {
    actions:{
        add({state,getters,rootState},payload){
            console.log(state,getters,rootState)
            console.log(payload)
        }
    }
}
END
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容