ThinkPHP6.0 + Vue + ElementUI + axios 的环境安装到实现 CURD 操作!

戏子无情 提交于 2020-10-07 01:02:31
  1. 官方文档地址:

    ​ ThinkPHP6.0: https://www.kancloud.cn/manual/thinkphp6_0/1037479

    ​ ElemetUI: https://element.eleme.cn/#/zh-CN

    ​ axios: https://www.kancloud.cn/yunye/axios/234845

    ​ Vue: https://cn.vuejs.org/v2/guide

  2. 创建码云仓库

  3. 克隆到本地

    git clone 你自己的仓库地址 0608
    
  4. 创建数据库

    -- 创建数据库 0608
    create database `0608` charset utf8;
    -- 创建数据表 user
    create table `user` (
    	`id` int(11) primary key auto_increment comment '用户ID',
    	`name` varchar(30) not null default '未知' comment '用户名',
    	`pwd` varchar(32) not null default '未知' comment '用户密码' 
    ) engine = InnoDB;
    -- 给 user.name 添加唯一索引
    alter table `user` add unique key u_name(`name`);
    -- 给 user.pwd 添加普通索引
    alter table `user` add index u_pwd(`pwd`);
    -- 创建数据表 school
    create table `school` (
    	`id` int(11) primary key auto_increment comment '学校ID',
    	`name` varchar(30) not null default '未知' comment '学校名',
    	`city` varchar(30) not null default '未知' comment '学校城市',
    	`num` varchar(30) not null default '0' comment '学校人数'
    ) engine = InnoDB;
    
  5. 进入项目

    cd 0608
    
  6. 安装ThinkPHP6.0

    composer create-project topthink/think php
    
  7. 配置域名/URL重写

    # 自行去配置域名
    # url 重写
    location / { 
       # 省略部分代码
       if (!-e $request_filename) {
       		rewrite  ^(.*)$  /index.php?s=/$1  last;
        }
    }
    
  8. 修改配置文件 .env 【来源于项目中的 .example.env】

    APP_DEBUG = true
    
    [APP]
    DEFAULT_TIMEZONE = Asia/Shanghai
    
    [DATABASE]
    TYPE = mysql
    HOSTNAME = 127.0.0.1
    DATABASE = 0608
    USERNAME = root
    PASSWORD = root
    HOSTPORT = 3306
    CHARSET = utf8
    DEBUG = true
    
    [LANG]
    default_lang = zh-cn
    
  9. 开启错误调试模式

    // 1 .env 文件中第 1 行
    APP_DEBUG = true
    
    // 2 config/app.php 中第 33 行
     'show_error_msg'   => true
    
  10. 初始化vue

    查看node、npm、cnpm、vue-cli是否安装成功

    // 查看 node 版本
    node -v
    // 查看 npm 版本
    npm -v
    // 查看 cnpm 版本
    cnpm -v
    // 查看 vue 版本
    vue -V
    // 初始化项目
    vue init webpack vue
    
  11. 进入vue进行测试、查看是否安装成功

    // 进入 vue 项目中
    cd vue
    // npm 启动项目
    npm run dev
    
    
  12. 安装 Element-UI、axios

    // 安装 ElementUI
    cnpm install element-ui --save
    // 安装 axios
    cnpm install axios --save
    
    
  13. 在 vue/src/main.js 中增加以下内容

    // 引入 elementUI
    // https://element.eleme.cn/#/zh-CN/component/quickstart
    import ElementUI from 'element-ui';
    import 'element-ui/lib/theme-chalk/index.css';
    Vue.use(ElementUI);
    // 引入 axios
    // https://segmentfault.com/a/1190000013128858
    import axios from 'axios'
    Vue.prototype.$ajax = axios
    
    
  14. 将初始化好的项目提交到远程仓库

    // 进入项目中
    cd 0608
    // 查看状态【红色、提示使用 git add 】
    git status
    // 添加代码到仓库
    git add ./
    // 查看状态【绿色、Changes to be committed:】
    git status
    // 提交代码到本地仓库
    git commit -m '提交注释'
    // 查看状态
    git status
    // 将远程仓库的更新拉取到本地
    git pull
    // 查看状态
    git status
    // 将本地的更新提交到远程仓库
    git push
    
    
  15. 添加资源控制器/模型层/资源路由

    // 使用命令行:创建资源控制器
    php think make:controller School
    // 使用命令行:创建模型
    php think make:model School
      
    // 添加资源路由 php/route/app.php
    // 跨域请求【路由->跨域请求】
    Route::resource('school', 'School')->allowCrossDomain();
    
    
  16. 编辑 curd 接口 - 控制器 - School.php

    <?php
    
    declare(strict_types=1);
    namespace app\controller;
    use app\model\School as ModelSchool;
    use think\facade\Validate;
    use think\Request;
    
    class School
    {
        /**
         * 显示资源列表
         * 【get】http://0608.cc/school
         * 【get】http://0608.cc/school?page=2
         *
         * @return \think\Response
         */
        public function index(ModelSchool $school)
        {
            $pageSize = 3;
            $res = $school->getPage($pageSize);
            if ($res) {
                return json(['code' => 0, 'msg' => 'ok', 'res' => $res]);
            } else {
                return json(['code' => 1, 'msg' => 'no', 'res' => null]);
            }
        }
    
        /**
         * 显示创建资源表单页.
         *
         * @return \think\Response
         */
        public function create()
        {
            //
        }
    
        /**
         * 保存新建的资源
         * 【post】http://0608.cc/school?name=shbw&city=&num=10000
         *
         * @param  \think\Request  $request
         * @return \think\Response
         */
        public function save(Request $request, ModelSchool $school)
        {
            // 接收数据
            $data['name'] = $request->param('name', '');
            $data['city'] = $request->param('city', '');
            $data['num'] = $request->param('num', '0');
            // 数据验证
            $rule = [
                'name' => 'require|max:30|min:2',
                'city' => 'require',
                'num'  => 'require'
            ];
            $message = [
                'name.require'  => '学校名称是必填项',
                'name.max'      => '学校名称最多30位',
                'name.min'      => '学校名称最少2位',
                'city.require'  => '学校所在城市是必填项',
                'num.require'   => '学校现有人数是必填项'
            ];
            // 粘贴来自于手册:验证->验证规则->方法定义
            $validate = Validate::rule($rule)->message($message);
            if (!$validate->check($data)) {
                return json(['code' => 1, 'msg' => $validate->getError(), 'res' => null]);
            }
            // 调用模型
            $res = $school->addOne($data);
            if ($res) {
                return json(['code' => 0, 'msg' => '添加成功', 'res' => $res]);
            } else {
                return json(['code' => 1, 'msg' => '添加失败', 'res' => $res]);
            }
        }
    
        /**
         * 显示指定的资源
         * 【get】http://0608.cc/school/3
         *
         * @param  int  $id
         * @return \think\Response
         */
        public function read($id, ModelSchool $school )
        {
            $where['id'] = $id;
            $res = $school->selOne($where);
            if ($res) {
                return json(['code' => 0, 'msg' => '查询成功', 'res' => $res]);
            } else {
                return json(['code' => 1, 'msg' => '查询失败', 'res' => $res]);
            }
        }
    
        /**
         * 显示编辑资源表单页.
         *
         * @param  int  $id
         * @return \think\Response
         */
        public function edit($id)
        {
            //
        }
    
        /**
         * 保存更新的资源
         * 【put】http://0608.cc/school/3?name=bjbw3&city=bj3&num=30000
         *
         * @param  \think\Request  $request
         * @param  int  $id
         * @return \think\Response
         */
        public function update(Request $request, $id, ModelSchool $school)
        {
            // 接收数据
            $where['id'] = $id;
            $data['name'] = $request->param('name', '');
            $data['city'] = $request->param('city', '');
            $data['num'] = $request->param('num', '0');
            // 数据验证
            $rule = [
                'name' => 'require|max:30|min:2',
                'city' => 'require',
                'num'  => 'require'
            ];
            $message = [
                'name.require'  => '学校名称是必填项',
                'name.max'      => '学校名称最多30位',
                'name.min'      => '学校名称最少2位',
                'city.require'  => '学校所在城市是必填项',
                'num.require'   => '学校现有人数是必填项'
            ];
            // 粘贴来自于手册:验证->验证规则->方法定义
            $validate = Validate::rule($rule)->message($message);
            if (!$validate->check($data)) {
                return json(['code' => 1, 'msg' => $validate->getError(), 'res' => null]);
            }
            // 调用模型
            $res = $school->updOne($where, $data);
            if ($res) {
                return json(['code' => 0, 'msg' => '修改成功', 'res' => $res]);
            } else {
                return json(['code' => 1, 'msg' => '修改失败', 'res' => $res]);
            }
        }
    
        /**
         * 删除指定资源
         * 【delete】http://0608.cc/school/1
         *
         * @param  int  $id
         * @return \think\Response
         */
        public function delete($id, ModelSchool $school)
        {
            $where['id'] = $id;
            $res = $school->delOne($where);
            if ($res) {
                return json(['code' => 0, 'msg' => '删除成功', 'res' => $res]);
            } else {
                return json(['code' => 1, 'msg' => '删除失败', 'res' => $res]);
            }
        }
    }
    
    
  17. 编辑 curd 接口 - 模型层 - School.php

    <?php
    declare (strict_types = 1);
    namespace app\model;
    use think\Model;
    
    /**
     * @mixin think\Model
     */
    class School extends Model
    {
        protected $table = 'school';
        protected $pk = 'id';
        // 设置字段信息
        protected $schema = [
            'id'          => 'int',
            'name'        => 'string',
            'city'        => 'string',
            'num'         => 'string'
        ];
    
        /**
         * 分页
         */
    
        public function getPage( $pageSize)
        {
            return self::paginate( $pageSize );
        }
    
        /**
         * 添加一条数据
         */
    
        public function addOne($data)
        {
            return self::insert( $data );
        }
    
        /**
         * 删除数据
         */
    
        public function delOne($where)
        {
            return self::where( $where )->delete();
        }
    
        /**
         * 修改
         */
    
        public function updOne($where,$data)
        {
            return self::where( $where )->update( $data );
        }
    
        /**
         * 查询一条
         */
    
        public function selOne($where)
        {
            return self::where( $where )->find();
        }
    }
    
    
  18. 使用Postman测试 curd 接口

    # 展示/分页 get
    http://0608.cc/school
    http://0608.cc/school?page=2
    # 添加 post 
    http://0608.cc/school?name=shbw&city=&num=10000
    # 根据 ID 查询一个 get 
    http://0608.cc/school/3
    # 修改 put
    http://0608.cc/school/3?name=shbw&city=&num=10000
    # 删除 delete
    http://0608.cc/school/1
    
    
  19. Vue中添加路由/页面

    // 在 vue/src/ 中增加 page/school/{ list.vue,add.vue }
    // 增加路由 vue/router/index.js
    import Vue from 'vue'
    import Router from 'vue-router'
    import HelloWorld from '@/components/HelloWorld'
    // 导入登录页面
    import login from '@/page/main/login.vue'
    // 导入以下页面
    import schoolList from '@/page/school/list.vue'
    import schoolAdd from '@/page/school/add.vue'
    import schoolEdit from '@/page/school/edit.vue'
    
    Vue.use(Router)
    
    export default new Router({
      routes: [{
          path: '/',
          name: 'HelloWorld',
          component: HelloWorld
        },
        {
          path: '/login',
          name: 'login',
          component: login
        },
        {
          path: '/schoolList',
          name: 'schoolList',
          component: schoolList
        },
        {
          path: '/schoolAdd',
          name: 'schoolAdd',
          component: schoolAdd
        },
        {
          path: '/schoolEdit',
          name: 'schoolEdit',
          component: schoolEdit
        }
      ]
    })
    
    
  20. 展示页面 - list.vue

    <template>
      <div>
        <a href="/#/schoolAdd"><el-button type="button" size="small" style="float: left;">数据添加</el-button></a>
        <!--  展示表格 start https://element.eleme.cn/#/zh-CN/component/table -->
        <el-table :data="tableData" stripe style="width: 100%">
          <el-table-column prop="id" label="ID" width="150"></el-table-column>
          <el-table-column prop="name" label="学校名" width="150"></el-table-column>
          <el-table-column prop="city" label="所在城市" width="150"></el-table-column>
          <el-table-column prop="num" label="人数" width="150"></el-table-column>
          <el-table-column label="操作">
            <template slot-scope="scope">
              <el-button @click.native.prevent="deleteRow(scope.row)" type="text" size="small">删除</el-button>
              <el-button @click.native.prevent="editRow(scope.row)" type="text" size="small">编辑</el-button>
            </template>
          </el-table-column>
        </el-table>
        <!--  展示表格 end -->
        <!-- 分页控件 start https://element.eleme.cn/#/zh-CN/component/pagination -->
        <el-pagination background layout="prev, pager, next" :total="total" :page-size="pageSize" @current-change="getCurrentPage"></el-pagination>
        <!-- 分页控件 end -->
      </div>
    </template>
    
    <script>
    export default {
      data() {
        return {
          tableData: [],
          currentPage: 1,
          total: 0,
          pageSize: 3
        };
      },
      created() {
        var _self = this;
        _self.getPage();
      },
      methods: {
        // 调用接口、获取分页数据
        getPage: function() {
          var _self = this;
          // 使用 ajax 请求后台提供的展示接口
          _self.$ajax
            .get('http://0608.cc/school', {
              params: {
                page: _self.currentPage
              }
            })
            .then(function(response) {
              _self.tableData = response.data.res.data;
              _self.total = response.data.res.total;
            })
            .catch(function(error) {
              console.log(error);
            });
        },
        //当前页改变事件
        getCurrentPage: function(page) {
          var _self = this;
          // 改变当前页码
          _self.currentPage = page;
          // 获取当前页数据
          _self.getPage();
        },
    
        // 删除一条数据
        deleteRow(data) {
          var _self = this;
          var id = data.id;
          _self.$ajax
            .delete('http://0608.cc/school/' + id)
            .then(function(response) {
              alert(response.data.msg);
              if (response.data.code == 0) {
                _self.getPage();
              }
            })
            .catch(function(error) {
              console.log(error);
            });
        },
        // 编辑
        editRow(row) {
          this.$router.push({ name: 'schoolEdit', params: row });
        }
      }
    };
    </script>
    
    <style></style>
    
    
  21. 添加页面 - add.vue

    <template>
      <div>
        <a href="/#/schoolList"><el-button type="button" size="small" style="float: left;">数据列表</el-button></a>
        <br />
        <br />
        <!--  表单 start https://element.eleme.cn/#/zh-CN/component/form -->
        <el-form :model="dataForm" status-icon ref="dataForm" label-width="100px" class="">
          <el-form-item label="学校名称" prop="name"><el-input type="text" v-model="dataForm.name"></el-input></el-form-item>
          <el-form-item label="所在城市" prop="city"><el-input type="text" v-model="dataForm.city"></el-input></el-form-item>
          <el-form-item label="人数" prop="num"><el-input type="number" v-model.number="dataForm.num"></el-input></el-form-item>
          <el-form-item>
            <el-button type="primary" @click="submitForm()">提交</el-button>
            <el-button @click="resetForm('dataForm')">重置</el-button>
          </el-form-item>
        </el-form>
        <!--  表单 end -->
      </div>
    </template>
    
    <script>
    export default {
      data() {
        return {
          dataForm: {
            name: '',
            city: '',
            num: ''
          }
        };
      },
      methods: {
        submitForm() {
          var _self = this;
          _self.$ajax
            .post('http://0608.cc/school', _self.dataForm)
            .then(function(response) {
              // 不管成功与失败、都弹出消息
              alert(response.data.msg);
              // 判断是否成功、成功跳转至展示页面
              if (response.data.code == 0) {
                _self.$router.push({ name: 'schoolList' });
              }
            })
            .catch(function(error) {
              console.log(error);
            });
        },
        resetForm(formName) {
          this.$refs[formName].resetFields();
        }
      }
    };
    </script>
    
    <style></style>
    
    
  22. 修改页面

    <template>
      <div>
        <a href="/#/schoolList"><el-button type="button" size="small" style="float: left;">数据列表</el-button></a>
        <br />
        <br />
        <!--  表单 start https://element.eleme.cn/#/zh-CN/component/form -->
        <el-form :model="dataForm" status-icon ref="dataForm" label-width="100px" class="">
          <el-form-item label="学校名称" prop="name"><el-input type="text" v-model="dataForm.name"></el-input></el-form-item>
          <el-form-item label="所在城市" prop="city"><el-input type="text" v-model="dataForm.city"></el-input></el-form-item>
          <el-form-item label="人数" prop="num"><el-input type="number" v-model.number="dataForm.num"></el-input></el-form-item>
          <el-form-item>
            <el-button type="primary" @click="submitForm()">提交</el-button>
            <el-button @click="resetForm('dataForm')">重置</el-button>
          </el-form-item>
        </el-form>
        <!--  表单 end -->
      </div>
    </template>
    
    <script>
    export default {
      data() {
        return {
          dataId: this.$route.params.id,
          dataForm: {
            name: this.$route.params.name,
            city: this.$route.params.city,
            num: this.$route.params.num
          }
        };
      },
      methods: {
        submitForm() {
          var _self = this;
          _self.$ajax
            .put('http://0608.cc/school/' + _self.dataId, _self.dataForm)
            .then(function(response) {
              // 不管成功与失败、都弹出消息
              alert(response.data.msg);
              // 判断是否成功、成功跳转至展示页面
              if (response.data.code == 0) {
                _self.$router.push({ name: 'schoolList' });
              }
            })
            .catch(function(error) {
              console.log(error);
            });
        },
        resetForm(formName) {
          this.$refs[formName].resetFields();
        }
      }
    };
    </script>
    
    <style></style>
    
    
  23. 登录页面

    <template>
      <div>
        <!--  表单 start https://element.eleme.cn/#/zh-CN/component/form -->
        <el-form :model="dataForm" status-icon ref="dataForm" label-width="100px" class="">
          <el-form-item label="用户名" prop="name"><el-input type="text" v-model="dataForm.name"></el-input></el-form-item>
          <el-form-item label="密码" prop="pwd"><el-input type="password" v-model="dataForm.pwd"></el-input></el-form-item>
          <el-form-item>
            <el-button type="primary" @click="submitForm()">登录</el-button>
            <el-button @click="resetForm('dataForm')">重置</el-button>
          </el-form-item>
        </el-form>
        <!--  表单 end -->
      </div>
    </template>
    
    <script>
    export default {
      data() {
        return {
          dataForm: {
            name: '',
            pwd: ''
          }
        };
      },
      methods: {
        submitForm() {
          var _self = this;
          _self.$ajax
            .get('http://0608.cc/login', { params: _self.dataForm })
            .then(function(response) {
              // 不管成功与失败、都弹出消息
              alert(response.data.msg);
              // 判断是否成功、成功跳转至展示页面
              if (response.data.code == 0) {
                _self.$router.push({ name: 'schoolList' });
              }
            })
            .catch(function(error) {
              console.log(error);
            });
        },
        resetForm(formName) {
          this.$refs[formName].resetFields();
        }
      }
    };
    </script>
    
    <style></style>
    
    
  24. 完工!!

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!