【前端面考面試官系列】入門Vue全家桶

(給達達前端加星標,提高前端技能)javascript

面試官問:Vue如何安裝的呢?php

達達回答:Vue的安裝能夠從兩個方面進行安裝,第一種是CDN引入,第二種是NPM安裝。css

CDN引入html

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

NPM安裝前端

npm install vue

面試官問,如何建立Vue項目?vue

達達寫下代碼:java

建立項目node

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue入門之Helloworld</title>
    <!--引入Vue庫-->
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
    <!--建立一個Div-->
    <div id="app">
        <!--Vue的模板的綁定數據的方法,用兩對花括號進行綁定Vue中的數據對象的屬性 -->
        {{message}}
    </div>


    <!--建立Vue的對象,並把數據綁定到上面建立好的div上去。-->
    <script type="text/javascript">
        var app=new Vue({ // 建立Vue對象。Vue的核心對象。
            el:'#app', // el屬性:把當前Vue對象掛載到 div標籤上,#app是id選擇器
            data:{    // data: 是Vue對象中綁定的數據
                message:'hello Vue!' // message 自定義的數據
            }
        })
</script>
</body>
</html>

輸出的結果:react

hello Vue!

面試官問:v-if和v-show的區別是?webpack

達達回答:

內部指令

v-if用於顯示與隱藏的元素

<div v-if="isShow">達達前端</div>

v-else,v-if不是它,就是它v-else

<div v-else>達達前端</div>

v-show

<div v-show="isShow">你好</div>

v-else-if

<div v-if="type === 'A'">A</div>
<div v-else-if="type === 'B'">B</div>
<div v-else-if="type === 'C'">C</div>
<div v-else>Not A/B/C</div>

v-if和v-show的區別是:

v-if用於元素的被銷燬和重建,使用這個指令開銷較爲高,在運行過程當中,儘可能用在不多改變時的狀況下使用。v-if元素銷燬和存在

v-show的用法,這個指令的使用開銷較小,在常頻繁地切換使用

面試官問:內部指令的用法有哪些,怎麼用呢?

達達回答:好,慢慢講述。

v-for的用法

<!-- 模板 -->
<div id="app">
    <ul>
        <li v-for="item in items">
            {{item}}
        </li>
    </ul>
</div>


<!--JS代碼 -->
<script type="text/javascript">
    var app=new Vue({
        el:'#app',
        data:{
            items:[ 1, 2, 3, 4]
        }
    })
</script>

對象遍歷

<!-- 模板 -->
<div id="app">
    <ul>
        <li v-for="(value, key, index) in object">
        {{ index }}. {{ key }} - {{ value }}
        </li>
    </ul>
</div>


<!--JS代碼 -->
<script type="text/javascript">
    var app=new Vue({
        el:'#app',
        data:{
            object: {
                firstName: 'dada',
                lastName: 'qianduan'
            }
        }
    })
</script>

v-text的出現爲了解決{{xx}}這個取值的問題,當網絡很慢的狀況下,或者是運行時出錯的狀況下,頁面顯示爲{{xxx}}。

<div>{{ message }}</div>
<!-- 同樣的 -->
<div v-text="message"></div>

v-html指令是用於輸出html代碼

<span v-html="msgHtml"></span>

v-on的用法

// html
<div>{{count}}</div>
<button v-on:click="add">加</button>


// JS
data:{
    count: 1
},
methods: {
    add() {
        this.count++;
    }
}

縮寫

<button @click="add">加</button>

v-model的用法,model都須要在data中聲明初始值:

data: {
    count: 1,
}

input的用法

<input type="text" v-model="message">

textarea

<textarea  cols="30" rows="10" v-model="message"></textarea>

checkbox

<input type="checkbox" id="first" value="1" v-model="status">
<label for="first">有效</label>


<input type="checkbox" id="second" value="2" v-model="status">
<label for="second">無效</label>


<div>狀態:{{status}}</div>

radio

<input type="radio" id="one" value="男" v-model="sex">
<label for="one">男</label>


<input type="radio" id="two" value="女" v-model="sex">
<label for="one">女</label>


<div>性別:{{sex}}</div>

select

<select v-model="selected">
    <option disabled value="">請選擇</option>
    <option>A</option>
    <option>B</option>
    <option>C</option>
</select>


<div>Selected: {{ selected }}</div>

v-bind方法

// html
<img v-bind:src="imgSrc"  width="200px">


// js
data: {    
    imgSrc:''
}

縮寫

<img :src="imgSrc"  width="200px">

v-pre方法,用這個指令能夠直接跳過vue的編譯,直接輸出原始值,若是在標籤中加入v-pre就不會輸出vue中的data值。

<div v-pre>{{message}}</div>

v-cloak能夠在vue渲染時指定的整個dom後才進行顯示,必須和css樣式一塊兒用

// css
[v-cloak] {
    display: none;
}


// html
<div v-cloak>{{message}}</div>

v-once只能顯示一次,第一次渲染的值就不會改變了

<div v-once>{{message}}</div>

面試官問:你知道Vue生命週期嗎?

達達回答:

new Vue() 實例化對象,init events & lifecycle 初始化,事件和生命週期

beforeCreate組件實例剛被建立,尚未實例化以前,執行一些初始化的操做,能夠製做加載動畫

init injections & reactivity 初始化,依賴注入和校驗

created組件實例建立完成,屬性已經綁定,可是dom尚未生成,$el屬性還不存在,頁面未被展現,結束加載動畫,發起異步網絡請求

has"el" option? no 判斷是否存在el屬性,若是有,則繼續編譯,若是沒有,則中止編譯,生命週期結束,知道在該vue實例上調用vm.$mount(el),即被喚醒繼續執行編譯,若是註釋掉「el」,等程序到create就中止了

判斷是否有template,若是有,則將其編譯成render函數,若是沒有,則將外部的HTML做爲模板編譯,template中的模板優先級高於outer html 的優先級。

yes的路線,compile template into render function

若是tremplate中組件的話,執行render方法渲染組件內容

compile el's outerhtml as template

beforeMount,完成虛擬dom配置,模板已經被編譯,把data裏面的數據和模板生成html,此時尚未掛載html到頁面上

create vm.$el and replace "el" with it,給vue實例對象添加$el成員,而且替換掉掛載的dom元素

mounted,用上面編譯好的html內容替換el屬性指向dom對象,方法結束後,dom結構完成,頁面顯示出來,發起網絡請求

Mounted,when data changes,beforeUpdate,當vue發現data中的數據發生了改變,會觸發對應組件的從新渲染,通常在組件發生更新以前,調用這個函數,頁面還不會展現修改的內容,但虛擬dom已經配置修改

virtual dom re-render and patch,從新渲染虛擬dom並經過diff算法對比vonde節點差別更新真實dom,updated,組件更新後,此方法執行後,修改後的頁面展示出來,即爲view從新渲染,數據更新

when wm.$destroy() is called,beforeDestroy,組件實例銷燬前調用,實例仍然徹底可用

teardown watchers, child components and event listeners 拆卸觀察者,子組件,事件監聽者

destroyed,在vue實例銷燬後調用,實例指示的全部東西都會被解除綁定,全部的事件監聽都會被移除,全部的子實例都會被銷燬

面試官問:在vue中經常使用的語句有哪些

達達回答:好的,請認真聽講

computed計算屬性,用於對原數據進行修改

computed: {
    newPrice () {
        return '¥' + this.price + '元';
    }
}

methods方法屬性,用於綁定方法

methods:{
    add (num) {
        this.count += num;
    }
}

watch數據變化監聽器

watch: {
    question(val, oldVal) {
        console.log('new: %s, old: %s', val, oldVal);
    }
}

filters 過濾器

filters: {
    filterA(value) {
        return value.toUpperCase();
    }
}

mixins用於減小代碼污染,減小代碼量,實現代碼重用

var addLog={
    updated:function(){
        console.log("數據放生變化,變化成"+this.count+".");
    }
}


var app = new Vue({
    el:'#app',
    data:{
        count: 100
    },
    // 混入
    mixins: [addLog]
})

extends用於擴展,對構造器進行擴展

var extendObj ={
    created: function(){
        console.log("我是");
    }
}


var app = new Vue({
    el:'#app',
    data:{
    },
    // 擴展
    extends: extendObj
})

面試官問,你知道哪些實例事件嗎?

達達回答,vue有實例屬性,實例方法,實例事件

$on接收兩個參數,第一個參數是調用時的事件名稱,第二個參數是一個匿名方法


app.$on('reduce',function(){
    console.log('執行了reduce()');
    this.count--;
});


app.$once('reduceOnce',function(){
    console.log('只執行一次的方法');
    this.count--;
});


function off(){
    console.log('關閉事件');
    app.$off('reduce');
}


function reduce() {
    // 事件調用
    console.log('emit事件調用');
    app.$emit('reduce');
}

面試官問:你知道自定義指令嗎

達達回答:知道吧

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue入門之自定義指令</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
    <div v-test="color">
        {{num}}
    </div>
</div>
<button onclick="unbindApp()">解綁</button>


<script type="text/javascript">
function unbindApp() {
    app.$destroy();
}


// 自定義指令
Vue.directive("test",{
    //被綁定
    bind:function (el, binding, vnode) {
        console.log("1-bind 被綁定");
        console.log("el:",el);
        console.log("binding:",binding);
        console.log("vnode:",vnode);
        el.style.color = binding.value;
    },
    //被插入
    inserted:function (el, binding, vnode) {
        console.log("2-inserted 被插入");
    },
    //更新
    update:function (el, binding, vnode) {
        console.log("3-update 更新");
    },
    //更新完成
    componentUpdated:function (el, binding, vnode) {
        console.log("4-componentUpdated 更新完成");
    },
    //解綁
    unbind:function (el, binding, vnode) {
        console.log("5-unbind 解綁");
    }
});


var app = new Vue({
    el:'#app',
    data:{
        num: 123,
        color:'red'
    }
})
</script>
</body>
</html>

面試官問:你用過組件嗎?

達達回答,用過的

組件全局註冊

Vue.component('button-counter', {
    data: function () {
        return {
            count: 0
        }
    },
    template: '<button v-on:click="count++">全局組件: {{ count }}</button>'
});


new Vue({
    el: '#app'
});


<button-counter></button-counter>

組件局部註冊

new Vue({
    el: '#app',
    components:{
        "button-inner":{
            data: function() {
                return {
                    inner: 0
                }
            },
            template: '<button v-on:click="inner++">局部組件: {{ inner }}</button>'
        }
    }
});


<button-inner></button-inner>

props屬性傳值

new Vue({
        el: '#app',
        components:{
            "button-props":{
                template:`
                <div >
                參數1: {{ da }}:---參數2: 
                {{fromHere}}
                </div>
                `,
                props:['da', 'fromHere']
            }
        }
    });


// html使用
<button-props da="da" from-here="world"></button-props>


props中須要駝峯取值

父子組件

// 子組件
var city = {
    template:`<div>dada</div>`
}
// 父組件
var parent = {
    template:
        `<div>
            <p> dadada!</p>
            <city></city>
        </div>`,
    components:{
        "city": city
    }
}


// 實例化
new Vue({
    el: '#app',
    // 定義局部組件
    components:{
        // 組件註冊
        "parent": parent
    }
});


// html使用
<parent></parent>

面試官:你瞭解模板嗎?

達達回答:還好

<div id="app">
</div>


<script type="text/javascript">
    // 實例化
    new Vue({
        el: '#app',
        data: {
            message: 'hello'
        },
        template:`<h1 >模板</h1>`
    });
</script>

<div id="app">
    <template id="demo2">
        <h2 >template模板</h2>
    </template>
</div>


<script type="text/javascript">
    // 實例化
    new Vue({
        el: '#app',
        data: {
            message: 'hello'
        },
        template:'#demo2'
    });
</script>

<div id="app">
</div>


<script type="x-template" id="demo3">
    <h2 >script標籤模板</h2>
</script>


<script type="text/javascript">
    // 實例化
    new Vue({
        el: '#app',
        data: {
            message: 'hello'
        },
        template:'#demo3'
    });
</script>

面試問:你瞭解插槽不?

達達回答:插槽就是slot,是組件的一塊Hmtl模板

<div id="app">
    <children>
        <span>123</span>
    </children>
</div>


<script type="text/javascript">
    var app = new Vue({
        el: '#app',
        components: {
            children: {
                template: "<button><slot></slot>單個插槽</button>"
            }
        }
    });
</script>

具名插槽slot,具名插槽能夠在一個組件中出現n次

<div id="app">
    <children>
        <span slot="first" @click="toknow">123</span>
        <span slot="second">456</span>
    </children>
</div>


<script type="text/javascript">
    var app = new Vue({
        el: '#app',
        methods: {
            toknow: function () {
                console.log("dada");
            }
        },
        components: {
            children: {
                template: "<button>
                <slot name='first'>
                </slot>
                具名插槽
                <slot name='second'>
                </slot>
                </button>"
            }
        }
    });
</script>

做用域插槽slot

<div id="app">
    <!-- 將數據傳遞給組件 -->
    <tb-list :data="data">
        <template slot-scope="scope">
            <p>索引:{{JSON.stringify(scope)}}</p>
            <p>索引:{{scope.$index}}</p>
            <p>姓名:{{scope.row.name}}</p>
            <p>年齡: {{scope.row.age}}</p>
            <p>性別: {{scope.row.sex}}</p>
        </template>
    </tb-list>
</div>


<script type="text/javascript">
    var app = new Vue({
        el: '#app',
        data: {
            data: [{
                name: 'dada',
                age: '12',
                sex: 'man'
            }]
        },
        components: {
            // 做用域slot
            'tb-list': {
                template:
                    `<ul>
                        <li v-for="(item, index) in data">
                            <slot :row="item" :$index="index">
                            </slot>
                        </li>
                    </ul>`,
                // 獲取值
                props: ['data']
            }
        }
    });
</script>

面試官問:你用過vue-cli嗎?說一說

達達回答:好的

vue-cli安裝,第一用npm安裝

npm -v

vue-cli安裝

npm install vue-cli -g

vue -V


-g表明全局安裝,而後查看版本

初始化項目

用vue init命令來初始化項目


vue init <template-name> <project-name>


init:表示要用vue-cli來初始化項目


<template-name>:表示模板名稱


vue-cli官方提供的5種模板


webpack


webpack-simple


browserify


browserify-simple


simple


<project-name>:標識項目名稱,用戶根據本身的項目來起名字。

項目初始化

vue init webpack my-vue-demo

Project name:項目名稱


Project description:項目描述


Author:做者


Install vue-router? 是否安裝vue的路由插件,須要安裝,選擇Y


Use ESLint to lint your code? 是否用ESLint來限制你的代碼錯誤和風格。不須要輸入n,須要選擇y


setup unit tests with Karma + Mocha? 是否須要安裝單元測試工具


Setup e2e tests with Nightwatch? 是否安裝e2e來進行用戶行爲模擬測試

運行項目

npm run dev


npm run build

面試官問:你瞭解vue-router嗎?說一說

達達回答,嗯,瞭解。

安裝

npm install vue-router --save

核心文件

import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'


// Vue全局使用Router
Vue.use(Router)


export default new Router({
  routes: [                //配置路由,這裏是個數組
    {                        //每個連接都是一個對象
      path: '/',            //連接路徑
      name: 'HelloWorld',        //路由名稱,
      component: HelloWorld     //對應的組件模板
    }
  ]
})

使用

import Vue from 'vue'
import App from './App'
import router from './router'


Vue.config.productionTip = false


new Vue({
  el: '#app',
  router, // 注入框架中
  components: { App },
  template: '<App/>'
})

頁面跳轉

<router-link to="/">[顯示字段]</router-link>


<p>導航 :
   <router-link to="/">首頁</router-link>
   <router-link to="/hello">hello</router-link>
</p>

編程式導航

this.$router.push('/xxx')


<button @click="goHome">回到首頁</button>


export default {
    name: 'app',
    methods: {
        goHome(){
            this.$router.push('/home');
        }
    }
}


//  同於 history.back()
this.$router.go(-1)
// 同於 history.forward()
this.$router.go(1)

路由嵌套

<template>
    <div class="hello">
        <h1>{{ msg }}</h1>
 
        <p>導航 :
            <router-link to="/home">首頁</router-link> | 
            <router-link to="/home/one">-子頁面1</router-link> |
            <router-link to="/home/two">-子頁面2</router-link>
        </p>


        <router-view/>
    </div>
</template>


<script>
export default {
    name: 'Home',
    data () {
        return {
            msg: 'dada!'
        }
    }
}
</script>


<style scoped>
</style>

子頁面

<template>
    <div class="hello">
        <h1>{{ msg }}</h1>
    </div>
</template>
<script>
export default {
    name: 'One',
    data () {
        return {
            msg: 'Hi, I am One Page!'
        }
    }
}
</script>


<style scoped>
</style>


<template>
    <div class="hello">
        <h1>{{ msg }}</h1>
    </div>
</template>
<script>
export default {
    name: 'Two',
    data () {
        return {
            msg: 'Hi, I am Two Page!'
        }
    }
}
</script>


<style scoped>
</style>

路由配置

import Vue from 'vue'
import Router from 'vue-router'
import Home from '@/components/Home'
import One from '@/components/One' 
import Two from '@/components/Two'


Vue.use(Router)


export default new Router({
    routes: [
    {
        path: '/', // 默認頁面重定向到主頁
        redirect: '/home'
    },
    {
        path: '/home', // 主頁路由
        name: 'Home',
        component: Home,
        children:[ // 嵌套子路由
            {
                path:'one', // 子頁面1
                component:One
            },
            {
                path:'two', // 子頁面2
                component:Two
            },
        ]
    }
    ]
})

路由傳遞參數

<router-link :to="{name:xxx, params: {key:value}}">
dada
</router-link>

<router-link :to="{name: 'one', params:{username:'123'}}">
子頁面
</router-link>

{
    path:'one', // 子頁面
    name: 'one', // 路由名稱-命名路由
    component:One
}

<h2>{{$route.params.username}}</h2>

url中傳遞參數

{
    path:'/home/two/:id/:name', // 子頁面
    component:Two
},

<p>ID:{{ $route.params.id}}</p>
<p>名稱:{{ $route.params.name}}</p>

<router-link to="/home/two/1/達達">子頁面</router-link>

編程式導航帶參數

{
    path:'/home/three', // 子頁面
    name: 'three',
    component:Three
}

<p>ID:{{ $route.params.id}}</p>
<p>名稱:{{ $route.params.name}}</p>

<button @click="toThreePage">頁面-params傳參</button>


// script
methods: {
    toThreePage() {
        this.$router.push(
        {
        name: 'three', 
        params: {
        id: 1, 
        name: 'dada'
        }
        }
        )
    }
}

query傳參數

{
    path:'/home/three', // 子頁面
    name: 'three',
    component:Three
}

<p>ID:{{ $route.query.id}}</p>
<p>名稱:{{ $route.query.name}}</p>

<button @click="toThreePage">頁面-params傳參</button>


methods: {
    toThreePage() {
        this.$router.push(
        {path: '/home/three', query: {id: 1, name: 'da'}}
        )
    }
}

命名路由

{
    path: 'one', // 子頁面
    name: 'one', // 路由名稱-命名路由
    component: One // 頁面組件
}

// template跳轉調用
<router-link :to="{name: 'one'}">子頁面</router-link>


// router.push函數跳轉調用
router.push({ name: 'user'}})

import Vue from 'vue'
import Router from 'vue-router'
// 建立頁面組件
const Header = { template: '<div>Header</div>' }
const Left = { template: '<div>Left</div>' }
const Right = { template: '<div>Right</div>' }


Vue.use(Router)


export default new Router({
    routes: [
    {
        path: '/', // 主頁路由
        components: {
            default: Header,
            a: Left,
            b: Right
        }
    }
    ]
})


<template>
    <div id="app">
        <router-view />
        <router-view name="a" class="left" />
        <router-view name="b" class="right" />
    </div>
</template>


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


<style>
#app {
    text-align: center;
    color: #2c3e50;
    width: 500px;
    border: 1px solid red;
    margin: 0 auto;
}


.left,.right{
    float: left;
    width:48%;
    text-align: center;
    border:1px solid red
}
</style>

重定向

export default new Router({
    routes: [
    {
        path: '/', // 默認頁面重定向到主頁
        redirect: '/home' // 重定向
    },
    {
        path: '/home', // 主頁路由
        component: Home,
        children:[ // 嵌套子路由
            {
                path:'/home/two/:id/:name', // 子頁面
                component:Two
            },
            {
                path:'/home/three/:id/:name', // 子頁面
                name: 'three', // 路由名稱-命名路由
                redirect: '/home/two/:id/:name' // 重定向-傳遞參數
            },
        ]
    }
    ]
})

<router-link to="/">首頁</router-link> | 
<router-link to="/home/two/1/lisi">子頁面</router-link>  |
<router-link :to="{name: 'three', params: {id: 1, name: 'dada'}}">
子頁面
</router-link>

redirect: '/home' // 重定向-不帶參數

redirect: '/home/two/:id/:name' // 重定向-傳遞參數

別名

{
    path:'/one', // 子頁面
    component:One,
    alias: '/oneother'
}

<router-link to="/oneother">子頁面1</router-link>

過渡動畫

<transition name="fade" mode="out-in">
    <router-view />
</transition>

.fade-enter-active {
    transition: opacity .5s;
}


.fade-enter {
    opacity: 0;
}


.fade-leave {
    opacity: 1;
}


.fade-leave-active {
    opacity:0;
    transition: opacity .5s;
}

mode模式

export default new Router({
    mode: 'history', //mode模式
    routes: [...]
})

404

// 404
{
    path: '*',
    component: () => import('@/components/404')
}

路由鉤子,第一全局鉤子,第二,路由單獨鉤子,第三,組件內鉤子

const router = new VueRouter({ ... })


// 全局路由攔截-進入頁面前執行
router.beforeEach((to, from, next) => {
    next();
});


router.afterEach(() => {
 
});


export default router;

路由單獨鉤子

{
    path:'/home/one', // 子頁面
        component: One,
   
        beforeEnter: (to, from, next) => {
        console.log('進入前執行');
            next();
        }
}

組件內鉤子

<script>
export default {
    name: 'Two',
    data () {
        return {
            msg: 'dada'
        }
    },


    beforeRouteEnter(to, from, next) {
        console.log('進入enter路由鉤子')
        next()
    },


    beforeRouteLeave(to,from, next){
        console.log('進入leave路由鉤子')
        next()
    },


    beforeRouteUpdate(to, from, next) {
        console.log('進入update路由鉤子')
        console.log(to.params.id)
        next()
    }
}
</script>

路由

import Home from '@/components/Home'
{
        path: '/home',
        component: Home
}

面試官問:你瞭解vuex是什麼嗎?要不也說說

達達回答:好的。

vuex是一個爲 Vue.js 應用程序開發的狀態管理模式。採用集中式存儲管理應用的全部組件的狀態,以相應的規則保證狀態以一種可預測的方式發生變化。

單向數據流

vuex的核心

安裝

npm install vuex --save

使用

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const state = {
    count: 1
}
const mutations = {
    DA(state, n) {
        state.count += n;
    }
}
const getters = {
    count: function(state){
        return state.count;
    }
}
const actions ={
    // 觸發mutations中相應的方法-通常小寫
    add ({commit}, data) {
        commit('DA', data)
    }
}


const store = new Vuex.Store({
    state,
    mutations,
    getters,
    actions
});


export default store;

<h2>{{ $store.state.count }}</h2>

computed: {
    count() {
        return this.$store.state.count;
    }
}

computed: mapState({
    // es5寫法
    count: function (state) {
         return state.count;
     },
    // es6寫法
    count: state => state.count
})

數組獲取
computed: mapState(['count'])

computed: mapState({
    count: 'count'
})

<button @click="$store.commit('DA')">+</button>
const mutations = {
    // 狀態變動函數
    DA(state) {
        state.count++;
    }
}

每一個模塊擁有本身的 state、mutation、action、getter、甚至是嵌套子模塊,從上至下進行一樣方式的分割。

// 模塊A
const moduleA = {
  state: { ... },
  mutations: { ... },
  actions: { ... },
  getters: { ... }
}


// 模塊B
const moduleB = {
  state: { ... },
  mutations: { ... },
  actions: { ... }
}


// 組裝
const store = new Vuex.Store({
  modules: {
    a: moduleA,
    b: moduleB
  }
})


// 取值
store.state.a // -> moduleA 的狀態
store.state.b // -> moduleB 的狀態

面試官最後一問:你瞭解axios嗎?

達達回答:嗯,用過。

Axios 是基於 promise 的 HTTP 庫,用在瀏覽器和 node.js 中。就是前端最火最簡單的一個http請求解決方案。

安裝

npm install vuex --save

代碼封裝

import fetch from '@/util/fetch'
const TMPURL = ''; // url地址
const params = {}; // 參數
fetch.post(TMPURL + '/login/login', params);

import axios from 'axios';
const httpService = axios.create({
    baseURL: process.env.BASE_API, // 需自定義
    // 請求超時時間
    timeout: 3000 
});


// request攔截器
httpService.interceptors.request.use(
    config => {
        // 加入token
        if (true) { 
            config.headers['User-Token'] = '';
        }
        return config;
    }, 
    error => 
        Promise.reject(error);
    }
)


// respone攔截器
httpService.interceptors.response.use(
    response => {
        const res = response.data;
        if (res.statuscode != 1) {
            return Promise.reject({
                status: res.statuscode,
                message: res.message
            });
        } else {
            return response.data;
        }
    },


    error => {
         if (error && error.response) {
            switch (error.response.status) {
                case 400:
                    error.message = '錯誤請求';
                    break;
                case 401:
                    error.message = '未受權,請從新登陸';
                    break;
                case 403:
                    error.message = '拒絕訪問';
                    break;
                case 404:
                    error.message = '請求錯誤,未找到該資源';
                    break;
                case 405:
                    error.message = '請求方法未容許';
                    break;
                case 408:
                    error.message = '請求超時';
                    break;
                case 500:
                    error.message = '服務器端出錯';
                    break;
                case 501:
                    error.message = '網絡未實現';
                    break;
                case 502:
                    error.message = '網絡錯誤';
                    break;
                case 503:
                    error.message = '服務不可用';
                    break;
                case 504:
                    error.message = '網絡超時';
                    break;
                case 505:
                    error.message = 'http版本不支持該請求';
                    break;
                default:
                    error.message = `未知錯誤${error.response.status}`;
            }
        } else {
            error.message = "鏈接到服務器失敗";
        }
        return Promise.reject(error);
    }
)
/*
 *  get請求
 *  url:請求地址
 *  params:參數
 * */
export function get(url, params = {}) {
    return new Promise((resolve, reject) => {
        httpService({
            url: url,
            method: 'get',
            params: params
        }).then(response => {
            resolve(response);
        }).catch(error => {
            reject(error);
        });
    });
}


/*
 *  post請求
 *  url:請求地址
 *  params:參數
 * */
export function post(url, params = {}) {
    return new Promise((resolve, reject) => {
        httpService({
            url: url,
            method: 'post',
            data: params
        }).then(response => {
            resolve(response);
        }).catch(error => {
            reject(error);
        });
    });
}


/*
 *  文件上傳
 *  url:請求地址
 *  params:參數
 * */
export function fileUpload(url, params = {}) {
    return new Promise((resolve, reject) => {
        httpService({
            url: url,
            method: 'post',
            data: params,
            headers: { 'Content-Type': 'multipart/form-data' }
        }).then(response => {
            resolve(response);
        }).catch(error => {
            reject(error);
        });
    });
}


export default {
    get,
    post,
    fileUpload
}

推薦系列

推薦閱讀  點擊標題可跳轉

【面試Vue全家桶】vue前端交互模式-es7的語法結構?async/await

【面試須要-Vue全家桶】一文帶你看透Vue前端路由

【面試須要】掌握JavaScript中的this,call,apply的原理

2019年的每一天日更只爲等待她的出現,好好過餘生,慶餘年 | 掘金年度徵文

進來就是一家人【達達前端技術社羣⑥】

以爲本文對你有幫助?請分享給更多人

關注「達達前端」加星標,提高前端技能

在博客平臺裏,將來的路還很長,也但願本身之後的文章你們能多多支持,多多批評指正,咱們一塊兒進步,一塊兒走花路。

很是感謝讀者能看到這裏,若是這個文章寫得還不錯,以爲「達達」我有點東西的話,以爲我可以堅持的學習,以爲此人能夠交朋友的話, 求點贊,求關注,求分享,對暖男我來講真的

很是有用!

感謝閱讀,原創不易,喜歡就點個[在看] or [轉發朋友圈],這是我寫做最大的動力。

意見反饋

若本號內容有作得不到位的地方(好比:涉及版權或其餘問題),請及時聯繫咱們進行整改便可,會在第一時間進行處理。

這是一個有質量,有態度的公衆號

點關注,有好運

好文章,我在看❤️

相關文章
相關標籤/搜索