上一节大概看了下VUE的入门,本节我们来做一个查询的demo。在写博客前我总是要给大家展示一下风景照。虽然是加载比较慢,但是也是为了让大家大饱眼福。蓝田九间房万亩荷花了解一下。
其实之前在写Anuglar7实战的时候,我们把饭店会员管理系统的主页进行了搭建,本节我们主要是搭建一个VUE的主页,还是那句话,无图无真相,先看图。
首先我们要确定我们要使用的组件,对于VUE,我之前项目中用过element,所以本篇文章我们所有控件都使用element。要使用element,得先安装element,在项目目录下面,直接npm install element-ui。
接下来我们先看一下项目结构
我们将一些css文件,bootstrap,部分图片等放到了static下面。这里的入口文件就是main.js
import Vue from 'vue' import App from './App' import router from './router' import ElementUI from 'element-ui' import 'element-ui/lib/theme-chalk/index.css' import axios from 'axios' import VueAxios from 'vue-axios' Vue.config.productionTip = false Vue.use(ElementUI) Vue.use(VueAxios, axios) /* eslint-disable no-new */ new Vue({ el: '#app', router, components: { App }, template: '<App/>' })
这里我们主要是引入了element-ui组件,方便我们后面所有的component使用。这里设置了VUE默认加载的组件,即App.vue组件,将其渲染到index.html页面中的id为app的div中。看一下html页面,引入了css文件以及js文件。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <title>饭店会员管理系统</title> <link rel="stylesheet" href="./static/bootstrap/bootstrap.min.css" /> <link rel="stylesheet" href="./static/bootstrap/bootstrap-theme.min.css" /> <link rel="stylesheet" href="./static/messager/css/messenger.css" /> <link rel="stylesheet" href="./static/messager/css/messenger-theme-flat.css" /> <link rel="stylesheet" href="./static/css/Site.css" /> <script type="text/javascript" src="./static/jquery/jquery-3.3.1.min.js"></script> <script type="text/javascript" src="./static/bootstrap/bootstrap.min.js"></script> <script type="text/javascript" src="./static/jquery/jquery-3.3.1.min.js"></script> <script type="text/javascript" src="./static/messager/js/messenger.min.js"></script> <script type="text/javascript" src="./static/messager/js/messenger-theme-flat.js"></script> <script type="text/javascript" src="./static/messager/js/messagebox.js"></script> </head> <body> <div id="app"></div> <!-- built files will be auto injected --> </body> </html>
在main.js中也引入了路由配置router,看一下代码
import Vue from 'vue' import Router from 'vue-router' import Default from '@/components/default' import Customer from '@/components/customer'; Vue.use(Router) export default new Router({ routes: [ { path: '/', name: 'default', component: Default }, { path: '/customer', name: 'customer', component: Customer } ] })
在这里我们定义了两个路由,一个默认路由,一个展示customer的页面。
对于default,没什么说的,这里我放了一个空页面。我们主要是是看一下App.vue这个入口component。它的模板部分如下
<template> <div id="app"> <div class="main"> <header> <div class="col-md-12"> <div class="col-md-5 website-title" style="text-align: left"> <img src="./assets/Images/member.png" width="50" height="50" /> <a href="" style="color:white">饭店会员管理系统</a> </div> <div id="logout" class="col-md-7" style="text-align: right; font-size: large"> <img id="img_UserPhoto" class="round-image" src="./assets/Images/users.jpg" /> <span style="margin-right: 10px"> 当前用户:{{currentUser}} <span style="color: white;margin-right:10px"></span> </span> <span id="currentTime">{{dateNow}}</span> <a href="javascript:void(0)">注销</a> </div> </div> </header> <div class="row"> <div class="col-md-2"> <div class="panel-group margin-t10" id="accordion"> <div class="panel panel-primary" id="div_User" runat="server"> <div class="panel-heading"> <h4 class="panel-title"> <a data-toggle="collapse" data-parent="#accordion" href="#collapseOne"> <b>会员信息</b> </a> </h4> </div> <div id="collapseOne" class="panel-collapse collapse in"> <div class="panel-body"> <ul class="navigation-ul"> <li class="span-nav"> <img src="./assets/Images/menu/member.png" /> <a routerLink="/app-customer/create">新增会员</a> </li> <li class="span-nav"> <img src="./assets/Images/menu/members.png" /> <router-link :to="{path: 'customer', query: {color: 'red' }}">会员管理</router-link> </li> </ul> </div> </div> </div> <div class="panel panel-primary" id="div_User" runat="server"> <div class="panel-heading"> <h4 class="panel-title"> <a data-toggle="collapse" data-parent="#accordion" href="#collapseOne"> <b>消费充值</b> </a> </h4> </div> <div id="collapseOne" class="panel-collapse collapse in"> <div class="panel-body"> <ul class="navigation-ul"> <li class="span-nav"> <img src="./assets/Images/menu/consume.png" /> <a href="">消费结算</a> </li> <li class="span-nav"> <img src="./assets/Images/menu/money.png" /> <a href="">充值记录</a> </li> <li class="span-nav"> <img src="./assets/Images/menu/cash.png" /> <a href="">消费记录</a> </li> </ul> </div> </div> </div> </div> </div> <div class="col-md-10"> <router-view></router-view> </div> </div> </div> </div> </template>
上面的部分主要是页头和左侧导航,右边是一个router-view,这个东西其实就是一个插槽,类似于angular的 <router-outlet>。当我们点击导航的时候,会根据路由表找到对应的组件,然后加载到插槽部分。
<script> import moment from 'moment' export default { name: 'HelloWorld', data() { return { dateNow: moment(new Date()).format("YYYY-MM-DD HH:mm:ss"), currentUser: "李磊" } }, created() { setInterval(() => { this.setCurrentTime() }, 1000); }, methods: { setCurrentTime: function () { this.dateNow = moment(new Date()).format("YYYY-MM-DD HH:mm:ss"); } } } </script>
jsx部分呢,其实很简单,主要是展示一个时间。VUE有一些生命周期钩子,这里我不再赘述,借用网上的一张图。
在这里我们使用到了created,在created function中我们每隔1s刷新一下当前页面头部的时间。ok接下来我们再看一下页面customer.vue。
<template> <div id="customer" class="margin-t10"> <div class="panel panel-primary"> <div class="panel-heading"> <h3 class="panel-title"> <label>会员管理</label> </h3> </div> <div class="panel-content padding-5"> <div class="row"> <label class="col-md-1">用户名:</label> <div class="col-md-3"> <el-input v-model="query.userNo" size="small" placeholder=""></el-input> </div> <label class="col-md-1">姓名:</label> <div class="col-md-2"> <el-input v-model="query.userName" size="small" placeholder=""></el-input> </div> <label class="col-md-1">性别:</label> <div class="col-md-2"> <el-select v-model="query.sex" size="small" placeholder="请选择"> <el-option v-for="item in sexList" :key="item.value" :label="item.label" :value="item.value"> </el-option> </el-select> </div> <div class="col-md-1"> <el-button type="primary" icon="el-icon-search" size="small" :loading="loading" @click="queryCustomer">查询</el-button> </div> <div class="col-md-12"> <div id="customerlist" class="margin-t10"> <el-table :data="customerList.dataList"> <el-table-column prop="UserNo" label="用户名" width="180"> </el-table-column> <el-table-column prop="Name" label="姓名" width="180"> </el-table-column> <el-table-column prop="Sex" label="性别" width="180"> <template slot-scope="scope"> <p>{{ scope.row.Sex=='1'? '男':'女' }}</p> </template> </el-table-column> <el-table-column prop="ParentCustomerName" label="推荐人" width="180"> </el-table-column> <el-table-column prop="Amount" label="余额" width="90"> </el-table-column> <el-table-column prop="InDate" label="创建日期"> </el-table-column> </el-table> <el-pagination background layout="prev, pager, next" :total="customerList.total" :page-size="pageSize" :page-sizes="[5, 10, 20, 50]" @current-change="pageIndexChanged" :current-page="currentPageIndex"> </el-pagination> </div> </div> </div> </div> </div> </div> </template>
三个查询条件,用户名,姓名,性别,分别双向绑定。button和table我们均采用element-ui组件。element-ui组件非常丰富,也非常好用,不管你是开发angular,react,还是vue都是一个很好的选择,说明文档很详细 https://element.eleme.cn/#/zh-CN/component/table
ok,就这样一个简单的查询页面就写完了,接下来我们再看一下jsx部分。
<script> import axios from 'axios' export default { name: 'customer', data() { return { query: { userNo: '', userName: '', sex: null }, client_id: 'XXXXXX', tokenUrl: '/token', baseUrl: 'http://localhost:8008', customerList: { dataList: [], total: 0 }, currentPageIndex: 0, pageSize: 5, accessToken: '', sexList: [{ label: '男', value: '1' }, { label: '女', value: '0' }], loading: false } }, created() { if (!this.accessToken) { let request = { username: "190xxxxxx", password: '111333' }; this.getOAuthToken(request); } }, methods: { pageIndexChanged: function ($event) { this.currentPageIndex = $event; this.queryCustomer(); }, queryCustomer: function () { this.loading = true; var queryUrl = this.baseUrl.concat('/api/customer/list?pageindex=' + this.currentPageIndex + '&pageSize=' + this.pageSize); if (this.query.userNo) { queryUrl += '&userno=' + this.query.userNo; } if (this.query.userName) { queryUrl += '&userno=' + this.query.userName; } if (this.query.sex) { queryUrl += '&sex=' + this.query.sex; } axios.get(queryUrl, { headers: { 'Authorization': `bearer ${this.accessToken}` } }).then((response) => { this.customerList.dataList = response.data.CustomerList; this.customerList.total = response.data.TotalCount; this.loading = false; }); }, getOAuthToken(request) { let body = `username=${request.username}&password=${request.password}&grant_type=password&client_id=${this.client_id}`; var requestUrl = this.baseUrl.concat(this.tokenUrl); axios.post(requestUrl, body, { headers: { 'content-type': 'application/x-www-form-urlencoded' } }).then((response) => { this.accessToken = response.data.access_token; console.log(this.accessToken); }); } } }</script>
在这里我们要请求api,就必须要使用异步ajax请求的组件,在这里我们选择了axios,这个组件有什么特点呢
支持浏览器和node.js
支持promise
能拦截请求和响应
能转换请求和响应数据
能取消请求
自动转换JSON数据
浏览器端支持防止CSRF(跨站请求伪造)
文档:http://www.axios-js.com/docs/
看起来还是很不错的,因为我们的api是需要oauth权限认证的,所以需要先请求一下token api,得到access_token,然后拿着token再去请求api。
然后是支持一下分页,
ok,今天就到这里,感谢每一位关注本站的同志。
上一篇 VUE实战(一)
下一篇 React 实战(一)