Vue构建单页应用最佳实战-2.X版

释放双眼,带上耳机,听听看~!

学习VUE 参考编写了一个:Vue构建单页应用最佳实战

上例是1.x版的,写了并不能运行,因此将其改进为2.x版的:

主要的不同在于:

  • 路由使用的变化

  • 事件传递的变化

详情介绍请看上面的链接,下面只放代码:

main.js

import Vue from 'vue';
import App from './App';
import Hello from './components/Hello.vue';
import Home from './components/Home.vue';
import TimeEntries from './components/TimeEntries.vue';
import LogTime from './components/LogTime.vue';

import VueRouter from 'vue-router';
import VueResource from 'vue-resource';

// 注册组件
Vue.use(VueResource);
Vue.use(VueRouter);

// 路由 
const routes = [{
        path: '/home',
        component: Home
    }, {
        path: '/time-entries',
        component: TimeEntries,
        children: [{
            path: 'log-time', // 这里前面不要/
            component: LogTime
        }]
    }

];
const router = new VueRouter({
    routes // (缩写)相当于 routes: routes
});

const app = new Vue({
    router,
    components: {
        app: App
    }

}).$mount('#app');
// router.start(App, '#app');

App.vue

<template>
    <div id="wrapper">
        <nav class="navbar navbar-default">
            <div class="container">
                <a class="navbar-brand" href="#"> <i class="glyphicon glyphicon-time"></i> 计划表 </a>
                <ul class="nav navbar-nav">
                    <li><router-link to="/home">首页</router-link></li>
                    <li><router-link to="/time-entries">计划列表</router-link></li>
                </ul>
            </div>
        </nav>
        <div class="container">
            <div class="col-sm-3">
               <sidebar :time="totalTime"></sidebar>
            </div>
            <div class="col-sm-9">
                <router-view v-on:deleteTime="deleteTime" v-on:timeUpdate="timeUpdate"></router-view>
            </div>
        </div>
    </div>
</template>

<script>
import Sidebar from './components/Sidebar.vue';

export default {
    name: 'app',
    components: {
        sidebar: Sidebar
    },
    data() {
        return {
            totalTime: 2
        }
    },
    methods: {
        deleteTime(timeEntry) {

            this.totalTime -= parseFloat(timeEntry.totalTime);
        },
        timeUpdate(timeEntry) {
            console.log('app');
            this.totalTime += parseFloat(timeEntry.totalTime);
        }
    },
    events: {
        timeUpdate(timeEntry) {
            this.totalTime += parseFloat(timeEntry.totalTime);
        },
        deleteTime(timeEntry) {

            this.totalTime -= parseFloat(timeEntry.totalTime);
        }
    }
}
</script>

<style>

</style>

components/Sidebar.vue

<template>
    <div class="panel panel-default">
        <div class="panel-heading">
            <h1 class="text-center">已有时长</h1> </div>
        <div class="panel-body">
            <h1 class="text-center">{{ time }} 小时</h1> </div>
    </div>
</template> 

<script>
    export default { 
        name : 'Sidebar',
        props: ['time'] 
    }
</script>

components/Home.vue

<template>
    <div class="jumbotron">
        <h1>任务追踪</h1>
        <p> <strong> <router-link to="/time-entries">创建一个任务</router-link> </strong> </p>
    </div>
</template>

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

components/TimeEntries.vue

<template>
    <div>
        <!-- <button v-if="$route.path !== '/time-entries/log-time'" v-link="'/time-entries/log-time'" class="btn btn-primary"> 创建 </button> -->
        <router-link v-if="$route.path !== '/time-entries/log-time'" to="/time-entries/log-time" class="btn btn-primary"> 创建 </router-link>
        <div v-if="$route.path === '/time-entries/log-time'">
            <h3>创建</h3> </div>
        <hr>
        <router-view v-on:timeUpdate="timeUpdate"></router-view>
        <div class="time-entries">
            <p v-if="!timeEntries.length"><strong>还没有任何任务</strong></p>
            <div class="list-group">
                <a class="list-group-item" v-for="timeEntry in timeEntries">
                    <div class="row">
                        <div class="col-sm-2 user-details">
                            <img :class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="timeEntry.user.image" class="avatar img-circle img-responsive" />
                            <p class="text-center"> <strong> {{ timeEntry.user.name }} </strong> </p>
                        </div>
                        <div class="col-sm-2 text-center time-block">
                            <h3 class="list-group-item-text total-time"> <i class="glyphicon glyphicon-time"></i> {{ timeEntry.totalTime }} </h3>
                            <p class="label label-primary text-center"> <i class="glyphicon glyphicon-calendar"></i> {{ timeEntry.date }} </p>
                        </div>
                        <div class="col-sm-7 comment-section">
                            <p>{{ timeEntry.comment }}</p>
                        </div>
                        <div class="col-sm-1">
                            <button class="btn btn-xs btn-danger delete-button" @click="deleteTimeEntry(timeEntry)"> X </button>
                        </div>
                    </div>
                </a>
            </div>
        </div>
    </div>
</template>

<script>
export default {
    data() {
        // 事先模拟一个数据 
        let existingEntry = {
            user: {
                name: '二哲',
                email: 'kodo@forchange.cn',
                image: 'https://sfault-avatar.b0.upaiyun.com/888/223/888223038-5646dbc28d530_huge256'
            },
            comment: '我的一个备注',
            totalTime: 2,
            date: '2016-11-03'
        }
        return {
            timeEntries: [existingEntry]
        }
    }, methods: {
        deleteTimeEntry(timeEntry) {
            //这个方法用于删除某一项计划 
            let index = this.timeEntries.indexOf(timeEntry);
            if (window.confirm('确定要删除吗?')) {
                this.timeEntries.splice(index, 1);                
                // this.$dispatch('deleteTime', timeEntry);
                this.$emit('deleteTime', timeEntry);
            }
        },
        timeUpdate(timeEntry) {
            console.log('time');
            console.log(timeEntry);
            this.timeEntries.push(timeEntry);
            // 继续触发上一级的
            this.$emit('timeUpdate', timeEntry);
        }
    }
}
</script>

<style>
.avatar {
    height: 75px;
    margin: 0 auto;
    margin-top: 10px;
    margin-bottom: 10px;
}

.user-details {
    background-color: #f5f5f5;
    border-right: 1px solid #ddd;
    margin: -10px 0;
}

.time-block {
    padding: 10px;
}

.comment-section {
    padding: 20px;
}
</style>

components/LogTime.vue

<template>
    <div class="form-horizontal">
        <div class="form-group">
            <div class="col-sm-6">
                <label>日期</label>
                <input type="date" class="form-control" v-model="timeEntry.date" placeholder="Date" /> </div>
            <div class="col-sm-6">
                <label>时间</label>
                <input type="number" class="form-control" v-model="timeEntry.totalTime" placeholder="Hours" /> </div>
        </div>
        <div class="form-group">
            <div class="col-sm-12">
                <label>备注</label>
                <input type="text" class="form-control" v-model="timeEntry.comment" placeholder="Comment" /> </div>
        </div>
        <button class="btn btn-primary" @click="saveNewLog">保存</button>
        <router-link to="/time-entries" class="btn btn-danger">取消</router-link>
        <hr>
    </div>
</template>

<script>
export default {
    data() {
        return {
            //模拟一个默认值 
            timeEntry: {
                user: {
                    name: '二哲',
                    email: 'kodo@forchange.cn',
                    image: 'https://sfault-avatar.b0.upaiyun.com/888/223/888223038-5646dbc28d530_huge256'
                }
            }
        }
    },
    methods: {
        // 添加新计划
        saveNewLog() {
            let timeEntry = this.timeEntry;

            console.log(timeEntry);
            // this.$dispatch('timeUpdate', timeEntry); 2.0取消了
            this.$emit('timeUpdate', timeEntry);
            // 下面不能这么写,这样将用户信息也清掉了,第二次之后会报错
            // this.timeEntry = {};
            // this.timeEntry.date = ''; 直接赋值也检查不到变化,需要用Vue.set 简单变通如下
            this.timeEntry = {
                user: {
                    name: '二哲',
                    email: 'kodo@forchange.cn',
                    image: 'https://sfault-avatar.b0.upaiyun.com/888/223/888223038-5646dbc28d530_huge256'
                }
            };

        }
    }
}
</script>

【转自慕课】https://www.imooc.com

Vue.js

common-all笔记-vuesell

2022-3-3 19:46:20

Vue.js

分享一个精致完整的Vue2+项目[douban]供大家交流学习

2022-3-3 19:46:54

搜索