• leyou_04_使用vue.js搭建页面—使用ajax完成品牌的查询


    1.使用vue.js搭建页面

     1.1使用的模板插件Vuetify

      中文UI组件官网:https://vuetifyjs.com/zh-Hans/getting-started/quick-start

     1.2要实现的效果

      1.3创建Brand.vue初始化页面

    <template>
      <span>
        hello
      </span>
    </template>
    
    <script>
      export default {
        name: "myBrand"
      }
    </script>
    
    <!-- scoped:当前样式只作用于当前组件的节点 -->
    <style scoped>
    
    </style>

     

      1.4首先是一个5列的表格 选用这个

      1.5复制模版

    <template>
      <div>
        <v-data-table
          :headers="headers"  
          :items="brand"
          :pagination.sync="pagination"
          :total-items="totalDesserts"
          :loading="loading"
          class="elevation-1"
        >
          <template slot="items" slot-scope="props">
            <td>{{ props.item.name }}</td>
            <td class="text-xs-right">{{ props.item.calories }}</td>
            <td class="text-xs-right">{{ props.item.fat }}</td>
            <td class="text-xs-right">{{ props.item.carbs }}</td>
            <td class="text-xs-right">{{ props.item.protein }}</td>
            <td class="text-xs-right">{{ props.item.iron }}</td>
          </template>
        </v-data-table>
      </div>
    </template>

      

      headers:表头信息,是一个数组也就是表格的列信息

      text:表格列的名称   value:该列关联的字段   align:对齐方式   sortable:是否需要排默认false

    headers: [
              {text: '品牌id', value: 'id', align: 'center', sortable: true},
              {text: '品牌名称', value: 'name', align: 'center', sortable: false},
              {text: '品牌LoGo', value: 'image', align: 'center', sortable: false},
              {text: '品牌首字母', value: 'letter', align: 'center', sortable: true},
              {text: '操作', align: 'center', sortable: false},
    
            ],
    • items:要在表格中展示的数据,数组结构,每一个元素是一行。在这里应该是品牌集合

    • pagination.sync:分页信息,包含了当前页,每页大小,排序字段,排序方式等。加上.sync代表服务端排序,当用户点击分页条时,该对象的值会跟着变化。监控这个值,并在这个值变化时去服务端查询,即可实现页面数据动态加载了。

    • total-items:总条数,在这里是品牌的总记录数

    • loading:boolean类型,true:代表数据正在加载,会有进度条。false:数据加载完毕。 

    <template slot="items" slot-scope="props">
       这段就是在渲染每一行的数据。Vue会自动遍历上面传递的items属性,并把得到的对象传递给这段template中的props.item属性。我们从中得到数据,渲染在页面即可。
    
    
    

    1.6页面搭建完成接下来只需要使用watch监控页面数据发生改变时发送相应的ajax请求

    <template xmlns:v-bind="http://www.w3.org/1999/xhtml">
      <div>
        <v-layout class="px-3 pb-2">
          <v-flex xs2>
            <v-btn color="info" small>新增品牌</v-btn>
          </v-flex>
          <v-spacer/>
          <v-flex xs4>
            <v-col cols="12" sm="6" md="3">
              <v-text-field label="搜索" hide-details append-icon="search" v-model="key"></v-text-field>
            </v-col>
          </v-flex>
        </v-layout>
        <v-data-table
          :headers="headers"
          :items="brands"
          :pagination.sync="pagination"
          :toatl-items="totalBrands"
          :loading="loading"
          class="elevation-1"
        >
          <template slot="items" slot-scope="props">
            <td class="text-xs-center">{{props.item.id}}</td>
            <td class="text-xs-center">{{props.item.name}}</td>
            <td class="text-xs-center"><img v-if="props.item.image" v-bind:src="props.item.image" width="130" height="40"/>
            </td>
            <td class="text-xs-center">{{props.item.letter}}</td>
            <td class="text-xs-center">
              <v-btn color="success" small>修改</v-btn>
              <v-btn color="error" small>删除</v-btn>
            </td>
    
          </template>
    
        </v-data-table>
      </div>
    </template>
    
    <script>
      export default {
        data() {
          return {
            totalDesserts: 0,
            desserts: [],
            loading: true,
            options: {},
            headers: [
              {text: '品牌id', value: 'id', align: 'center', sortable: true},
              {text: '品牌名称', value: 'name', align: 'center', sortable: false},
              {text: '品牌LoGo', value: 'image', align: 'center', sortable: false},
              {text: '品牌首字母', value: 'letter', align: 'center', sortable: true},
              {text: '操作', align: 'center', sortable: false},
    
            ],
            brands: [],
            pagination: {},
            totalBrands: 0,
            loading: false,
            key: "",//搜索条件
          }
        },
      }
    </script>
    
    <style scoped>
    
    </style>
    
    
    
    在列的最后增加一列图标
    <template slot="items" slot-scope="props">
            <td class="text-xs-center">
              <v-btn color="success" small>修改
           <v-icon>edit</v-icon>//用一个图标来代替修改 
    </v-btn> <v-btn color="error" small>删除</v-btn> </td> </template>
    
    

    增加按钮和搜索框

    <v-layout class="px-3 pb-2"><!--代表是一行 -->
          <v-flex xs2><!--设置宽度 -->
            <v-btn color="info" small>新增品牌</v-btn>
          </v-flex>
          <v-spacer/> <!--自动补全中的的空间 -->
          <v-flex xs4>
            <v-col cols="12" sm="6" md="3">
              <v-text-field label="搜索" hide-details append-icon="search" v-model="key"></v-text-field>
            </v-col>
          </v-flex>
        </v-layout>

    1.7对搜索框和分页,排序,每页记录数进行监控当数据发生改变时调用ajax

    //监控
    watch:{
          key(){
            this.loadBrands();
          },
          pagination:{
    //深度监控
            deep:true,
            handler(){
              this.loadBrands();
            }
          }
    },

    1.8发送ajax方法

    methods: {
          loadBrands() {
            this.$http.get("/item/brand/page", {
              params: {
                page:this.pagination.page,//当前页
                rows:this.pagination.rowsPerPage,//每页记录数
                sortBy:this.pagination.sortBy,//排序字段
                desc:this.pagination.descending,//是否降序
                key: this.key//搜索条件
              }
            }).then(resq =>{
              this.brands=resq.data.items;
              this.totalBrands=resq.data.total;
            })
          }
        },
    this.$http.get("/item/brand/page", 通过vue.js的原型去配置的
    在http.js中定义了
    Vue.prototype.$http = axios;// 将axios添加到 Vue的原型,这样一切vue实例都可以使用该对象

    1.9config.js中请求地址的自动拼接 发送的任何请求都会自动拼接api

    const baseUrl = 'http://api.leyou.com'
      api: `${baseUrl}/api`,

    2.后台的处理(使用restful风格)

    2.1拿到ajax传递的参数

    @RestController
    @RequestMapping("brand")
    public class BrandController {
    
        @Autowired
        private BrandService brandService;
        @GetMapping("page")
        public ResponseEntity<PageResult<Brand>> queryBrandPage(
                @RequestParam(value = "page", defaultValue = "1") Integer page,
                @RequestParam(value = "rows", defaultValue = "5") Integer rows,
                @RequestParam(value = "storyBy", required = false) String storyBy,
                @RequestParam(value = "desc", defaultValue = "false") boolean desc,
                @RequestParam(value = "key", required = false) String key) {
    
               PageResult<Brand> result=brandService.queryBrandPage(page,rows,storyBy,desc,key);
            System.out.println(result);
               return  ResponseEntity.ok(result);
        }
    }

    2.2在servicer中处理//分页//过滤//排序//查询//结果集的封装

    通过通用mapper操作数据库

    @Service
    public class BrandService {
        @Autowired
        private BrandMapper brandMapper;
    
        public PageResult<Brand> queryBrandPage(Integer page, Integer rows, String storyBy, boolean desc, String key) {
            //分页   mapper自带的分页助手
            PageHelper.startPage(page, rows);
    
            //过滤  select * from tb_brand where name like "%"+key+"%" or letter==key order by storyBy  desc
            Example example = new Example(Brand.class);
            if (StringUtils.isNotBlank(key)) {
                example.createCriteria().orLike("name", "%" + key + "%").orEqualTo("letter", key.toUpperCase());
            }
    
            //排序
            if (StringUtils.isNotBlank(storyBy)) {
                String orderByClause=storyBy+(desc? " desc":" asc");
                example.setOrderByClause(orderByClause);
            }
    
            //查询
            List<Brand> list = brandMapper.selectByExample(example);
            if (CollectionUtils.isEmpty(list)){
                throw  new LyException(ExceptionEnum.BRAND_NOT_FOND);
            }
            //帮我们把查询到的结果List进行封装  封装的结果集里面有Total,pageNum,pageSizedeng
            PageInfo<Brand> info = new PageInfo<>(list);
    
            //封装结果集
            PageResult<Brand> result = new PageResult<Brand>(info.getTotal(),list);
    
            return result;
    
        }
    }
     PageInfo<Brand> info = new PageInfo<>(list);
    帮我们把查到的sql语句结果强转为PageInfo对象
    PageInfo对象中定义了很多的分页属性
    例如:
    private static final long serialVersionUID = 1L;
        //当前页
        private int pageNum;
        //每页的数量
        private int pageSize;
        //当前页的数量
        private int size;
        //当前页面第一个元素在数据库中的行号
        private int startRow;
        //当前页面最后一个元素在数据库中的行号
        private int endRow;
        //总记录数
        private long total;
        //总页数
        private int pages;
        //结果集
        private List<T> list;
     
  • 相关阅读:
    selenium webdriver使用过程中出现Element is not currently visible and so may not be interacted with的处理方法
    转:使用C#的HttpWebRequest模拟登陆网站
    第一个WCF服务
    WinForm DataGridview.AutoSizeColumnsMode属性
    Winform 程序中DataGridView 控件添加行号
    DevExpress GridControl行颜色标识
    基于T4模板的文档生成
    NHibernate 支持的数据库及配置参数
    MahApps.Metro
    Log4Net 配置文件样例
  • 原文地址:https://www.cnblogs.com/asndxj/p/11568720.html
Copyright © 2020-2023  润新知