vue-ele-node-实战-demo-笔记②

views下面新建home.vue

<template>
    <div class="index">
        <HeadNav />
        <router-view />
    </div>
</template>

<script>
import HeadNav from '../components/HeadNav';
export default {
    name: 'index',
    components: { HeadNav }
};
</script>

<style scoped>
.index {
    height: 100%;
    width: 100%;
    overflow: hidden;
}
</style>

home是index的二级路由
修改路由

		{
            path: '/index',
            component: Index,
            children: [
                { path: '', component: Home },
                { path: '/home',name: 'home', component: Home }
            ]
        },

这样是index.vue是不显示的,在index.vue下面添加router-view

<template>
    <div class="index">
        <HeadNav />
        <router-view />
    </div>
</template>

配置二级路由 infoshow

{ path: '/infoshow',name: 'infoshow', component: InfoShow }

views下面新建InfoShow.vue

<template>
   <div class="infoshow">
       <el-row type="flex" class="row-bg" justify="center">
           <el-col :span='8'>
               <div class="user">
                    <img src="user.avatar" class='avatar' alt="">
               </div>
           </el-col>
           <el-col :span='16'>
               <div class="userinfo">
                  <div class="user-item">
                    <i class="fa fa-user"></i>
                   <span style="margin: 0 5px">name</span>
                  </div>
                  <div class="user-item">
                    <i class="fa fa-cog"></i>
                    <span style="margin: 0 5px">identity</span>
                  </div>
               </div>
           </el-col>
       </el-row>
    </div>
</template>

<script>
export default {
    name: 'infoshow',
    components: {}
};
</script>

<style scoped>
.index {
    height: 100%;
    width: 100%;
    overflow: hidden;
}

.infoshow {
    width: 100%;
    height: 100%;
    box-sizing: border-box;
    /* padding: 16px; */
}
.row-bg {
    width: 100%;
    height: 100%;
}
.user {
    text-align: center;
    position: relative;
    top: 30%;
}
.user img {
    width: 150px;
    border-radius: 50%;
}
.user span {
    display: block;
    text-align: center;
    margin-top: 20px;
    font-size: 20px;
    font-weight: bold;
}
.userinfo {
    height: 100%;
    background-color: #eee;
}
.user-item {
    position: relative;
    top: 30%;
    padding: 26px;
    font-size: 28px;
    color: #333;
}
</style>

在index.html中引入图标

<!-- 图标 -->
  <link href="//cdn.bootcss.com/font-awesome/4.7.0/css/font-awesome.css" rel="stylesheet">

记得保存

去HeadNav中设置点击个人信息进行跳转

		showInfoList() {
            this.$router.push('/infoshow') 

        },```


测试ok,

获取全局user
```js
	computed:{
        user(){
            return this.$store.getters.user
        }
    }

绑定 img :src,把要{{}}显示的地方改好

搞定,完成左侧导航栏,elecopy一份

index.vue引入component
测试ok,

接下来敲table,ele找自定义table 自定义table模板

views文件夹下面新建formList.vue

created时候请求api GET info,然后将info保存到tableData中

复制ele的table html

<template>
    <!-- el-tbale 绑定值 tableData -->
    <el-table
        v-if="tableData.length >= 0"
        :data="tableData"
        border
        style="width: 100%"
    >
        <el-table-column label="序号" align="center" type="index" width="70">
        </el-table-column>

        <el-table-column
            label="创建时间"
            align="center"
            prop="date"
            width="180"
        >
        </el-table-column>

        <el-table-column
            label="收支类型"
            align="center"
            prop="type"
            width="180"
        >
        </el-table-column>

        <el-table-column
            label="收支描述"
            align="center"
            prop="describe"
            width="180"
        >
        </el-table-column>

        <el-table-column label="收入" align="center" prop="income" width="180">
        </el-table-column>

        <el-table-column label="支出" align="center" prop="expend" width="180">
        </el-table-column>

        <el-table-column
            label="账户现金"
            align="center"
            prop="cash"
            width="180"
        >
        </el-table-column>

        <el-table-column label="备注" align="center" prop="remark" width="180">
        </el-table-column>
    </el-table>
</template>

<script>
export default {
    name: 'fund-list',
    components: {},
    data() {
        return {
            tableData: []
        };
    },
    created() {
        this.getProfile();
    },
    methods: {
        getProfile() {
            this.$axios.get('/api/profiles').then(res => {
                this.tableData = res.data;
                console.log(res.data)
            });
        }
    }
};
</script>

<style scoped></style>

美工 加入icon ,类似的就不放重复的了

		<el-table-column
            label="创建时间"
            align="center"
            prop="date"
            width="180"
        >
            <template slot-scope="scope">
                <i class="el-icon-time"></i>
                <span style="margin-left: 10px">{{ scope.row.date }}</span>
            </template>
        </el-table-column>
        
         <el-table-column label="支出" align="center" prop="expend" width="180">
            <template slot-scope="scope">
                <i class="el-icon-money"></i>
                <span style="margin-left: 10px; color:#00d053">- {{
                    scope.row.expend
                }}</span>
            </template>
        </el-table-column>

最外层加上div 加上 padding,美工做完后,写handle方法

获取数据,完善增删改

加入操作 写handle方法

加入添加按钮,点击添加会有dialo弹框

在components下面创建Dialog.vue
我们希望点击添加按钮时 弹出弹框

在父组件添加dialog

data() {
        return {
            tableData: [],
            dialog:{
                show: false
            }
        };
    },

在Dialog.vue中用props引入进来

export default {
   
    name: 'dialog',
    // 父组件 属性传值过来
    props:{
        dialog: Object,
    }
}

那么点击添加按钮时调用的方法为 把show改成true

 	handleAdd() {
            this.dialog.show = true
        }

在Dialog.vue中 把:visible绑定成dialog的show

<template>
    <div class="dialog">
        <el-dialog
            title="添加资金信息"
            :visible="dialog.show"
            :modal-append-to-body="false"
        >
        </el-dialog>
    </div>
</template>

父组件我要把信息传递到弹框中,绑定dialog

  <Dialog :dialog="dialog"/>

去测试的时候是不能关闭对话框的
我们需要加上.sync

:visible.sync="dialog.show"

写弹框 里面的form表单
传递的值有formData,format_tpye_list是用来遍历展示的

rules是写在data()里面的

写onSubmit ,格式

	 onSubmit(form){
            this.$refs[form].validate(valid => {
                if(valid){
                    this.$axios.post('/api/profiles/add', this.formData)
                    .then(res => {
                        this.$message({
                            message: '数据添加成功',
                            type: 'success'
                        })
                    })

                    // 隐藏dialog
                    this.dialog.show = false
                    // 自动刷新
                    this.$emit('update')
                }
            })
        }

注册一个update事件让父级去执行 @update就是接收到这个事件后去执行get信息的操作

<Dialog :dialog="dialog" @update="getProfile()"/>

接下来是编辑功能

我们想让data信息由父级传递,我们把formData: {} 剪切走,贴到FundList.vue里面去

:formData这样传递过去

        <Dialog :dialog="dialog" :formData="formData" @update="getProfile()"/>

子组件用props接收

props: {
        dialog: Object,
        formData:Object
    },

回到父级,修改属性添加 title和option 传递给子组件用来判断是添加还是修改

	dialog:{
                show: false,
                title: '',
                option: 'edit',
            }

那么子组件title应该绑成

:title="dialog.title"

所以在点击的时候 需要修改这些对应的属性以显示对应的title

	handleEdit(index, row) {
            // 编辑
            this.dialog.show = true
            this.dialog.title = '修改资金信息'
            this.dialog.option = 'edit'
     
        }
  
 handleAdd() {
            this.dialog.show = true
            this.dialog.title = '添加资金信息'
            this.dialog.option = 'add'
        }

这样去做一个区分,接下来在编辑的时候,我们要拿到当前行的信息保存到formdata中

handleEdit(index, row) {
            // 编辑
            this.dialog.show = true
            this.dialog.title = '修改资金信息'
            this.dialog.option = 'edit'
            // 我们要拿到当前行的信息保存到formdata中
            this.formData = {
                type: row.type,
                describe: row.describe,
                income: row.income,
                expend: row.expend,
                cash: row.cash,
                remark: row.remark,
                id: row._id
            }
     
        },

同理 提交的时候 formdata是全空的,这里就不放出来了, 大同小异

回到表单的提交方法onSubmit,我们还要对提交和编辑进行区分以调用不同的api

	onSubmit(form) {
            this.$refs[form].validate(valid => {
                if (valid) {
                    const url =
                        this.dialog.option == 'add'
                            ? 'add'
                            : `edit/${this.formData.id}
                    `;

                    this.$axios
                        .post(`/api/profiles/${url}`, this.formData)
                        .then(res => {
                            if (url == 'add') {
                                this.$message({
                                    message: '数据添加成功',
                                    type: 'success'
                                });
                            } else {
                                this.$message({
                                    message: '数据修改成功',
                                    type: 'success'
                                });
                            }
                        });

                    // 隐藏dialog
                    this.dialog.show = false;
                    // 自动刷新
                    this.$emit('update');
                }
            });
        }

最后是写delete方法

handleDelete(index, row) {
            this.$axios.delete(`/api/profiles/delete/${row._id}`).then(res => {
                // 提醒框
                this.$message('删除成功');
                // 刷新页面
                this.getProfile();
            });
        },

测试一下,ok

分页,用ele 去官网copy一下
去到FundList组件下,copy

<!--分页-->
            <el-row>
                <el-col :span="24">
                    <div class="pagination">
                        <el-pagination
                            @size-change="handleSizeChange"
                            @current-change="handleCurrentChange"
                            :current-page="currentPage4"
                            :page-sizes="[5, 10, 15, 20]"
                            :page-size="100"
                            layout="total, sizes, prev, pager, next, jumper"
                            :total="400"
                        >
                        </el-pagination>
                    </div>
                </el-col>
            </el-row>

创建data给一个paginations属性

paginations: {
                // 当前位于页数
                page_index: 1,
                total: 0,
                page_size: 5,
                // 每页显示多少条
                page_sizes: [5, 10, 15, 20],
                // 翻页属性
                layout: "total, sizes, prev, pager, next, jumper"
            }

修改绑定属性

				<el-pagination
                            @size-change="handleSizeChange"
                            @current-change="handleCurrentChange"
                            :current-page.sync="paginations.page_index"
                            :page-sizes="paginations.page_sizes"
                            :page-size="paginations.page_size"
                            :layout="paginations.layout"
                            :total="paginations.total"
                        >

实现两个方法handleSizeChange,handleCurrentChange

加多一个data属性 allTableData: [],
把getProfile()里面的tableData和所有tableData都改成AllTableData

getProfile() {
            this.$axios.get('/api/profiles').then(res => {
                this.allTableData = res.data;
                // console.log(res.data);
                // 设置分页数据
                this.setPainations();
            });
        },

并且加多调用一个setPainations函数,主要是用作初始化

setPainations() {
            // 分页属性初始化设置
            this.paginations.total = this.allTableData.length;
            this.paginations.page_index = 1;
            this.paginations.page_size = 5;
            // 设置tabelData数据
            this.tableData = this.allTableData.filter((item, index) => {
                return index < this.paginations.page_size;
            });

        },

切换size函数实现

handleSizeChange(page_size) {
            // 切换size
            this.paginations.page_index = 1;
            this.paginations.page_size = page_size;
            // 设置tabelData数据
            this.tableData = this.allTableData.filter((item, index) => {
                return index < page_size;
            });
        },

实现切换页面

handleCurrentChange(page) {
            // 当前页
            let sortnum = this.paginations.page_size * (page - 1);
            // 设置tableData 取页头往后
            let table = this.allTableData.filter((item, index) => {
                return index >= sortnum;
            });
            // 取页尾往前
            this.tableData = table.filter((item, index) => {
                return index < this.paginations.page_size;
            });
        }

时间选择器 筛选功能,把html结构写上

		<el-form :inline="true" ref="add_data">
                <!--时间选择器-->
                <el-form-item label="按照时间筛选:">
                    <el-date-picker
                        v-model="value2"
                        type="datetime"
                        placeholder="开始时间"
                        align="right"
                    >
                    </el-date-picker>
                    <el-date-picker
                        v-model="value2"
                        type="datetime"
                        placeholder="结束时间"
                        align="right"
                    >
                    </el-date-picker>
                </el-form-item>
                <!--筛选btn-->
                <el-form-item class="btn">
                    <el-button type="primary" 
                        size="small"
                        icon="search"
                        @click="handleSearch()">
                        筛选</el-button
                    >
                </el-form-item>

                <!--添加btn-->
                <el-form-item class="btnRight">
                    <el-button type="primary" size="small" @click="handleAdd()">
                        添加</el-button
                    >
                </el-form-item>
            </el-form>

添加关于时间的容器

search_data:{
                startTime :'',
                endTime :'',
            },

把他们绑定上

    v-model="search_data.startTime"
    
    v-model="search_data.endTime"
            <el-form :inline="true" ref="add_data" :model="search_data">

这里也要search_data

handleSearch实现方法

handleSearch() {
            if (!this.search_data.startTime || !this.search_data.endTime) {
                this.$message({
                    message: '请选择时间区间',
                    type: 'warning'
                });
            } else {
                const sTime = this.search_data.startTime.getTime();
                const eTime = this.search_data.endTime.getTime();
                console.log(sTime);
                console.log(eTime);

                this.allTableData = this.filterTableData.filter(
                    (item, index) => {
                        let date = new Date(item.date);
                        let time = date.getTime();
                        console.log(time);
                        console.log(time >= sTime && time <= eTime);
                        return time >= sTime && time <= eTime;
                    }
                );
                // 分页数据调用
                this.setPainations();
            }
        },

ctrl+k+4 所有代码折叠

添加filterTableData:[],容器 用来保存筛选的内容
在getProfile()时将所有内容保存到filterTableData

修改nodejs date时间格式化 引用moment

dateFormat(date) {
            {
                return moment(date).format('YYYY-MM-DD HH:mm:ss');
            }
        }

展示的时候调用这个函数

{{ dateFormat(scope.row.date) }}

ok 搞定

权限设定

添加computed,获取权限

computed: {
        user(){
            return this.$store.getters.user
        }
    }

在btn中添加v-if="user.identity == 'manage'"

项目打包, heroku免费,注册 登陆
下载heroku cli
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
前端打包 private false, npm run build

后端server.js设置

// 执行前端静态页面
if(process.env.NODE_ENV === 'production'){
    const pass = require('path')
    app.use(express.static('client/dist'))
    // 其他页面都跳转到index.html
    app.get('*', (req, res) => {
        res.sendFile(path.resolve(__dirname, 'client', 'dist'
        ,'index.html'
        ))
    })
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值