Day02_CMS前端开发
CMS前端开发
1 Vue.js与Webpack研究
参考链接:https://www.cnblogs.com/artwalker/p/13387386.html
2 CMS前端工程创建
2.1 导入系统管理前端工程
CMS系统使用Vue-cli脚手架创建, Vue-cli是Vue官方提供的快速构建单页应用的脚手架,github地址: https://github.com/vuejs/vue-cli(有兴趣的同学可以参考官方指导使用vue-cli创建前端工程),本项目对Vue-cli 创建的工程进行二次封装,下边介绍CMS工程的情况。
2.2.1 工程结构
如果我要基于Vue-Cli创建的工程进行开发还需要在它基础上做一些封装,导入课程资料中提供Vue-Cli封装工程。 将课程资料中的xc-ui-pc-sysmanage.7z拷贝到UI工程目录中(和xc-ui-pc-static-portal目录并列),并解压,用WebStorm打开xc-ui-pc-sysmanage目录。

2.2.2 package.json
package.json记录了工程所有依赖,及脚本命令:

开发使用:npm run dev
打包使用:npm run build
2.2.3 webpack.base.conf.js
webpack.base.conf.js就是webpack的webpack.config.js配置文件,在此文件中配置了入口文件及各种Loader。
webpack是通过vue-load解析.vue文件,通过css-load打包css文件等。
2.2.4 main.js
main.js是工程的入口文件,在此文件中加载了很多第三方组件,如:Element-UI、Base64、VueRouter等。
index.html是模板文件。
2.2.5 src目录
src目录下存放页面及js代码。

assets:存放一些静态文件,如图片。
base:存放基础组件
base/api:基础api接口
base/component:基础组件,被各模块都使用的组件
base/router:总的路由配置,加载各模块的路由配置文件
common:工具类
component:组件目录,本项目不用
mock:存放前端单元测试方法
module:存放各业务模块的页面和api方法
下级目录以模块名命名,下边以cms举例:
cms/api:cms模块的api接口
cms/component:cms模块的组件
cms/page: cms模块的页面
cms/router:cms模块的路由配置
statics:存放第三方组件的静态资源
vuex:存放vuex文件,本项目不使用
static:与src的平级目录,此目录存放静态资源
它与assets的区别在于,static目录中的文件不被webpack打包处理,会原样拷贝到dist目录下
2.2 单页面应用介绍
什么是单页应用?
单页应用(英语:single-page application,缩写SPA)是一种网络应用程序或网站的模型,它通过动态重写当前页面来与用户交互,而非传统的从服务器重新加载整个新页面。这种方法避免了页面之间切换打断用户体验,使应用程序更像一个桌面应用程序。在单页应用中,所有必要的代码(HTML、JavaScript和CSS)都通过单个页面的加载而检索,或者根据需要(通常是为响应用户操作)动态装载适当的资源并添加到页面。尽管可以用位置散列或HTML5历史API来提供应用程序中单独逻辑页面的感知和导航能力,但页面在过程中的任何时间点都不会重新加载,也不会将控制转移到其他页面。与单页应用的交互通常涉及到与网页服务器后端的动态通信。
单页面应用的优缺点:
优点:
1、用户操作体验好,用户不用刷新页面,整个交互过程都是通过Ajax来操作。
2、适合前后端分离开发,服务端提供http接口,前端请求http接口获取数据,使用JS进行客户端渲染。
缺点:
1、首页加载慢
单页面应用会将js、 css打包成一个文件,在加载页面显示的时候加载打包文件,如果打包文件较大或者网速慢则 用户体验不好。
2、SEO不友好
SEO(Search Engine Optimization)的意思是搜索引擎优化。它是一种利用搜索引擎的搜索规则来提高网站在搜索引擎排名的方法。目前各家搜索引擎对JS支持不好,所以使用单页面应用将大大减少搜索引擎对网站的收录。
总结:
本项目的门户、课程介绍不采用单页面应用架构去开发,对于需要用户登录的管理系统采用单页面开发。
3 CMS前端页面查询开发
3.1 页面原型
3.1.1 创建页面
3.1.1.1 页面结构
在model目录创建 cms模块的目录结构

在page目录新建page_list.vue
.vue文件的结构如下:
<template>
<!‐‐编写页面静态部分,即view部分‐‐>
测试页面显示...
</template>
<script>
  /*编写model及vm部分。*/
</script>
<style>
  /*编写页面样式,不是必须*/
</style>
在页面的template中填写 “测试页面显示...”。
注意:template内容必须有一个根元素,否则vue会报错,这里我们在template标签内定义一个div。
3.1.1.2 页面路由
在cms/router目录下创建index.js页面。
现在先配置路由,实现url访问到页面,再进行内容完善与调试。
1、在cms的router下配置路由
import Home from '@/module/home/page/home.vue';
import page_list from '@/module/cms/page/page_list.vue';
export default [{
    path: '/',
    component: Home,
    name: 'CMS',//菜单名称
    hidden: false,
    children:[
      {path:'/cms/page/list',name:'页面列表',component: page_list,hidden:false}
    ]
  }
]
2、在base目录下的router下添加导入cms模块的路由
// 导入路由规则
import CmsRouter from '@/module/cms/router'
// 合并路由规则
concat(CmsRouter)
3、测试
启动xc-ui-pc-sysmanage工程,刷新页面,页面可以外正常浏览,并且看到“测试页面显示...”字样
3.1.2 Table组件测试
3.1.2.1 Element-UI介绍
本项目使用Element-UI来构建界面,Element是一套为开发者、设计师和产品经理准备的基于 Vue 2.0 的桌面端组件库。
Element-UI官方站点:http://element.eleme.io/#/zh-CN/component/installation
3.1.2.2 Table组件测试
本功能实现的页面列表,用户可以进行分页查询、输入查询条件查询,通过查看Element-UI库,我们需要Table 表 格、Form表单 及Pagination 分页组件。
进入Element-UI官方,找到Table组件,拷贝源代码到vue页面中,如下:
  <template>
    <el-table
      :data="tableData"
      style="width: 100%">
      <el-table-column
        prop="date"
        label="日期"
        width="180">
      </el-table-column>
      <el-table-column
        prop="name"
        label="姓名"
        width="180">
      </el-table-column>
      <el-table-column
        prop="address"
        label="地址">
      </el-table-column>
    </el-table>
  </template>
  <script>
    export default {
      data() {
        return {
          tableData: [{
            date: '2016-05-02',
            name: '王小虎',
            address: '上海市普陀区金沙江路 1518 弄'
          }, {
            date: '2016-05-04',
            name: '王小虎',
            address: '上海市普陀区金沙江路 1517 弄'
          }, {
            date: '2016-05-01',
            name: '王小虎',
            address: '上海市普陀区金沙江路 1519 弄'
          }, {
            date: '2016-05-03',
            name: '王小虎',
            address: '上海市普陀区金沙江路 1516 弄'
          }]
        }
      }
    }
  </script>
测试:

通过查看代码发现:
el-table组件绑定了tableData模型数据。
tableData模型数据在script标签中定义。
3.1.3页面内容完善
根据需求完善页面内容,完善列表字段,添加分页组件与按钮组件。
<template>
  <div>
    <!--    按钮-->
    <el-row>
      <el-button type="primary" v-on:click="query" size="small">查询</el-button>
    </el-row>
    <!--    Table表格-->
    <el-table
      :data="list"
      stripe
      style="width: 100%">
      <el-table-column type="index" width="60"></el-table-column>
      <el-table-column
        prop="pageName"
        label="页面名称"
        width="120">
      </el-table-column>
      <el-table-column
        prop="pageAliase"
        label="别名"
        width="180">
      </el-table-column>
      <el-table-column
        prop="pageType"
        label="页面类型"
        width="150">
      </el-table-column>
      <el-table-column
        prop="pageWebPath"
        label="访问路径"
        width="250">
      </el-table-column>
      <el-table-column
        prop="pagePhysicalPath"
        label="物理路径"
        width="250">
      </el-table-column>
      <el-table-column
        prop="pageCreateTime"
        label="创建时间"
        width="180">
      </el-table-column>
    </el-table>
    <!--    分页-->
    <el-pagination
      v-on:current-change="changePage"
      layout="prev, pager, next"
      :total="total"
      :current-page="this.params.page"
      :page-size="this.params.size"
      style="float:right">
    </el-pagination>
  </div>
</template>
<script>
  export default {
    data() {
      return {
        list: [],
        total: 50,
        params: {
          page: 1, // 页码
          size: 2 //每页显示个数
        }
      }
    },
    methods:{
      //分页查询
      changePage:function () {
        this.query();
      },
      //查询
      query:function () {
        alert("查询")
      }
    }
  }
</script>
<style>
  /*编写页面样式,不是必须*/
</style>
2、测试

3.2 Api调用
3.2.1 Api方法定义
在cms模块的api目录定义cms.js,
在cms.js中定义如下js方法,此方法实现http请求服务端页面查询接口。
//public是对axios的工具类封装,定义了http请求方法
import http from './../../../base/api/public'
export const page_list = (page, size, params) => {
  return http.requestQuickGet('http://localhost:31001/cms/page/list/'+page+'/'+size)
}
axios实现了http方法的封装,vue.js官方不再继续维护vue-resource,推荐使用 axios。
3.2.2 Api调用
前端页面(page_list.vue)导入cms.js,调用js方法请求服务端页面查询接口。
import * as cmsApi from '../api/cms'
在query方法中调用 page_list方法
 //查询
      query:function () {
        cmsApi.page_list(this.params.page, this.params.size,this.params).then((res)=>{
          console.log(res)
          this.total = res.queryResult.total
          this.list = res.queryResult.list
        })
      }
3.3 跨域问题解决
测试上边的代理 ,结果报错如下 :
No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:11000' is therefore not allowed access.
原因:浏览器的同源策略不允许跨域访问,所谓同源策略是指协议、域名、端口相同。
解决:采用proxyTable解决。
proxyTable是什么?
vue-cli提供的解决vue开发环境下跨域问题的方法,proxyTable的底层使用了http-proxymiddleware(https://github.com/chimurai/http-proxy-middleware),它是http代理中间件,它依赖node.js, 基本原理是用服务端代理解决浏览器跨域:

cms跨域解决原理:
1、访问页面http://localhost:11000/
2、页面请求http://localhost:11000/cms
由于 url由http://localhost:31001/cms...改为“http://localhost:11000/cms.",所以不存在跨域
3、通过proxyTable由node服务器代理请求 http://localhost:31001/cms
服务端不存在跨域问题
具体的配置如下:
1)修改api方法中url的定义
请求前加/api前缀
//public是对axios的工具类封装,定义了http请求方法
import http from './../../../base/api/public'
let sysConfig = require('@/../config/sysConfig')
let apiUrl = sysConfig.xcApiUrlPre;
export const page_list = (page, size, params) => {
  return http.requestQuickGet(apiUrl+'/cms/page/list/'+page+'/'+size)
}
2)在config/index.js下配置proxyTable
以/api/cms开头的请求,代理请求http://localhost:31001
'/api/cms': {
        target: 'http://localhost:31001',
        pathRewrite: {
          '^/api': ''
        }
3.4 分页查询测试
1、定义分页视图
使用v-on监听更改分页事件
v‐on:current‐change="changePage"
// 作用是点击下一页后,自动更新当前页面数据
<!--    分页-->
    <el-pagination
      v-on:current-change="changePage"
      layout="prev, pager, next"
      :total="total"
      :current-page="this.params.page"
      :page-size="this.params.size"
      style="float:right">
    </el-pagination>
2、定义数据模型对象
data() {
      return {
        list: [],
        total: 50,
        params: {
          page: 1, // 页码
          size: 2 //每页显示个数
        }
      }
    },
3、定义分页方法,接收页码参数
//分页查询,接收page页码
      changePage(page) {
        this.params.page = page;
        this.query();
      },
修改完毕,测试分页效果。
3.5 进入页面立即查询
目前实现的功能是进入页面点击查询按钮向服务端表求查询,实际的需求是进入页面立即查询。
如何实现?
这要用到vue的钩子函数,每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、 编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会。
通常使用最多的是created和mounted两个钩子:
created:vue实例已创建但是DOM元素还没有渲染生成。
mounted:DOM元素渲染生成完成后调用。
本例子在两个方法的任意一个都满足需求:
添加如下代码:
mounted() {
	// 默认查询页面
	this.query()
}
重新刷新页面。
4 前后端请求响应流程小结

1、在浏览器输入前端url
2、前端框架vue.js根据url解析路由,根据路由找到page_list.vue页面
3、首先执行page_list.vue中的钩子方法
4、在钩子方法中调用query方法
5、在query方法中调用cms.js中的page_list方法
6、cms.js中的page_list方法通过axios请求服务端接口
7、采用proxyTable解决跨域问题,node.js将请求转发到服务端(http://localhost:31001/cms/page/list)
8、服务端处理,将查询结果响应给前端
9、成功响应调用then方法,在then方法中处理响应结果,将查询结果赋值给数据模型中的total和list变量
10、vue.js通过双向数据绑定将list数据渲染输出
Day02_CMS前端开发的更多相关文章
- 总结:Mac前端开发环境的搭建(配置)
		新年新气象,在2016年的第一天,我入手了人生中第一台自己的电脑(大一时好友赠送的电脑在一次无意中烧坏了主板,此后便不断借用别人的或者网站的).macbook air,身上已无分文...接下来半年的房 ... 
- 前端开发:面向对象与javascript中的面向对象实现(二)构造函数与原型
		前端开发:面向对象与javascript中的面向对象实现(二)构造函数与原型 前言(题外话): 有人说拖延症是一个绝症,哎呀治不好了.先不说这是一个每个人都多多少少会有的,也不管它究竟对生活有多么大的 ... 
- openresty 前端开发入门五之Mysql篇
		openresty 前端开发入门五之Mysql篇 这章主要演示怎么通过lua连接mysql,并根据用户输入的name从mysql获取数据,并返回给用户 操作mysql主要用到了lua-resty-my ... 
- JS高级前端开发群加群说明及如何晋级
		JS高级前端开发群加群说明 一.文章背景: 二. 高级群: 三. 加入方式: 四. 说明: 一.文章背景: 去年年初建了几个群,在不经意间火了,一直排在“前端开发”关键字搜索结果第一名.当然取得这 ... 
- web前端开发分享-目录
		1. web前端开发分享-css,js入门篇 2. web前端开发分享-css,js进阶篇 3. web前端开发分享-css,js提高篇 4. web前端开发分享-css,js工具篇 5. web前端 ... 
- 前端开发:setTimeout与setInterval 定时器与异步循环数组
		前端开发:setTimeout与setInterval 定时器与异步循环数组 前言: 开通博客园三个月以来,随笔记录了工作中遇到的大大小小的难题,也看过无数篇令人启发的文章,我觉得这样的环境是极好的, ... 
- 前端开发:面向对象与javascript中的面向对象实现(一)
		前端开发:面向对象与javascript中的面向对象实现(一) 前言: 人生在世,这找不到对象是万万不行的.咱们生活中,找不到对象要挨骂,代码里也一样.朋友问我说:“嘿,在干嘛呢......”,我:“ ... 
- 前端开发:css基础知识之盒模型以及浮动布局。
		前端开发:css基础知识之盒模型以及浮动布局 前言 楼主的蛮多朋友最近都在学习html5,他们都会问到同一个问题 浮动是什么东西? 为什么这个浮动没有效果? 这个问题楼主已经回答了n遍.今天则是把 ... 
- 前端开发:Javascript中的数组,常用方法解析
		前端开发:Javascript中的数组,常用方法解析 前言 Array是Javascript构成的一个重要的部分,它可以用来存储字符串.对象.函数.Number,它是非常强大的.因此深入了解Array ... 
随机推荐
- JavaScript基础函数体中的唯一var模式(002)
			全局变量是不好的.所以在声名变量的时候,应该采用函数体中的唯一var模式(Single var Pattern).这个模式有不少好处: 提供了一个唯一的地方来查看函数体中声名的变量 在使用一个变量之前 ... 
- Spring Security(二) —— Guides
			摘要: 原创出处 https://www.cnkirito.moe/spring-security-2/ 「老徐」欢迎转载,保留摘要,谢谢! 2 Spring Security Guides 上一篇文 ... 
- sublime 搜索时忽略文件夹
			如上图:添加 "folder_exclude_patterns": ["要忽略的文件夹"] 
- Git超详细用法,通俗易懂
			创建本地仓库 和 远端共享仓库 直接下载安装包:Git下载地址 安装 git,查看 git 版本,git version 配置项目的 git 账号 git config --global user.n ... 
- Javascript安全编程规范
			命名 1.原则——编码格式UTF-8,根据功能为变量与方法命名(尽量不缩写) 2.类——构造函数/类 使用驼峰命名法,且首字母大写 3.方法——动词.动宾结构,使用驼峰命名法,首字母小写 例如:get ... 
- 通过注入DLL修改API代码实现钩取(一)
			通过注入DLL修改API代码实现钩取(一) Ox00 大致思路 通过CreateRemoteThread函数开辟新线程,并将DLL注入进去 通过GetProcessAddress函数找到需钩取的API ... 
- Python基础-类与对象
			类的基本使用 class Person(): def __init__(self,name,age): self.name = name self.age = age def info(self): ... 
- C++中类继承public,protected和private关键字作用详解及派生类的访问权限
			注意:本文有时候会用Visual Studio Code里插件的自动补全功能来展示访问权限的范围(当且仅当自动补全范围等价于对象访问权限范围的时候),但是不代表只要是出现在自动补全范围内的可调用对象/ ... 
- js自定义方法绑定元素事件
			//事件绑定封装 function addEvent(elem, type, handle){ if(elem.addEventListener){ elem.addEventListener(typ ... 
- Halcon一维测量官方案例解析
			下面的例子简要介绍了如何使用HALCON的一维测量工具.最长的部分是预处理和后处理:测量本身只包括两个操作符调用. 测量保险丝-fuse 预处理主要是测量线的生成.在示例程序中,这个步骤是通过将测量对 ... 
