5_Vue 实战练习2

需求:点击左边列表栏显示相应的页面,实现数据的增删改查
在这里插入图片描述

1、导入样式

这里使用的是现成的素材

安装 bootstrap 固定版本

npm i bootstrap@3.3.7

安装完成之后 ,在入口处引入 js 文件

import "./../node_modules/bootstrap/dist/css/bootstrap.css"; // 引入
import "./assets/index.css"; // 引入index.css

2、设计组件

页面可以分为三个组件来完成

设计头部组件

<template>
   <nav class="navbar navbar-inverse navbar-fixed-top">
        <div class="container-fluid">
            <div class="navbar-header">
                <a class="navbar-brand" href="#/">Vue 实践</a>
            </div>
        </div>
    </nav>
</template>

<script>
export default {

}
</script>

<style>
</style>

设计左边列表显示组件

<template>
  <div class="col-sm-3 col-md-2 sidebar">
    <ul class="nav nav-sidebar">
      <router-link tag="li" to="/1">
        <a href="#">1</a>
      </router-link>

      <router-link tag="li" to="/2">
        <a href="#">2</a>
      </router-link>

      <router-link tag="li" to="/3">
        <a href="#">3</a>
      </router-link>
    </ul>
  </div>
</template>

<script>
export default {};
</script>

<style>
</style>

注意:

  1. 添加 tag 属性后,对应对应生成 <li></li>标签
参考:https://segmentfault.com/q/1010000015169230
  1. 因为要使用路由实现页面的改变,所以使用 router-link

设计右边菜单组件

<template>
  <div>
    <h2 class="sub-header">Hero List</h2>
    <a class="btn btn-success" href="/#add">Add</a>
    <div class="table-responsive">
      <table class="table table-striped">
        <thead>
          <tr>
            <th>id</th>
            <th>姓名</th>
            <th>性别</th>
            <th>操作</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td>1</td>
            <td>2</td>
            <td>3</td>
            <td>
              <a href="javascript:;" >编辑</a> &nbsp;&nbsp;
              <a href="javascript:;" @click='deleteI(l.id)'>删除</a>
            </td>
          </tr>
        </tbody>
      </table>
    </div>
  </div>
</template>

<script>

export default {
    data(){
        
    },
}
</script>

<style>
</style>

3、使用组件

<template>
  <div id="app">
    <header-com></header-com>
    <div class="container-fluid">
        <div class="row">
            <list-com></list-com>
            <div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
              <router-view></router-view>
            </div>

        </div>
    </div>
  </div>
</template>

<script>
import headerCom from './components/header'
import listCom from './components/list'
import menuCom from './components/menu'

export default {
  name: 'App',
  components: {
    headerCom,
    listCom,
    menuCom
  }
}
</script>

<style>

</style>

注意:

  1. 这个位置应该是要放右边菜单组件,但是考虑到要通过路由来实现页面的改变,所以放上了路由试图

4、设计功能

路由功能

  1. 安装路由模块
 cnpm i vue-router
  1. 引用 router
 import VueRouter from 'vue-router'
  1. 使用 router
Vue.use(VueRouter)
  1. 设计路由表
import firstlist from '../components/menu.vue'
import twolist from '../components/twolist.vue'
import threelist from '../components/threelist.vue'
import add from '../components/add.vue'
import edit from '../components/edit.vue'

const routes = [
    {
        path: '/',
        redirect: '/1'
    },
    {
        path: '/1',
        component: firstlist
    },
    {
        path: '/2',
        component: twolist
    },
    {
        path: '/3',
        component: threelist
    },
    {
        path: '/add',
        component: add
    },
    {
        path: '/edit/:id',
        component: edit
    }
]
const router = new VueRouter({
    linkActiveClass: "active",
    routes: routes
})
  1. router 加入实例
new Vue({
  store,
  render: h => h(App),
  router
}).$mount('#app')
  1. 加入承载视图
<template>
  <div id="app">
    <header-com></header-com>
    <div class="container-fluid">
        <div class="row">
            <list-com></list-com>
            <div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
              <router-view></router-view>
            </div>

        </div>
    </div>
  </div>
</template>

提取路由模块

把路由业务抽取到 router.js

步骤:

  • 引入vue
  • 在最后一行把 router 对象暴露出去
  • 在 main.js 中引入 router.js
import Vue from 'vue'

import VueRouter from 'vue-router'// 引用router
Vue.use(VueRouter) // 使用router

import firstlist from '../components/menu.vue'
import twolist from '../components/twolist.vue'
import threelist from '../components/threelist.vue'
import add from '../components/add.vue'
import edit from '../components/edit.vue'

const routes = [
    {
        path: '/',
        redirect: '/1'
    },
    {
        path: '/1',
        component: firstlist
    },
    {
        path: '/2',
        component: twolist
    },
    {
        path: '/3',
        component: threelist
    },
    {
        path: '/add',
        component: add
    },
    {
        path: '/edit/:id',
        component: edit
    }
]
const router = new VueRouter({
    linkActiveClass: "active",
    routes: routes
})

//导出router
export default router
import router from './components/router'

列表渲染

当点击左边侧栏时,右边列表显示相应的信息

这里使用的是 json-server 模拟服务器的情况

  1. 安装 axios 插件
cnpm i axios
  1. 引入 axios
import axios from "axios"
  1. 定义数据
data(){
        return{
            list:[]
        }
    },
  1. 请求列表的方法封装
showDate(){
            axios.get('http://localhost:3000/heroes').then((rep)=>{
                this.list=rep.data
            }).catch((er)=>{
                console.log(er)
            });
        },
  1. 实例完成事件

还要定义方法的触发时间,当匹配到路由,跳转到列表页面时,触发函数,需要使用到钩子函数 mounted

mounted(){
            this.showDate()
        }
  1. 根据数据渲染列表

发送请求拿到数据后,还要在页面做相应的渲染

<template>
  <div>
    <h2 class="sub-header">Hero List</h2>
    <a class="btn btn-success" href="/#add">Add</a>
    <div class="table-responsive">
      <table class="table table-striped">
        <thead>
          <tr>
            <th>id</th>
            <th>姓名</th>
            <th>性别</th>
            <th>操作</th>
          </tr>
        </thead>
        <tbody>
          <tr v-for='l in list' :key='l.id'>
            <td>{{l.id}}</td>
            <td>{{l.name}}</td>
            <td>{{l.gender}}</td>
            <td>
              <a href="javascript:;" >编辑</a> &nbsp;&nbsp; &nbsp;&nbsp;
              <a href="javascript:;">删除</a>
            </td>
          </tr>
        </tbody>
      </table>
    </div>
  </div>
</template>

删除功能

当点击操作栏的删除按钮时,需要发送相应的请求进行删除

  1. 注册删除事件
<a href="javascript:;" @click='deleteI(l.id)'>删除</a>
  1. 定义删除方法
deleteI(id){
            if(confirm('是否要删除')){
                axios.delete('http://localhost:3000/heroes/'+id).then((rep)=>{
                    if(rep.status == 200){
                        this.showDate()
                    }
                }).catch(error=>{
                    console.log(error)
                })
            }
        }

注意:

  1. 因为删除需要 id 所以定义删除方法的时候 把 id 传进去
  2. 删除前一定要再次询问
  3. 删除请求完成后,需要判断删除情况
  4. 删除完成后,需要再次回到显示列表

新增功能

点击新增按钮时,首先需要跳转到新增页面

  1. 增加匹配路由
{
        path: '/add',
        component: add // 引入组件 配置路由
    },
  1. 添加 hash 以对应路由表
<a class="btn btn-success" href="/#add">Add</a>
  1. 添加页面
<template>
  <div>
    <h2 class="sub-header">Add 1</h2>
    <form>
      <div class="form-group">
        <label for="exampleInputEmail1">姓名</label>
        <input
          type="text"
          class="form-control"
          placeholder="请输入姓名"
        />
      </div>
      <div class="form-group">
        <label for="exampleInputPassword1">性别</label>
        <input
          type="text"
          class="form-control"
          placeholder="请输入性别"
        />
      </div>

      <button type="submit" class="btn btn-success">提交</button>
    </form>
  </div>
</template>
  1. v-model 绑定输入框
<input
type="text"
class="form-control"
v-model="formData.name"
placeholder="请输入姓名"
/>

<input
type="text"
class="form-control"
v-model="formData.gender"
placeholder="请输入性别"
/>

//1.添加数据
data() {
    return {
    // 定义一个数据对象 存储 姓名和性别
      formData: {
        name: "",
        gender: "",
      },
    };
  },
  1. 新增添加事件

输入框输入完毕后,点击确定按钮需要出发相应事件

<button type="submit" @click="addI" class="btn btn-success">提交</button>
addI() {
      if (this.formData.name && this.formData.gender) {
         axios
          .post("http://localhost:3000/heroes/", this.formData)
          .then((rep) => {
            if (rep.status == 201) {
              this.$router.push({
                path: "/",
              });
            } else {
              alert("添加失败");
            }
          });
      } else {
        alert("输入为空");
      }
    },

注意:

  1. 需要判断输入框是否为空
  2. 请求完成后,需要判断是否删除成功
  3. 使用编程式导航完成路由功能,跳转到列表页面

编辑功能

添加编辑路由 注意 由于需要拿到编辑数据的标识 所以需要动态路由

  1. 添加动态路由
{ path: "/edit/:id", component: Edit }
  1. 编辑按钮添加跳转的属性
<router-link :to="{path:'/edit/'+item.id }">编辑</router-link>
  1. 编辑页面
<template>
  <div>
    <h2 class="sub-header">编辑</h2>
    <form>
      <div class="form-group">
        <label for="exampleInputEmail1">姓名</label>
        <input
          type="text"
          class="form-control"
          v-model="formData.name"
          placeholder="请输入姓名"
        />
      </div>
      <div class="form-group">
        <label for="exampleInputPassword1">性别</label>
        <input
          type="text"
          class="form-control"
          v-model="formData.gender"
          placeholder="请输入性别"
        />
      </div>

      <button type="submit" class="btn btn-success">
        更新
      </button>
    </form>
  </div>
</template>
  1. 通过 id 获取数据
showInit() {
      axios
        .get("http://localhost:3000/heroes/" + this.$route.params.id)
        .then((rep) => {
          this.formData = rep.data;
        });
    },

页面加载完成时,执行该方法将数据回显到页面

mounted() {
    this.showInit();
  },
  1. 新增编辑事件
<button type="submit" @click="updateI" class="btn btn-success">
	更新
</button>
updateI() {
      if (this.formData.name && this.formData.gender) {
        axios
          .put("http://localhost:3000/heroes/" + this.$route.params.id, {
            name: this.formData.name,
            gender: this.formData.gender,
          })
          .then((rep) => {
            if (rep.status == 200) {
              this.$router.push({
                path: "/",
              });
            } else {
              alert("修改失败");
            }
          });
      } else {
        alert("不能为空");
      }
    },

注意:

  1. 需要判断输入框是否为空
  2. axios 发送更新请求需要传回 id、数据
  3. 请求完成后,使用编程式导航,跳转到列表页面

案例优化:axios 统一导入

每次组件使用到 axios 时,都需要导入 axios ,配置 axios 后不需要再导入

步骤:

  1. 在入口 main.js 文件中引入 axios,并赋值给全局 Vue 对象的原型
import Axios from "axios";
Vue.prototype.$http = Axios
  1. 调用接口时 采用 实例.属性的方式即可调用
this.$http

案例优化:设置 baseUrl

步骤 :

  1. 给 axios 中的 baseUrl 设置常态值
Axios.defaults.baseURL = "http://localhost:3000"; // 设置共享的方法
  1. 使用
// 没改造之前
'http://localhost:3000/heroes/'

// 设置完常态值
'/heroes/'

案例优化:统一设置激活样式

点击左边侧边栏时,路由跳转时,不知道点击的是哪一个,使用激活样式,显示点击的栏

router.js 的路由表上面加上

linkActiveClass: "active", // active为bootstrap中的 一个class样式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值