vue+ имитация яйца Booking.com

Vue.js

图片

предисловие

Этот проект является имитацией страницы Booking.com, потому что страницу авиабилетов booking.com нельзя открыть, поэтому страницы билетов нет, и я написал только страницу бронирования, страницу входа и страницу регистрации для бэк-энда. апи Прошу простить меня за неадекватность.

стек технологий

Передняя часть: vue + стилус + аксиомы

Серверная часть: egg.js + mysql + продолжение

Развертывание: nginx + xshell + Xftp

Демонстрация эффекта

Интерфейс Vue

Инкапсуляция маршрута папки utils

Инкапсуляция запроса axios

import axios from 'axios'

const host = 'http://127.0.0.1:7001/api'
export { host }

function request (url, method, data, header = {}) {
  return new Promise((resolve, reject) => {
    return axios({
      method: method,
      url: host + url,
      data: data,
      header: {
        'content-type': 'application/json' // 默认值
      }
    }).then((res) => {
      resolve(res.data)
    }).catch(error => {
      reject(error)
    })
  })
}

export function get (url, data) {
  return request(url, 'GET', data)
}

export function post (url, data) {
  return request(url, 'POST', data)
}

router.js

ленивая загрузка маршрутов

import Vue from 'vue'
import Router from 'vue-router'

const _import_ = file => () => import(`@/pages/${file}.vue`)

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      redirect: '/booking'
    },
    {
      path: '/booking',
      name: 'booking',
      component: _import_('booking'),
      children: [
        {
          path: '/',
          name: '/',
          component: _import_('hotel'),
          meta: {
            title: 'Booking.com | 官网 | 热门酒店和民宿'
          }
        },
        {
          path: 'plane',
          name: 'plane',
          component: _import_('plane'),
          meta: {
            title: 'Booking 飞机'
          }
        },
        {
          path: 'rentCar',
          name: 'rentCar',
          component: _import_('rentCar'),
          meta: {
            title: 'Booking 租车'
          }
        },
        {
          path: 'fWheel',
          name: 'fWheel',
          component: _import_('fWheel'),
          meta: {
            title: 'Booking 观光和活动'
          }
        },
        {
          path: 'taxi',
          name: 'taxi',
          component: _import_('taxi'),
          meta: {
            title: 'Booking 出租车'
          }
        }
      ]
    },
    {
      path: '/user/login',
      name: 'login',
      component: _import_('login'),
      meta: {
        title: '登录'
      }
    },
    {
      path: '/user/register',
      name: 'register',
      component: _import_('register'),
      meta: {
        title: '注册'
      }
    }
  ]
})

Написание страницы

Остальное - написать страницу, пожалуйста, смотрите бэкэнд ниже.

задняя часть

структура страницы

后端

Создание сиквела

  • Установить продолжение

Вы можете проверить это

  • Добавьте следующий код в файл config.default.js конфигурации.
config.sequelize = {
    dialect:'mysql',
    host:'127.0.0.1',
    port: 3306,
    username: 'root',
    password: '******',
    database: 'booking'
  }
  • Добавьте код в файл конфигурации plugin.js.
// Sequelize插件
  sequelize: {
    enable:true,
    package:'egg-sequelize'
  }
  • Создайте файл .sequelizer в том же каталоге, что и приложение, и напишите следующий код.
'use strict'

const path = require('path');

module.exports = {
  config: path.join(__dirname, 'database/config.json'),
  'migrations-path': path.join(__dirname, 'database/migrations'),
  'seeders-path': path.join(__dirname, 'database/seeders'),
  'models-path': path.join(__dirname, 'app/model')
}

Выполните команду инициализации продолжения

./node_modules/.bin/sequelize init

Наконец, используйте команду sequenceize, чтобы создать таблицу и добавить начальные данные.sequelizeВы также можете посмотреть на выше

междоменная проблема

Добавьте следующий код в файл config.default.js конфигурации.

config.security = {
    csrf: {
      enable: false,
      ignoreJSON: true
    },
    domainWhiteList: ['*']
  };
  
  config.cors = {
    origin: '*',
    allowMethods: 'GET,HEAD,PUT,POST,DELETE,PATCH'
  };
  • Добавьте код в файл конфигурации plugin.js.
cors: {
	  enable: true,
	  package: 'egg-cors'
  },

ссылка mysql

  • Установить MySQL
  • Создайте файл базы данных config.js в том же каталоге приложения.
{
  "development": {
    "username": "root",
    "password": "******",
    "database": "booking",
    "host": "127.0.0.1",
    "dialect": "mysql",
    "operatorsAliases": false
  },
  "test": {
    "username": "root",
    "password": "******",
    "database": "booking",
    "host": "127.0.0.1",
    "dialect": "mysql",
    "operatorsAliases": false
  },
  "production": {
    "username": "root",
    "password": "******",
    "database": "booking",
    "host": "127.0.0.1",
    "dialect": "mysql",
    "operatorsAliases": false
  }
}

Пишем бэкенд API

router.js

'use strict';

/**
 * @param {Egg.Application} app - egg application
 */
module.exports = app => {
  const { router, controller } = app;
  router.prefix('/api')
  router.get('/booking/currency', controller.booking.getCurrency);
  router.get('/booking/location', controller.booking.getLocation);
  router.get('/booking/hotelType', controller.booking.getHotelType);
  router.get('/booking/hotelRent', controller.booking.getHotelRent);
  router.get('/booking/hotelStation', controller.booking.getHotelStation);
  router.post('/user/login', controller.user.login)
  router.post('/user/register', controller.user.register)
};

слой контроллера

'use strict';

const Controller = require('egg').Controller;

class UserController extends Controller {
  async login() {
    const { ctx } = this;
    const { username, password } = ctx.request.body
    await ctx.service.user.loginIn({ username, password })
  }

  async register() {
    const { ctx } = this;
    const { username, password } = ctx.request.body
    await ctx.service.user.register({ username, password })
  }
}

module.exports = UserController;

сервисный уровень

const Service = require('egg').Service

class UserService extends Service {
  async loginIn(user) {
    // sql 及存储业务的组织
    const { ctx, app } = this
    const userInfo = await ctx.model.User.findOne({where: { username: user.username }})
    console.log(userInfo)
    let msg = ''
    let code = 0
    if (userInfo == null) {
      msg = '用户不存在,请注册'
      code = 378
    } else {
      if (user.password != userInfo.password) {
        msg = '密码错误,请重新输入'
        code = 399
      } else {
        msg = '登录成功'
        code = 200
      }
    }
    ctx.body = {
      msg: msg,
      code: code
    }
  }

  async register(user) {
    // sql 及存储业务的组织
    const { ctx, app } = this
    let msg = ''
    let code = 0
    const userInfo = await ctx.model.User.findOne({where: { username: user.username }})
    if (userInfo != null) {
      msg = '用户已存在,请重新注册'
      code = 356
    } else {
      await ctx.model.User.create(user)
      msg = '注册成功'
      code = 200
    }
    ctx.body = {
      msg: msg,
      code: code
    }
  }
}

module.exports = UserService

слой модели

module.exports = app => {
  // console.log('model层')
  const { INTEGER, STRING, BOOLEAN }  = app.Sequelize;
  const user = app.model.define('user', {
    id: {
      allowNull: false,// 允许为空吗
      primaryKey: true,// 主键
      autoIncrement: true,// 自增
      type: INTEGER,// 类型
      comment: '用户id'
    },
    username: {
      type: STRING(50),
      primaryKey: true,// 主键
      allowNull: false,
      defaultValue: '',
      comment: '用户名'
    },
    password: {
      type: STRING(32),
      allowNull: false,
      defaultValue: '',
      comment: '用户密码'
    },
    disabled: {
      type: BOOLEAN,
      allowNull: false,
      defaultValue: false,
      comment: '是否是禁用状态'
    }
  },
  {
    timestamps: false,
    tableName: 'user',
    underscored: false
  })
  // console.log(location, '-----')
  return user
}

Задняя часть почти Наконец-то сайт запущен

Развертывание веб-сайта

Развертывание веб-сайта здесь

Создание и настройка сервера Nginx

egg.js развернут на сервере

установка nginx и mysql

установка nginx и mysql

Настройка конфигурации Nginx подробные инструкции

Большое спасибо за вышеуказанную документацию

Мой адрес на гитхабе:мой гитхаб

Адрес веб-сайта:адрес веб-сайта(Срок действия сервера истек)

наконец

В конце, конечно, наглеть и просить еще одну звезду.Если вы считаете, что мой проект неплох, дайте звезду, чтобы его поощрить~