VUE路由案例(商品列表)---vue练习必选项目(附原码)

20 篇文章 1 订阅

VUE路由案例(商品列表)—vue练习必选项目(附原码)

练习VUE基础知识点,练习了组件封装,父子组件之间得通信,组件插槽和组件路由,是一个很不错得练习项目

在这里插入图片描述

路由配置

二级路由

组件

  • Layout.vue —总的框架
  • List.vue ----商品列表
  • Search.vue -----商品搜索
  • My.vue-----我的信息

配置路由

const routes = [
  {
    path: '/',
    redirect: '/list',
    component: () => import('../views/Layout'),
    children: [
      {
        path: 'list',
        component: () => import('../views/List'),
      },
      {
        path: 'search',
        component: () => import('../views/Search'),
      },
      {
        path: 'my',
        component: () => import('../views/My'),
      },
    ],
  },
  {
    path: '*',
    component: () => import('../views/NotFound'),
  },
]
底部封装
  • 创建MyTabBar.vue组件
<template>
  <van-tabbar v-model="active" route>
    <van-tabbar-item icon="home-o" to="/list">商品列表</van-tabbar-item>
    <van-tabbar-item icon="search" to="/search">商品搜索</van-tabbar-item>
    <van-tabbar-item icon="friends-o" to="/my">我的信息</van-tabbar-item>
  </van-tabbar>
</template>

<script>
export default {
  data() {
    return {
      active: 0,
    }
  },
}
</script>
顶部封装
  • 创建MyHead.vue组件

    <template>
      <div class="head">TabBar案例</div>
    </template>
    
    <script>
    export default {}
    </script>
    
    <style scoped>
    .head {
      height: 50px;
      line-height: 50px;
      background-color: blue;
      text-align: center;
      color: white;
    }
    </style>
    
    
商品列表
  • 封装MyTable.vue ===标签和样式
  • axios 在MyGoodList.vue请求数据回来
  • 请求地址https://www.escook.cn/api/goods
  • 传入MyTable.vue 中循环数据显示

axios 在MyGoodList.vue请求数据回来

  • 下载axios

    yarn add axios
    
  • MyGoodList.vue

    <template>
      <div>
        <my-table :list="list"></my-table>
      </div>
    </template>
    
    <script>
    import axios from 'axios'
    import MyTable from './MyTable.vue'
    export default {
      components: {
        MyTable,
      },
      data() {
        return {
          list: [],
        }
      },
      created() {
        // axios({
        //   url: 'https://www.escook.cn/api/goods',
        // }).then((res) => {
        //   let {
        //     data: { data: result },
        //   } = res
        //   console.log(result)
        // })
        this.getDate()
      },
      methods: {
        async getDate() {
          let {
            data: { data: result },
          } = await axios({ url: 'https://www.escook.cn/api/goods' })
          console.log(result)
          this.list = result
        },
      },
    }
    </script>
    
  • MyTable.vue

    <template>
      <table class="table">
        <thead>
          <tr>
            <th>#</th>
            <th>名称</th>
            <th>价格</th>
            <th>标签</th>
            <th>操作</th>
          </tr>
        </thead>
        <tbody>
          <tr v-for="(item, index) in list">
            <td>{{ item.id }}</td>
            <td>{{ item.goods_name }}</td>
            <td>{{ item.goods_price }}</td>
            <td>{{ item.tags }}</td>
            <td>
              <van-button type="primary">删除</van-button>
            </td>
          </tr>
        </tbody>
      </table>
    </template>
    
    <script>
    export default {
      props: {
        list: Array,
      },
    }
    </script>
    
    <style scoped>
    .table {
      width: 100%;
      margin: 20px auto;
      border: 1px solid #333;
      border-collapse: collapse;
    }
    td,
    th {
      border: 1px solid #333;
      height: 30px;
    }
    </style>
    
商品表格–插槽

使用插槽技术,和作用域插槽技术,给MyTable.vue组件,自定义列标题,自定义表格内容

需求:允许用户自定义表个头和表格单元格内容

  • 把MyTable.vue里准备slot
  • 使用MyTable组件时传入具体标签

步骤:

  • ​ 提高组件==复用性和灵活性 ==,把表格列标题thead部分预留slot ,设置name属性
  • 使用MyTable.vue时,传入列标题标签
  • 表格内容td部分也可以让组件使用者自定义,也给tbody预留slot 和name属性
  • 使用插槽需要用到插槽内的item对象上的数据,作用域插槽

MyTable.vue

<template>
  <table class="table">
    <thead>
      <tr>
        <!-- <th>#</th>
        <th>名称</th>
        <th>价格</th>
        <th>标签</th>
        <th>操作</th> -->
        <slot name="header"></slot>
      </tr>
    </thead>
    <tbody>
      <tr v-for="(item, index) in list">
        <!-- <td>{{ item.id }}</td>
        <td>{{ item.goods_name }}</td>
        <td>{{ item.goods_price }}</td>
        <td>{{ item.tags }}</td>
        <td>
          <van-button type="primary">删除</van-button>
        </td> -->
        <slot name="body" :row="item" :index="index"></slot>
      </tr>
    </tbody>
  </table>
</template>

<script>
export default {
  props: {
    list: Array,
  },
}
</script>

MyGoodList.vue

<template>
  <div>
    <my-table :list="list">
      <template #header>
        <th>#</th>
        <th>名称</th>
        <th>价格</th>
        <th>标签</th>
        <th>操作</th>
      </template>
      <template #body="{ row, index }">
        <td>{{ row.id }}</td>
        <td>{{ row.goods_name }}</td>
        <td>{{ row.goods_price }}</td>
        <td>{{ row.tags }}</td>
        <td>
          <van-button type="primary">删除</van-button>
        </td>
      </template>
    </my-table>
  </div>
</template>
商品表格tags
<td>
          <van-tag v-for="(str, ind) in row.tags" :key="ind" type="primary">{{
            str
          }}</van-tag>
        </td>
商品表格–删除功能

点击删除按钮删除数据

分析:

  • 删除按钮绑定点击事件
  • 作用域插槽绑定id出来
  • 传给删除方法,删除MyGoodList.vue里数组的数据

MyGoodList.vue—注册点击事件

 <van-button type="primary" @click="removeBtn(row.id)"
            >删除</van-button>

MyGoodList.vue 根据id删除

methods:{
    removeBtn(id) {
      // 1 根据id查找下标
      let index = this.list.findIndex((obj) => obj.id === id)
      // 2 实现删除
      this.list.splice(index, 1)
    },
}
商品表格—添加tab

需求:点击tab按钮,出现输入框自动获取焦点,失去焦点关闭输入框,会出新增tag,esc清空内容

  • 点击tab,按钮消失,输入框出现
  • 输入框自动获焦
  • 失去焦点,输入框消失,按钮出现
  • 检测输入框回车,无数据拦截
  • 输入框取消,清空数据
  • 检测输入框回车,有数据添加
点击tab,按钮消失,输入框出现
  <div class="top">
            <van-field
              v-model="value"
              v-if="row.inputVisible"
              placeholder="请输入tab内容"
            />
            <van-button v-else @click="row.inputVisible = true" type="info"
              >tag+</van-button
            >
 </div>
输入框自动获焦
<van-field
              v-model="value"
              v-if="row.inputVisible"
              placeholder="请输入tab内容"
              :autofocus="true"
            />
失去焦点,输入框消失,按钮出现
 <van-field
              v-model="value"
              v-if="row.inputVisible"
              placeholder="请输入tab内容"
              :autofocus="true"
              @blur="row.inputVisible = false"
            />
输入框回车新增tag

1:监听input的回车事件

<van-field
              v-model="row.inputValue"
              v-if="row.inputVisible"
              placeholder="请输入tab内容"
              :autofocus="true"
              @blur="row.inputVisible = false"
              @keydown.enter="enterFn(row)"
            />

2.事件处理函数

 // 新增tag
    enterFn(row) {
      // console.log(row, 0)
      // 非空判断
      if (row.inputValue.trim().length === 0) {
        return alert('请输入数据')
      }

      // 添加
      row.tags.push(row.inputValue)
      row.inputValue = ''
    },
input框 esc清空内容
 @keydown.esc="row.inputValue = ''"

附带项目原码:
https://download.csdn.net/download/idiot_MAN/86726354

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值