03_12.用axios以及組件化做商品管理

1. 首先將文件夾進(jìn)行分類
組件化
2. 分析
  • 由上面的圖可以看出,我們先將功能進(jìn)行模塊化劃分,將公共部分提取出來,放到一個(gè)common的文件夾內(nèi),然后根據(jù)不同的頁面進(jìn)行創(chuàng)建不同的文件夾,詳細(xì)如上圖所示。
3. 源代碼展示
  • index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <link rel="stylesheet" href="style/main.css">
</head>
<body>
    <div id="app">
        <app-goods></app-goods>
    </div>

    <!-- vue的全局組件, 全局自定義指令, 全局過濾器必須在vue實(shí)例之前定義, 否則vue實(shí)例無法解決 -->
    <script src="./lib/vue.js"></script>
    <script src="./lib/axios.js"></script>

    <!-- 公共組件 -->
    <script src="./components/common/header.js"></script>
    <script src="./components/common/footer.js"></script>
    <script src="./components/common/list.js"></script>
    <script src="./components/common/search.js"></script>

    <!-- 頁面級別組件 -->
    <script src="./components/goods/goods.js"></script>
    <script src="./components/goods/add.js"></script>
    <script src="./components/home/home.js"></script>
    <script src="./components/login/login.js"></script>

    <!-- 導(dǎo)入過濾器 -->
    <script src="./filter/date.js"></script>

    <!-- 導(dǎo)入自定義指令 -->
    <script src="./directive/focus.js"></script>

    <!-- 入口 -->
    <script src="./main.js"></script>
</body>
</html>
  • style/main.css
.wrapper {
    width: 800px;
    margin: 20px auto;
}
.operation {
    margin-bottom: 10px;
    text-align: center;
    line-height: 20px;
    font-size: 18px;
}
.operation input {
    padding: 5px;
    border: 1px solid deepskyblue;
}
.operation button {
    border-radius: 3px;
    background-color: deepskyblue;
}
.search {
    text-align: left;
    line-height: 20px;
    font-size: 18px;
}
.search input {
    padding: 5px;
    border: 1px solid deeppink;
}
#tb{
    width: 800px;
    border-collapse: collapse;
    margin: 20px auto;
}
#tb th{
    background-color: #0094ff;
    color:white;
    font-size: 16px;
    padding: 5px;
    text-align: center;
    border: 1px solid black;
}
#tb td{
    padding: 5px;
    text-align: center;
    border: 1px solid black;
}
  • ./components/common/header.js
/*
 * @Author: Robyn 
 * @Date: 2017-11-12 19:27:25 
 * @Last Modified by:   Robyn 
 * @Last Modified time: 2017-11-12 19:27:25 
 */

Vue.component('app-header', {
    template: `
    <header>
        <h1>{{ title }}</h1>
        <p>{{ content }}</p>
    </header>`,
    props: ['title'],
    data: function() {
        return {
            content: '這是頭部文件內(nèi)容'
        };
    }
});
  • ./components/common/footer.js
/*
 * @Author: Robyn 
 * @Date: 2017-11-12 19:28:12 
 * @Last Modified by: Robyn
 * @Last Modified time: 2017-11-12 19:28:32
 */

Vue.component('app-footer', {
    template: `
    <footer>
        <p>{{ content }}</p>
        <address>{{ address }}</address>
    </footer>`,
    data: function() {
        return {
            content: '這里是尾部內(nèi)容',
            address: '北京市'
        };
    }
});
  • ./components/common/list.js
/*
 * @Author: Robyn 
 * @Date: 2017-11-12 19:29:30 
 * @Last Modified by:   Robyn 
 * @Last Modified time: 2017-11-12 19:29:30 
 */

Vue.component('app-list', {
    template: `
    <table id="tb">
        <tr>
            <th>編號</th>
            <th>名稱</th>
            <th>創(chuàng)建時(shí)間</th>
            <th>操作</th>
        </tr>
        <!-- 沒有數(shù)據(jù)才顯示, 有數(shù)據(jù)隱藏 -->
        <tr v-if="list.length == 0">
            <td colspan="4">列表無數(shù)據(jù)</td>
        </tr>
        <!-- 渲染商品列表 -->
        <tr v-for="item in list" >
            <td>{{ item.id }}</td>
            <td>{{ item.name }}</td>
            <td>{{ item.ctime | date }}</td>
            <td>
                <!-- @符號是v-on的簡寫方式 -->
                <a href="#" @click="deleteBtn(item.id)">刪除</a>
            </td>
        </tr>
    </table>`,

    props: ['list'],

    data: function() {
        return {};
    },

    methods: {
        // 子組件里面監(jiān)聽刪除按鈕的點(diǎn)擊事件, 但是不負(fù)責(zé)刪除操作, 
        // 而是當(dāng)收到點(diǎn)擊事件的時(shí)候, 告訴父親, 它要?dú)⒁坞S便
        deleteBtn(id) {
            this.$emit('del', id);
        }
    }
});
  • ./components/common/search.js
/*
 * @Author: Robyn 
 * @Date: 2017-11-12 19:30:12 
 * @Last Modified by:   Robyn 
 * @Last Modified time: 2017-11-12 19:30:12 
 */


Vue.component('app-search', {
    template: `
    <div class="search">
        <input type="text" placeHolder="請輸入篩選內(nèi)容" v-model="searchKey">
    </div>`,
    data: function() {
        return {
            searchKey: ''
        };
    },
    watch: {
        // 當(dāng)這個(gè)值變量時(shí), 我通過自定義事件通知父, 同時(shí)把最新的值也給傳過去
        searchKey() {
            this.$emit('change', this.searchKey);
        }
    }
});
  • ./components/goods/goods.js
/*
 * @Author: Robyn 
 * @Date: 2017-11-14 20:10:34 
 * @Last Modified by:   Robyn 
 * @Last Modified time: 2017-11-14 20:10:34 
 */
Vue.component('app-goods', {
    template: `
    <article>
        <app-header v-bind:title="'商品管理'"></app-header>
        <app-add-goods v-on:add="addGoods"></app-add-goods>
        <app-search v-on:change="search"></app-search>
        <app-list v-bind:list="searchGoodsList" v-on:del="deleteGoods"></app-list>
        <app-footer></app-footer>
    </article>
    `,
    data: function() {
        return {
            goodsList: [],
            searchKeyword: ''
        };
    },
    methods: {
        // 通過id刪除商品, 現(xiàn)在不光要?jiǎng)h除本地的數(shù)據(jù), 還要調(diào)用接口刪除服務(wù)器上的數(shù)據(jù)
        deleteGoods(delId) {
            axios.get(`http://vue.studyit.io/api/delproduct/${delId}`)
            .then((resp) => {
                // 當(dāng)服務(wù)器刪除成功后, 本地再刪除
                this.goodsList = this.goodsList.filter(
                    goods => goods.id != delId
                );
            });
        },
        // 接收搜索子組件傳遞過來的新值
        search(keyword) {
            this.searchKeyword = keyword;
        },
        // 獲取商品列表
        getGoods() {
            axios.get('http://vue.studyit.io/api/getprodlist')
            .then(
                (resp) => {this.goodsList = resp.data.message}
            );
        },
        // 添加商品, 接口請求成功后, 為了刷新頁面, 再手動(dòng)調(diào)用一下getGoods方法
        addGoods(name) {
            axios.post('http://vue.studyit.io/api/addproduct', `name=${name}`)
            .then(
                (resp) => {alert('添加成功'); this.getGoods()} 
            );
        }
    },
    computed: {
        // 搜索后的商品列表
        searchGoodsList() {
            return this.goodsList.filter(
                goods => goods.name === this.searchKeyword || this.searchKeyword == ''
            );
        }
    },
    // 數(shù)據(jù)可以使用了, 那么就發(fā)送請求
    created() {
        this.getGoods();
    }
});
  • ./components/goods/add.js
/*
 * @Author: Robyn 
 * @Date: 2017-11-14 20:12:37 
 * @Last Modified by:   Robyn 
 * @Last Modified time: 2017-11-14 20:12:37 
 */

Vue.component('app-add-goods', {
    template: `
    <div class="operation">
        <input type="text" placeholder="請輸入名稱" v-model="name">
        <button type="button" v-on:click="addGoods">添加數(shù)據(jù)</button>
    </div>`,
    data: function() {
        return {
            name: ''
        };
    },
    methods: {
        // 把值發(fā)送給父使用
        addGoods() {
            this.$emit('add', this.name);
        }
    }
});
  • ./components/home/home.js
/*
 * @Author: Robyn 
 * @Date: 2017-11-12 19:31:33 
 * @Last Modified by:   Robyn 
 * @Last Modified time: 2017-11-12 19:31:33 
 */

Vue.component('app-home', {
    template: `
    <article>
        <app-header v-bind:title="'首頁'"></app-header>
        <app-footer></app-footer>
    </article>
    `,
    data: function() {
        return {};
    }
});
  • ./components/login/login.js
/*
 * @Author: Robyn 
 * @Date: 2017-11-12 19:32:08 
 * @Last Modified by:   Robyn 
 * @Last Modified time: 2017-11-12 19:32:08 
 */

Vue.component('app-login', {
    // 每個(gè)組件的模版, 必須要使用一個(gè)根元素包裹起來
    template: `
    <article>
        <app-header v-bind:title="'登陸'"></app-header>
        <app-footer></app-footer>
    </article>
    `,
    data: function() {
        return {};
    }
});
  • ./filter/date.js
/*
 * @Author: Robyn 
 * @Date: 2017-11-12 19:32:43 
 * @Last Modified by:   Robyn 
 * @Last Modified time: 2017-11-12 19:32:43 
 */

// 實(shí)現(xiàn)一個(gè)處理日期的過濾器
Vue.filter('date', function(time) {
    var date = new Date(time);
    return `${ date.getFullYear() }-${ date.getMonth() + 1 }-${ date.getDate() }`;
});
  • ./directive/focus.js
/*
 * @Author: Robyn 
 * @Date: 2017-11-12 19:33:19 
 * @Last Modified by:   Robyn 
 * @Last Modified time: 2017-11-12 19:33:19 
 */

// 實(shí)現(xiàn)一個(gè)全局自動(dòng)焦點(diǎn)指令
Vue.directive('focus', {
    inserted(node) {
        node.focus();
    }
});
  • ./main.js
/*
 * @Author: Robyn 
 * @Date: 2017-11-12 19:33:49 
 * @Last Modified by:   Robyn 
 * @Last Modified time: 2017-11-12 19:33:49 
 */

new Vue({
    el: '#app',
    data: {}
});
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,327評論 6 537
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,996評論 3 423
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,316評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,406評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,128評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,524評論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,576評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,759評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,310評論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,065評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,249評論 1 371
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,821評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,479評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,909評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,140評論 1 290
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,984評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,228評論 2 375

推薦閱讀更多精彩內(nèi)容