1. vue.js研究
1.1 vue.js介绍
- vue.js是什么?
Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。
渐进式框架:Progressive,说明vue.js的轻量,是指一个前端项目可以使用vue.js一两个特性也可以整个项目都用
vue.js。
自底向上逐层应用:作为渐进式框架要实现的目标就是方便项目增量开发。参考:https://cn.vuejs.org/v2/guide/
1.2 Vue.js的使用
在html页面使用script引入vue.js的库即可使用。
使用Npm管理依赖,使用webpack打包工具对vue.js应用打包。大型应用推荐此方案。
-
Vue-CLI脚手架
使用vue.js官方提供的CLI脚本架很方便去创建vue.js工程雏形。
1.3 vue.js有哪些功能?
-
声明式渲染
Vue.js 的核心是一个允许采用简洁的模板语法来声明式地将数据渲染进 DOM 的系统。比如:使用vue.js的插值表达式放在Dom的任意地方, 差值表达式的值将被渲染在Dom中。
-
条件与循环
dom中可以使用vue.js提供的v-if、v-for等标签,方便对数据进行判断、循环。
-
双向数据绑定
Vue 提供v-model 指令,它可以轻松实现Dom元素和数据对象之间双向绑定,即修改Dom元素中的值自动修改绑定的数据对象,修改数据对象的值自动修改Dom元素中的值。
-
处理用户输入
为了让用户和你的应用进行交互,我们可以用
v-on
指令添加一个时间监听器,通过它调用在 Vue 实例中定义的方法 -
组件化应用构建
vue.js可以定义一个一个的组件,在vue页面中引用组件,这个功能非常适合构建大型应用。
2. Vue.js基础
2.1 MVVM模式
vue.js是一个MVVM的框架,理解MVVM有利于学习vue.js。
- MVVM拆分解释为:
- Model:负责数据存储
- View:负责页面展示
- View Model:负责业务逻辑处理(比如Ajax请求等),对数据进行加工后交给视图展示
- MVVM要解决的问题是将业务逻辑代码与视图代码进行完全分离,使各自的职责更加清晰,后期代码维护更加简单
- 用图解的形式分析Ajax请求回来数据后直接操作Dom来达到视图的更新的缺点,以及使用MVVM模式是如何来解决这个缺点的
- Vue中的 MVVM
从上图看出,VM(ViewModel)可以把view视图和Model模型解耦合,VM的要做的工作就是vue.js所承担的。
2.2 入门程序
本次测试我们在门户目录中创建一个html页面进行测试,正式的页面管理前端程序会单独创建工程。在门户目录中创建vuetest目录,并且在目录下创建vue_01.html文件
vue.js入门程序
{{name}}
代码编写步骤:
- 定义html,引入vue.js
- 定义app div,此区域作为vue的接管区域
- 定义vue实例,接管app区域。
- 定义model(数据对象)
- VM完成在app中展示数据
2.3 1+1=2
实现效果:
代码如下:
vue.js入门程序
-
v-model
:在表单控件或者组件上创建双向绑定
v-model
仅能在如下元素中使用:input select textarea components(Vue中的组件)
-
解决插值表达式闪烁问题,使用
v-text
v-text
可以将一个变量的值渲染到指定的元素中,它可以解决插值表达式闪烁的问题 v-on
绑定一个按钮的单击事件-
v-bind
1、作用: v‐bind可以将数据对象绑定在dom的任意属性中。 v‐bind可以给dom对象绑定一个或多个特性,例如动态绑定style和class 2、举例:
3、缩写形式
2.4 v-if和v-for
Document
- {{index}}‐{{item}}
- {{key}}‐{{value}}
-
{{index}}‐{{item.user.uname}}‐{{item.user.age}}
{{index}}‐{{item.user.uname}}‐{{item.user.age}}
3. webpack入门
使用vue.js开发大型应用需要使用webpack打包工具,本节研究webpack的使用方法。
3.1 webpack介绍
Webpack 是一个前端资源的打包工具,它可以将js、image、css等资源当成一个模块进行打包。
从图中我们可以看出,Webpack 可以将js、css、png等多种静态资源 进行打包,使用webpack有什么好处呢?
-
模块化开发
程序员在开发时可以分模块创建不同的js、 css等小文件方便开发,最后使用webpack将这些小文件打包成一个文件,减少了http的请求次数。
webpack可以实现按需打包,为了避免出现打包文件过大可以打包成多个文件。
-
编译typescript、ES6等高级js语法
随着前端技术的强大,开发中可以使用javascript的很多高级版本,比如:typescript、ES6等,方便开发,
webpack可以将打包文件转换成浏览器可识别的js语法。
-
CSS预编译
webpack允许在开发中使用Sass 和 Less等原生CSS的扩展技术,通过sass-loader、less-loader将Sass 和 Less的语法编译成浏览器可识别的css语法。
webpack的缺点:
- 配置有些繁琐
- 文档不丰富
3.2 安装webpack
-
安装Node.js
webpack基于node.js运行,首先需要安装node.js。
下载对应你系统的Node.js版本: https://nodejs.org/en/download/
测试:
node -v
-
安装NPM
- 自动安装NPM
npm全称Node Package Manager,他是node包管理和分发的工具,使用NPM可以对应用的依赖进行管理,NPM
的功能和服务端项目构建工具maven差不多,我们通过npm 可以很方便地下载js库,打包js文件。
node.js已经集成了npm工具,在命令提示符输入 npm -v 可查看当前npm版本
-
设置包路径
包路径就是npm从远程下载的js包所存放的路径。
使用 npm config ls 查询NPM管理包路径(NPM下载的依赖包所存放的路径)
NPM默认的管理包路径在C:/用户/[用户名]/AppData/Roming/npm/node_meodules,为了方便对依赖包管理,我 们将管理包的路径设置在单独的地方,本教程将安装目录设置在node.js的目录下,**创建npm_modules和npm_cache**,执行下边的命令:
本教程安装node.js在D:\Software\node-v10.16.0\node下所以执行命令如下:
```
npm config set prefix "D:\Software\node-v10.16.0\node\npm_modules"
npm config set cache "D:\Software\node-v10.16.0\node\npm_cache"
```
- 安装cnpm
npm默认会去国外的镜像去下载js包,在开发中通常我们使用国内镜像,这里我们使用淘宝镜像下边我们来安装cnpm:
有时我们使用npm下载资源会很慢,所以我们可以安装一个cnmp(淘宝镜像)来加快下载速度。
输入命令,进行全局安装淘宝镜像。
```
npm install -g cnpm --registry=https://registry.npm.taobao.org
```
安装后,我们可以使用以下命令来查看cnpm的版本
```
cnpm -v
```
`nrm ls` 查看镜像已经指向taobao
使`nrm use XXX`切换 镜像
如果nrm没有安装则需要进行全局安装:`cnpm install -g nrm`
-
安装webpack
连网安装
本地安装:将webpack安装到指定应用程序的目录下。
进入这个目录,执行
npm install --save-dev webpack 或 cnpm install --save-dev webpack
全局安装:将webpack安装npm默认的依赖包的目录(前边配置在了nodejs的安装目录下)在任意目录,执行
npm install -g webpack 或 cnpm install -g webpack
建议指定webpack的版本进行安装
全局安装:
npm install [email protected] -g或 cnpm install [email protected] -g
本地安装
npm install --save-dev [email protected] 或 cnpm install --save-dev [email protected]
3.3 入门程序
-
通过入门程序实现对js文件的打包,体会webpack是如何对应用进行模块化管理。 对上边1+1=2的例子使用webpack进行模块化管理
-
定义模块:创建webpacktest01目录,将vue.min.js及vue_02.html拷贝到目录下。
-
定义model01.js
在webpacktest01目录下创建model01.js
将本程序使用的加法运算的js方法抽取到一个js文件,此文件就是一个模块
// 定义add函数 function add(x, y) { return x + y } // function add2(x, y) { // return x + y+1 // } // 导出add方法 module.exports.add = add; // module.exports ={add,add2};//如果有多个方法这样导出 // module.exports.add2 = add2//如果有多个方法也可以这样导出
-
定义main.js
在webpacktest01目录下创建main.js,main.js是本程序的js主文件,包括如下内容:
在此文件中会引用model01.js模块
引用vue.min.js(它也一个模块)
-
将html页面中构建vue实例的代码放在main.js中。
var {add} = require('./model01.js'); var Vue = require('./vue.min'); var VM = new Vue({ el:"#app",//表示当前vue对象接管app的div区域 data:{ name:'黑马程序员',// 相当于是MVVM中的Model这个角色 num1:0, num2:0, result:0, url:'http://www.itcast.cn' }, methods:{ change:function(){ //这里使用了导入的model01.js文件中的add方法 this.result = add(Number.parseInt(this.num1),Number.parseInt(this.num2)) alert(this.result) } } })
-
打包测试
上边将mode01.js模块及main.js主文件编写完成,下边使用webpack对这些js文件进行打包
进入程序目录,执行
webpack main.js build.js
,这段指令表示将main.js打包输出为 build.js文件执行完成,观察程序目录是否出现build.js。-
在html中引用build.js
vue.js入门程序
-
3.4 webpack-dev-server
webpack-dev-server开发服务器,它的功能可以实现热加载 并且自动刷新浏览器。
创建一个新的程序目录,这里我们创建webpacktest02目录,将webpack入门程序的代码拷贝进来,并在目录下创 建src目录、dist目录。
将main.js和model01.js拷贝到src目录。
3.4.1 安装配置
-
安装webpack-dev-server
cnpm install [email protected] [email protected] [email protected] --save-dev
安装完成自动创建package.json(记录了本程序所依赖的包信息)
安装完成自动创建node_modules(存放了本程序所依赖的包)
-
在package.json中配置script(运行命令)
"scripts": { "dev": "webpack‐dev‐server ‐‐inline ‐‐hot ‐‐open ‐‐port 5008" },
-
配置webpack.config.js
在webpacktest02目录下创建 webpack.config.js
webpack的配置文件,配置了入口文件、输入文件的路径、依赖的插件。
-
配置模板文件
将原来的vue_02.html作为模板文件,为了和内存中的index.html文件名区别,注意将vue_02.html中的script标签去掉,内容如下:
vue.js入门程序 -
配置html-webpack-plugin
在webpack.config.js中配置html-webpack-plugin插件
var htmlwp = require('html‐webpack‐plugin'); module.exports={ entry:'./src/main.js', //指定打包的入口文件 output:{ path : dirname+'/dist', // 注意: dirname表示webpack.config.js所在目录的绝对路径 filename:'build.js' //输出文件 }, plugins:[ new htmlwp({ title: '首页', //生成的页面标题
首页 filename: 'index.html', //webpack‐dev‐server在内存中生成的文件名称,自动将build注入到这个页面底部,才能实现自动刷新功能 template: 'vue_02.html' //根据index1.html这个模板来生成(这个文件请程序员自己生成) }) ] }
-
-
使用webpack的命令去运行程序
进入 webpacktest02目录,执行
npm run dev
-
使用debugger进行调试
-
在webpack.config.js中配置:
devtool: 'eval‐source‐map',
webpack.config.js部分内容如下:
var htmlwp = require('html‐webpack‐plugin'); module.exports={ entry:'./src/main.js', //指定打包的入口文件 output:{ path : dirname+'/dist', // 注意: dirname表示webpack.config.js所在目录的绝对路径 filename:'build.js' //输出文件 }, devtool: 'eval‐source‐map', ......
在要打断点的代码处加debugger
-
4. CMS前端工程创建
4.1 导入系统管理前端工程
CMS系统使用Vue-cli脚手架创建, Vue-cli是Vue官方提供的快速构建单页应用的脚手架,github地址: https://github.com/vuejs/vue-cli(有兴趣的同学可以参考官方指导使用vue-cli创建前端工程),本项目对Vue-cli 创建的工程进行二次封装,下边介绍CMS工程的情况。
4.1.1 工程结构
如果我要基于Vue-Cli创建的工程进行开发还需要在它基础上作一些封装,导入课程资料中提供Vue-Cli封装工程。
将课程资料中的xc-ui-pc-sysmanage.7z拷贝到UI工程目录中,并解压,用WebStorm打开xc-ui-pc-sysmanage目录。
4.1.2 package.json
package.json记录了工程所有依赖,及脚本命令:
- 开发使用:
npm run dev
- 打包使用:
npm run build
4.1.3 webpack.base.conf.js
webpack.base.conf.js就是webpack的webpack.config.js配置文件,在此文件中配置了入口文件及各种Loader。
webpack是通过vue-load解析.vue文件,通过css-load打包css文件等。
4.1.4 main.js
main.js是工程的入口文件,在此文件中加载了很多第三方组件,如:Element-UI、Base64、VueRouter等。index.html是模板文件。
4.1.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目录下。
5. CMS前端页面查询开发
5.1 页面结构
在model目录创建 cms模块的目录结构
在page目录新建page_list.vue,扩展名为.vue。
.vue文件的结构如下:
测试页面显示...
在页面的template中填写 “测试页面显示...”。
注意:template内容必须有一个根元素,否则vue会报错,这里我们在template标签内定义一个div。
5.2 页面路由
在cms目录下创建page_list.vue页面。
现在先配置路由,实现url访问到页面再进行内容完善与调试。
5.2.1 在cms的router下配置路由
import Home from '@/module/home/page/home.vue';
import page_list from '@/module/cms/page/page_list.vue';
export default [{
path: '/cms',
component: Home,
name: 'CMS内容管理',
hidden: false,
children:[
{path:'/cms/page/list',name:'页面列表',component: page_list,hidden:false}
]
}]
5.2.2 在base目录下的router导入cms模块的路由
5.3 页面内容完善
根据需求完善页面内容,完善列表字段,添加分页组件。
查询
5.4. 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。
前端页面导入cms.js,调用js方法请求服务端页面查询接口。
-
导入cms.js
-
在query方法中调用 page_list方法
5.5 跨域问题解决
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-proxy- middleware(https://github.com/chimurai/http-proxy-middleware),它是http代理中间件,它依赖node.js, 基本原理是用服务端代理解决浏览器跨域:
cms跨域解决原理:
- 访问页面
http://localhost:11000/
- 页面请求
http://localhost:11000/cms
由于url由http://localhost:31001/cms...
改为“http://localhost:11000/cms.
",所以不存在跨域 - 通过proxyTable由node服务器代理请求
http://localhost:31001/cms
.
服务端不存在跨域问题
具体的配置如下:
-
修改api方法中url的定义
请求前加/api前缀
-
在config/index.js下配置proxyTable。
以/api/cms开头的请求,代理请求
http://localhost:31001
5.6 分页查询
-
定义分页视图
使用v-on监听更改分页事件
-
定义数据模型对象
export default { data() { return { list: [], total:0, params:{ page:1, size:10 } } }, methods:{ query:function(){ // alert('查询') //调用服务端的接口 cmsApi.page_list(this.params.page,this.params.size).then((res)=>{ //将res结果数据赋值给数据模型对象 this.list = res.queryResult.list; this.total = res.queryResult.total; }) }, changePage:function(page){//形参就是当前页码 //调用query方法 // alert(page) this.params.page = page; this.query() } }
5.7 进入页面立即查询
目前实现的功能是进入页面点击查询按钮向服务端表求查询,实际的需求是进入页面立即查询。 如何实现?
这要用到vue的钩子函数,每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会。
通常使用最多的是created和mounted两个钩子:
- created:vue实例已创建但是DOM元素还没有渲染生成。
- mounted:DOM元素渲染生成完成后调用。
本例子在两个方法的任意一个都满足需求:
添加如下代码
6. 前后端请求响应流程小结
- 在浏览器输入前端url
- 前端框架vue.js根据url解析路由,根据路由找到page_list.vue页面
- 首先执行page_list.vue中的钩子方法
- 在钩子方法中调用query方法。
- 在query方法中调用cms.js中的page_list方法
- cms.js中的page_list方法通过axios请求服务端接口
- 采用proxyTable解决跨域问题,node.js将请求转发到服务端(http://localhost:31001/cms/page/list`)
- 服务端处理,将查询结果响应给前端
- 成功响应调用then方法,在then方法中处理响应结果,将查询结果赋值给数据模型中的total和list变量。
- vue.js通过双向数据绑定将list数据渲染输出。