vue-cli从零开始实现一个仿豆瓣app(一)

最近利用vue+nodejs+mysql实现了一个简单的仿豆瓣网站,记录一下实现的过程。

先放上github地址:https://github.com/jaminejiang/douban.git

首先是搭建框架。

项目需要安装的是node和git,这里不详细讲

快速搭建vue-cli可以按照官网的步骤: 点击打开链接
# 全局安装 vue-cli
$ npm install --global vue-cli
# 创建一个基于 webpack 模板的新项目
$ vue init webpack my-project
# 安装依赖,走你
$ cd my-project
$ npm install
$ npm run dev
webpack帮我们打包好了,简单的看一下生成的\build\webpack.base.conf.js中的内容
entry: {
    app: './src/main.js'
  },
  output: {
    path: config . build . assetsRoot ,
    filename: '[name].js' ,
    publicPath: process . env . NODE_ENV === 'production'
      ? config . build . assetsPublicPath
      : config . dev . assetsPublicPath
  },
entry规定了入口为main.js,通过这个入口index.html页面就可以利用main.js渲染App.vue.

接下来搭建后台服务器部分,以实现操作数据库等。

在根目录创建一个server文件夹,文件夹中api文件夹实现业务逻辑,db.js封装数据库的信息,包括用户名密码等,sqlMap实现映射sql语句,而index.js则是服务器的入口。
用git在server文件夹上git bash,引入依赖的包,包括最终要的express和mysql,body-parser等。
之后就可以在命令行敲nodemon index启动后台服务器啦。
注意后台的端口是3000,前台是8080,这里有跨域问题。
app . listen ( 3000 );  //监听的端口号
console . log ( 'success listen at port:3000......' );
这里要设置代理与跨域,方法就是设置vue的映射表。
在config文件夹的index.js文件中,加入以下proxyTable设置
// Paths
    assetsSubDirectory: 'static' ,
    assetsPublicPath: '/' ,
    proxyTable: {
      '/api' : {
        target: 'http://127.0.0.1:3000/api/' ,
        changeOrigin: true ,
        pathRewrite: {
            '^/api' : ''
        }
      }
    },

意思就是前台请求中带有/api的地址都会映射到http://127.0.0.1:3000/api中,而在server的index.js中就可以将请求的地址与业务逻辑模块一一对应。
项目最终的映射如下:
app . use ( '/api/user' , userApi );           //到地址'/api/user'的请求将映射到userApi
app . use ( '/api/film' , filmApi );          //到地址'/api/film'的请求将映射到filmApi
app . use ( '/api/search' , searchApi );          //到地址'/api/search'的请求将映射到searchApi

到这里为止前后台的交流已经实现了。
接下来就是写个简单的登陆注册来测试一下。

登陆注册实现

无论学开发什么,最开始我都是登陆注册啊,又简单又能树立信心。
这里先讲一下router映射。

在项目的src文件夹下建一个router.js文件,用来处理前端路由。
import mainComponent from './components/mainComponent'
import userComponent from './components/userComponent'
import userIsLogin from './components/checkIsUserLogin'
import userGoToLogin from './components/loginStyle'

const routers = [
    {
        path: '/' ,
        redirect: '/main' ,
        meta: {
            keepAlive: false
        }
    },
    {
        path: '/main' ,
        name: 'mainPage' ,
        component:mainComponent ,
        meta: {
            keepAlive: false
        }
    },
    {
        path: '/userAuthority' ,
        name: 'userPage' ,
        component:userComponent ,
        meta: {
            keepAlive: false
        },
        children: [
            {
                path: 'checkUserLogin' ,
                component:userIsLogin ,
                meta: {
                    keepAlive: false
                }
            },
            {
                path: 'goToLogin' ,
                component:userGoToLogin ,
                meta: {
                    keepAlive: false
                }
            }
        ] 
    },
   
]
export default routers

设置好router之后还要在入口文件中注册这个router
import Vue from 'vue'
import App from './App'
import vueRouter from 'vue-router'
import routers from './routers'

Vue . config . productionTip = false

Vue . use ( vueRouter );
const router = new vueRouter ({
  mode: 'history' ,
  routes:routers
});

/* eslint-disable no-new */
new Vue ({
  el: '#app' ,
  router ,
  render : h => h ( App )
})
这个router设置一进入主界面就跳转到首页,即展示最新的电影、电视剧等
App.vue中固定了footer,footer中有两个按钮可以在首页和登陆页切换。
import Vue from 'vue'
import App from './App'
import vueRouter from 'vue-router'
import routers from './routers'

Vue.config.productionTip = false

Vue.use(vueRouter);
const router = new vueRouter({
  mode:'history',
  routes:routers
});

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  render: h => h(App)
})

上面的userComponent就是实现登陆注册的。
登陆注册模块一跳进去先后台检查是否已经登陆,如果没有才跳转到登陆界面,否则显示用户名。这部分先跳过,直接讲登陆注册。

我是把登陆框和注册框写在一个页面,通过v-if切换,其实回过头看这里完全可以写一个组件从而实现复用,有时间再优化一下吧。
html就略过了,直接看交互部分。

引入axios,实现类似ajax功能。
import axios from 'axios'
import vue from 'vue'
vue.prototype.$axios = axios

goToLogin:function(){    //登陆请求
            if(!this.loginUserName||!this.loginPwd){  //请求框没有输入完整
                this.operateModal(1);
                return false;
            }else{
                var _this = this;
                var loginData = {'username':this.loginUserName,'password':this.loginPwd};

                this.$axios.post('/api/user/queryUser',loginData).then(function(res){

                    if(res.data==-1){                //用户名不存在
                        _this.loginUserName = '';
                        _this.loginPwd = '';
                        _this.operateModal(2);
                    }else if(res.data==0){          //密码错误
                        _this.loginPwd = '';
                        _this.operateModal(3);
                    }else if(res.data==1){          //登陆成功
                        _this.operateModal(4);
                    }
                }).catch(function(err){
                    console.log(err);
                });

            }
        },

在server的api中建一个userApi。js文件

var models = require('../db');
var express = require('express');
var router = express.Router();
var mysql = require('mysql');
var $sql = require('../sqlMap');
var session = require('express-session');
var cookieParser = require('cookie-parser');

router.use(cookieParser());
router.use(session({
    secret:'123456',
    resave: true,
    saveUninitialized:false
    })
);

//连接数据库
var conn = mysql.createConnection(models.mysql);
conn.connect();

//查询用户接口
router.post('/queryUser',(request,response) => {
    var body = request.body;
    var queryUser = $sql.user.query_user;
    conn.query(queryUser,body.username, function( err , result ){
        if(err){
            console.log(err);            //数据库操作失败
        }
        if(result[0]===undefined){
            response.send('-1');             //查询不到该用户名
        }else{
            if(result[0].password!==body.password){
                response.send('0');          //密码错误
            }else{
                request.session.sessionUserName = body.username;
                request.session.sessionUserId = result[0].userid;
                response.send('1');          //查询到该用户,登陆成功
            }
        }
    });
});

数据库语句和数据库设置部分就跳过,可以用navicat在数据库中手动创建几个用户信息就可以测试登陆啦。
注册部分后台代码如下:


router.post('/addUser',( request , response ) => {
    var body = request.body;
    var addUser = $sql.user.add;
    var query_user = $sql.user.query_user;
    conn.query(query_user, body.username,function( err , result){
        if(err){
            console.log(err);
        }
        if(result[0]===undefined){
            conn.query(addUser,[body.username,body.password],function( erradd , res){
                if(erradd){
                    console.log(erradd);
                }
                if(res){
                    request.session.sessionUserId = res.insertId;
                    request.session.sessionUserName = body.username;
                    response.send('1');             //插入成功
                }
            });
        }else{
            response.send('0');                  //用户已存在,插入失败
        }
    });
});


到这里就可以初步跑起来了。

版权声明:本文为qq_40063133原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。