前后端分离:必备——你不得不知道的那些事儿

这篇文章主要整理一下WebPack、Vue-CLI、ElementUI、Axios这些前后端分离中一定会用到的知识点


 0.引言

上一篇文章前后端分离:前导——后端程序员能看懂的VUE整理了一些Vue的基本语法和知识点,在搬砖的过程中后端程序员不至于看不懂前端的代码;这篇文章将继续整理前后端分离所需要的知识点,主要分为WebPack、Vue-CLI、ElementUI、Axios这几个部分,分别讲述了如何打包程序成为现在市面上浏览器都能看懂的代码、规模化的生产前端代码、高效简洁堪比HTML/CSS/JS时期Bootstrap的神器ElementUI、以及前后端分离最重要的工具Axios。

1.Webpack

本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle

很多网站都是基于ES5+的,但是Vue是基于ES6+开发的,所以我们就需要一个工具来将ES6+降级为ES5+来满足各浏览器的需要,对详细的教程感兴趣的同学可以移步webpack官网文档,这里我只讲一下最基本的如何将程序打包。

在之前的程序中,如果需要加载一些文件通常会选用<script>直接引用,虽然很方便,但是也有一些显而易见的弊端:

  • 全局作用域下容易造成变量冲突;
  • 文件只能按照<script>的书写顺序进行加载;
  • 开发人员必须主观的解决各模板之间和代码库的依赖关系;
  • 在大型项目中各种资源难以管理,长期积累的问题导致代码库混乱不堪。

简单举个例子来说:我在写项目,引入了一个外部的JS文件,但是这个文件的作者使用的变量名称和我的项目中变量名称有冲突,那么这时候的报错怎么查?查出来怎么改?这就是问题。

通过了CommonsJS、AMD、CMD、ES6等标准后,大家希望的模块系统给可以兼容多种模块风格,尽量利用已有的代码,不仅仅是Javascript模块化,还有字体、CSS、图片等资源也要模块化。

安装webpack

webpack作为一款模块加载兼打包工具,可以将各种资源:JS、JSX、ES6、SASS、LESS、图片等都作为模块来处理和使用,使用如下命令安装:

npm install webpack -g
npm insatall webpack-cli -g

测试通过webpack -v和webpack-cli -v来查看是否安装成功:

 

使用

我们创建一个新的文件夹,名为Webpack-Build,用IDEA打开,接下来我们创建一个module文件夹,用来放置JS文件;现在我们写一个hello.js:

//暴露一个方法
exports.sayHi = function () {
    document.write("<div><h1>zijun</h1></div>")
};

这个文件中使用exports来暴露方法sayHi,再写一个main.js:

var hello = require("./hello");

hello.sayHi();

既然有了暴露的方法,那就要有一个地方来引入,在main.js中使用var引入hello.js文件,这样我们就可以使用它的暴露的方法sayHi(),不管hello.js中有多少个方法,只要使用exports暴露就可以在main.js中使用。

接下来就是重点部分:打包。我们在项目目录下建立一个js文件webpack.config.js:

module.exports = {
    entry: './modules/main.js',
    output: {
        filename: "./js/bundle.js"
    }
};

这是一个规范的webpack打包代码,exports代表需要导出;entry是入口,代表程序打包好之后的入口;output代表打包之后的输出,filename为输出位置;总的来说就是从main.js开始将代码打包,打包输出到bundle.js,在控制台输入:webpack,等待程序运行完毕就会在项目目录下发现dist文件夹,打开就会看到js文件夹,里面就是我们的bundle.js文件:

!function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=0)}([function(e,t,n){n(1).sayHi()},function(e,t){t.sayHi=function(){document.write("<div><h1>zijun</h1></div>")}}]);

这时如果需要使用hello.js或者main.js就不需要引入这两个文件,直接引入bundle.js即可,建一个Index.html来检测一下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script src="dist/js/bundle.js"></script>
</body>
</html>

可以正常打开: 

并且在控制台如果没有关闭进程,那么在修改代码的时候bundle.js也会睡着我们的修改内容为之改变,也就是热部署。

2.Vue-CLI

Vue CLI 是一个基于 Vue.js 进行快速开发的完整系统,提供:

  • 通过 @vue/cli 实现的交互式的项目脚手架。
  • 通过 @vue/cli + @vue/cli-service-global 实现的零配置原型开发。
  • 一个运行时依赖 (@vue/cli-service),该依赖:
    • 可升级;

    • 基于 webpack 构建,并带有合理的默认配置;

    • 可以通过项目内的配置文件进行配置;

    • 可以通过插件进行扩展。

  • 一个丰富的官方插件集合,集成了前端生态中最好的工具。
  • 一套完全图形化的创建和管理 Vue.js 项目的用户界面。

Vue CLI 致力于将 Vue 生态中的工具基础标准化。它确保了各种构建工具能够基于智能的默认配置即可平稳衔接,这样你可以专注在撰写应用上,而不必花好几天去纠结配置的问题。与此同时,它也为每个工具提供了调整配置的灵活性,无需 eject。

安装

首先我们要安装Node.js,需要8.9或者更高版本,官方推荐的是8.11.0+,安装好后使用node -v和 npm -v来查看版本:

接下来我们需要安装Node的淘宝加速镜像:

npm install cnpm -g

一般我们会选择cnpm来安装其他的东西,因为国内的还是比国外的要快,如果cnpm安装失败则尝试npm,直到安装成功。

接下来我们通过cnpm安装vue-cli:

cnpm install vue-cli -g

安装好后可以使用vue list来查看可以使用哪些模板来创建Vue应用:

第一个Vue-cli程序

安装好后就可以开始建立应用了,找到应用的位置,进入路径,使用vue init webpack myvue来建立一个叫做myvue的vue-cli应用,确定好名称(名称不能有大写)和作者后,其余的选项全部选择no就可以建立一个空白的基于webpack的vue-cli应用程序,安装好后的文件夹就变成了这样:

可以看到我的多了一个node-config文件夹,接下来需要初始化就可以得到这个文件夹,继续在命令行输入:

cd myvue
npm install
npm run dev

分别是,进入刚才建立的myvue文件夹、安装初始化、运行,全部成功后我们会看到一个界面:

这时就可以在浏览器中输入localhost:8080,如果看到下面的界面,说明成功的创建了第一个vue-cli程序:

这时我们通过IDEA打开myxue文件夹,就可以看到我们的第一个vue-cli程序的内容了:

 components文件夹是放置组件的,APP.vue用来展示模板,main.js用来绑定APP.vue,这些是基本配置。

路由

我们有了vue-cli后就可以来学习一下路由,基于刚才的应用,我们删除logo.png、HelloWorld.vue,并且将APP.vue和main.js中有关HelloWorld.vue的代码删除,现在你就得到了一个空白的Vue应用程序。

在后端我们要进行页面跳转时,只需要进行转发或者重定向就可以了,而在前端集成时,就要通过路由来进行处理:Vue Router是Vue的官方路由管理器,和Vue.js核心深度集成,让构建页面变得易如反掌。

vue-router是一个插件包,所以要使用npm/cnpm来安装的,如果你的node_modules中没有vue-router文件夹,那么就使用下面的命令来安装:

npm install vue-router --save-dev

安装好后就可以来测试了,我们首先建立两个页面,分别是首页main.vue:

<template>
    <h1>首页</h1>
</template>

<script>
    export default {
        name: "main"
    }
</script>

<style scoped>

</style>

内容页content.vue:

<template>
    <h1>内容页</h1>
</template>

<script>
    export default {
        name: "content"
    }
</script>

<style scoped>

</style>

这时候为了能够实现页面跳转,我们要建立一个路由管理文件夹router,建立一个index.js文件:

//主配置
import Vue from 'vue'
import VueRouter from 'vue-router'

import Content from '../components/content'
import Main from '../components/main'

//安装路由
Vue.use(VueRouter);

//导出
export default new VueRouter({
  routes: [
    {
      //路由的路径
      path: '/content',
      //还可以起名字
      name: 'content',
      //跳转的组件
      component: Content
    },
    {
      path: '/main',
      name: 'main',
      component: Main
    }
  ]
});

解释一下,首先我们配置Vue,然后配置路由vue-router,将两个页面import导入,安装路由Vue.use,最后导出路由export,在导出时可以设置路由的路径、路由的名字、跳转的位置;

然后我们在main.js中进行路由的配置:

// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router/index' //自动扫描里面的路由配置

Vue.config.productionTip = false;

/* eslint-disable no-new */
new Vue({
  el: '#app',
  //配置路由
  router,
  components: { App },
  template: '<App/>'
})

配置很简单,import导入我们的路由管理文件,然后再Vue对象中加入就可以了; 

最后是对入口页面的配置:

<template>
  <div id="app">
    <h1>Vue-Router</h1>
    <router-link to="/main">首页</router-link>
    <router-link to="/content">内容页</router-link>
    <router-view></router-view>
  </div>
</template>

<script>

export default {
  name: 'App'
}
</script>

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

<router-link> 是一个组件,该组件用于设置一个导航链接,切换不同 HTML 内容,to 属性为目标地址, 即要显示的内容;使用<router-view>来展示跳转后的内容。

可以看一下最终的效果:

3.Axios

Vue.js 2.0 版本推荐使用 axios 来完成 ajax 请求。

Axios 是一个基于 Promise 的 HTTP 库,可以用在浏览器和 node.js 中。

安装

使用CDN:

<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

<script src="https://cdn.staticfile.org/axios/0.18.0/axios.min.js"></script>

或者使用npm:

$ npm install axios

生命周期

从Vue实例创建、运行、到销毁期间,总是伴随着各种各样的事件,这些事件统称生命周期,而生命周期钩子就是生命周期方法事件的别名。

 从官网的图上可以看到,在不同的进度中有不同的钩子函数,主要的生命周期函数分类为:

  • 创建期间的生命周期函数:
    • beforeCreate:实例刚在内存中被创建出来,此时还没有初始化好data和methods属性;
    • created:实例在内存中完成创建OK,此时data和mthods已经创建OK,还没有开始编译模板;
    • beforeMount:此时已经完成了模板的编译,但还没有挂载到页面中;
    • mounted:此时已经将编译好的模板挂载到了页面指定的容器中显示;
  • 运行期间的生命周期函数:
    • beforeUpdate:状态更新之前执行函数,此时data中的状态值是最新的,但界面上显示的数据还是旧的,因为还没有重新渲染DOM节点;
    • updated:实例更新完后调用此函数,此时data中的状态值和界面上显示的数据都已经完成了更新,界面已经被重新渲染好了;
  • 销毁期间的生命周期函数:
    • beforeDestroy:实例销毁之前调用,在这一步实例仍完全可用;
    • destroyed:Vue实例销毁后调用,调用后Vue实例所指示的所有东西都会解绑定,所有事件监听器会被移除,所有子实例也会被销毁。

使用

因为使用Axios是为了实现异步通信,所以就要有后端传过来的数据,我来模仿后端传来的数据建立一个data.json文件:

{
  "name": "zijun",
  "age": "18",
  "url": "https://blog.csdn.net/qq_39732867",
  "page": 1,
  "isNotProfit": "true",
  "address": {
    "street": "安远门",
    "city": "西安",
    "country": "中国"
  },
  "links": [
    {
      "name": "001",
      "url": "001"
    },
    {
      "name": "002",
      "url": "002"
    },
    {
      "name": "003",
      "url": "003"
    }
  ]
}

这段代码就是模仿后端传过来的json数据,包含了布尔值、数字、字符串、数组、对象等类型,现在我们写一个html代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<div id="vue">
    {{info.name}}
</div>

<script src="../vue/vue.min.js"></script>
<script src="http://unpkg.com/axios/dist/axios.min.js"></script>
<script>
    var vm = new Vue({
        el: '#vue',
        data:{},//这是属性的data

        data(){
            return{
                //请求的返回参数格式必须和JSON字符串一样
                info:{
                    name: null
                }
            }
        },
        mounted(){ //钩子函数,链式编程
            axios.get('data.json').then(response=>(this.info = response.data));
        }
    });

</script>

</body>
</html>

我们以mounted函数来举例,在mounted函数中应该写异步请求,Java中是$Ajax,Vue2.0+就是axios,因为是链式编程所以首先使用get方法获取数据获取的是‘data.json’,then表示‘然后’的意思,response就是得到的数据这里可以替换为其他的变量,然后‘=>’得到‘this.info = response.data’;

这时的data()和Vue对象中的data不一样,这里的data()是钩子函数执行后的数据装载,在mounted函数未执行时,info.name的值仍为null,mounted函数执行后,获取了data.json的数据response.data,data()更新并渲染,这时效果如下:

分别给出get方法和post方法:

//get
<body>
<div id="app">
  {{ info }}
</div>
<script type = "text/javascript">
new Vue({
  el: '#app',
  data () {
    return {
      info: null
    }
  },
  mounted () {
    axios
      .get('json_demo.json')
      .then(response => (this.info = response.data))
      .catch(function (error) { // 请求失败处理
        console.log(error);
      });
  }
})
</script>
</body>
//post
<body>
<div id="app">
  {{ info.data.name }}
</div>
<script type = "text/javascript">
new Vue({
  el: '#app',
  data () {
    return {
      info: null
    }
  },
  mounted () {
    axios
      .post('demo_axios_post.php')
      .then(response => (this.info = response))
      .catch(function (error) { // 请求失败处理
        console.log(error);
      });
  }
})
</script>
</body>

4.ElementUI

最后说起前端页面怎么画,大家第一时间想到的应该是BootStrap,但是ElementUI更加与Vue兼容:

可以通过npm安装:

npm i element-ui -S

或者使用CDN:

<!-- 引入样式 -->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<!-- 引入组件库 -->
<script src="https://unpkg.com/element-ui/lib/index.js"></script>

这时我们随便找一些组件:

可以看到已经完全使用Vue的方式才能看的懂了,这就是技术更新啊朋友们,因为组件是模板,所以是可复用的,需要时只需要通过slot插入就可以用,就很棒,现在我们来做一个实例:

首先创建一个新的Vue-cli应用,进行一些文件的创建:

这时先写Login.vue:

<template>
  <div>
    <el-form ref="loginForm" :model="form" :rules="rules" label-width="80px " class="login-box">
      <h3 class="login-title">欢迎登录</h3>
      <el-form-item label="账号" prop="username">
        <el-input type="text" placeholder="请输入账号" v-model="form.username"/>
      </el-form-item>
      <el-form-item label="密码" prop="password">
        <el-input type="password" placeholder="请输入密码" v-model="form.password"/>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" v-on:click="onSubmit('loginForm')">登录</el-button>
      </el-form-item>
    </el-form>

    <el-dialog
      title="温馨提示"
      :visible.sync="dialogVisible"
      width="30%"
      :before-close="handleClose">
      <span>请输入账号和密码</span>
      <span slot="footer" class="dialog-footer">
          <el-button type="primary" @click="dialogVisible = false">确定</el-button>
        </span>
    </el-dialog>
  </div>
</template>

<script>
  export default {
    name: "Login",
    data() {
      return {
        form: {
          username: '',
          password: ''
        },

        //表单验证,需要在el-form-item元素中增加prop属性
        rules: {
          username: [
            {required: true, message: '账号不可为空', trigger: 'blur'}
          ],
          password: [
            {required: true, message: '密码不可为空', trigger: 'blur'}
          ]
        },

        //对话框显示和隐藏
        dialogVisible: false
      }
    },

    methods: {
      onSubmit(formName) {
        //为表单绑定验证功能
        this.$refs[formName].validate((vaild) => {
          if (vaild) {
            //使用vue-router 路由指导到指定页面,该方式称为编程式导航
            this.$router.push("/main");
          } else {
            this.dialogVisible = true;
            return false;
          }
        });
      }
    }
  }
</script>

<style lang="scss" scoped>
  .login-box {
    border: 1px solid #DCDFE6;
    width: 350px;
    margin: 180px auto;
    padding: 35px 35px 15px 35px;
  }

</style>

然后是Main.vue:

<template>
    <h1>首页</h1>
</template>

<script>
    export default {
        name: "Main"
    }
</script>

<style scoped>

</style>

写好后顺便配个路由:

import Vue from 'vue'
import VueRouter from 'vue-router'

import Main from '../views/Main'
import Login from '../views/Login'

Vue.use(VueRouter);

export default new VueRouter({
  routes: [
    {
      path: '/main',
      name: 'main',
      component: Main
    },
    {
      path: '/login',
      name: 'login',
      component: Login
    }
  ]
});

然后是main.js:

// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'

import router from './router/index'

import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'

Vue.use(router);
Vue.use(ElementUI);

Vue.config.productionTip = false

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

 最后配一下APP.vue:

<template>
  <div id="app">
    <router-link to="/login">login</router-link>
    <router-view></router-view>
  </div>
</template>

<script>

export default {
  name: 'App'
}
</script>

看一下效果:

这里一直出现login是因为我们在APP.vue的模板中就写下了router-link,而其他的内容都是在router-view中显示的,所以只需要将router-link放在Main.vue中就可以了。


这篇文章简单整理了一下前后端分离会遇到的知识点,包括webpack、vue-cli的使用,axios进行异步加载数据,ElementUI进行前端页面的开发,这些都是前后端分离过程中会用到的,当然作为后端工程师只需要了解会用就可以了【笑~】,接下来就可以尝试使用前后端分离来写项目了,我们下次见👋

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值