本文假设你对Yii和Vue都比较熟悉,至少都在项目里用过,另外笔者新人,之后不定时放一些干货,欢迎程序媛关注php
Yii是一个PHP全端框架,典型的mvc的项目结构,后端接口都是一个控制器里放了不少的action,每一个action都是一个接口,能够返回JSON,也能够render出一个html5页面,这些页面就是mvc的view,结构紧凑强耦合。html
Vue是一个前端框架,主要思想就是SPA(单页面应用),组件化开发是其根本目的。前端
这二者怎么去结合使用才能达到工程的最易开发和最易维护是一个很值得思考的问题,小编结合项目需求,设计了一套利用这二者来构建先后端分离项目的架构vue
看一下项目目录的样子html5
这里有bapp、bmanager、bshare等等多个项目,每一个项目里的文件结构是这样的ios
既然咱们已经考虑先后端分离了,那么Yii里面的view层,咱们就不须要了,相似于这些view的代码git
return $this->render('baseinfo', ['phone' => $contact['mobilephone'], 'isdel' => $isdel]);
var host = "<?= Yii::$app->params['bUrl']?>";var mobilephone="<?php echo $phone ?>";var isdel="<?php echo $isdel ?>";
<div class="base"><span class="name"><?php echo $name; ?></span> <span class="mobile"><?php echo $mobilephone; ?></span></div><div class="mark">备注:<?php echo $notes; ?></div>
这些看上去很是丑陋的代码将不容许出如今项目里。Vue是一个完整的前端SPA项目,放在服务器上能够独立运行。那么咱们考虑把这个项目打包放在bapp的web目录下(下面以bapp项目为案例说明),由于这个web目录就是Yii里边对应站点的根目录,(例如bapp项目的域名为bapp.stock.com,在web目录下放一张图片,那么这张图片的远程路径就该是http://bapp.stock.com/IMG_1383.JPG)github
这里有一个关键的地方,咱们整个项目叫作bapp,那么Yii里面的后端项目取名就叫作bapp,vue前端项目取名也叫bapp,这样能保持对应,便于理解,这是一个要遵照的规范。web
这个是vue成功build以后的文件,存放在web/bapp下,对于一个vue-cli初始化构造的项目,如今就可使用url:http://bapp.stock.com/bapp来访问你的前端项目了vuex
上面的思路基本就实现了一个简单的先后端分离过程。实际项目中咱们还有不少须要规范和注意的地方。下面依据咱们须要解决的三个主要问题来进一步设计这个架构
vue的build项目自动放在yii的web目录下
这一点对于这种先后端分离的开发模式很重要,vue-cli默认的build路径是放在dist下,如今必需要让build的文件自动放在其余路径下的yii的web下,这里就须要修改默认的配置了
因为vue项目默认是存放在站点的根目录下,也就是编译后生成的全部文件必须放在trunk/bapp/web下,这个目录本来有一些其余文件,最好不要直接扔过去,建一个新目录trunk/bapp/web/bapp来存放这些文件将会更加清晰。这样你会发现一个新问题,你build的项目放在web/bapp下会没法运行,会找不到文件路径。这就要修改vue的运行根目录,用来解决vue项目在子站点里没法运行的问题,很简单,修改路由的base便可
开发环境生产环境部署怎么解决
Vue项目的config下有dev.env.js、test.env.js、prod.env.js,你能够在这里设置你的APIURL,请求接口的地方使用process.env.APIURL来获取,这种模式下,咱们须要在不一样环境发布不一样的webapp包,相似于Android和ios的app开发模式。这种方法在咱们这并不可取,由于PHP在各个环境里已经配置了站点,vue项目在php项目下,因此咱们要从php来获取当前的运行环境,这才显示出咱们这种架构的易维护呀。具体思路就是在vue里解析当前的url获取环境了。
在vue的main.js里来作这个工做
利用document.location.href获取运行环境,把api站点存在vuex里,须要请求接口的地方从vuex里直接取,上面代码里解析完apiurl以后有一个解析路由的过程,这个下面再讲
原生客户端怎么去请求vue页面
vue项目可能会包含不少页面,有的页面多是一个较大的模块,好比商城系统的全部页面,有的页面可能就是一个用户须知什么的单页面,客户端浏览器在调用这些页面须要按照模块来调用。这里就要求vue项目在开发过程当中必须按照不一样模块在route下创建不一样路由的规范去作,这样既有利于前端代码碎片化,也有利于客户端调用更加方便。
在后端控制器里trunk/bapp/controllers/里我有一个BuserController的控制器,在这个控制器里添加了一个action
这个action很是重要,是先后端分离的关键
这个action很是重要,是先后端分离的关键
这个action很是重要,是先后端分离的关键
这个action名字也须要遵循规范都叫作webapp,在后端其余项目里,好比个人工程里还有capp项目,我也能够在capp下的CuserController里添加这个webapp的action。
$url = Yii::$app->params['bUrl'] . "bapp/#/{$page}?route={$route}&{$query}&" . $this->sessionQueryString();
其中这行代码比较关键,这个url其实就是bapp/web/bapp的vue项目的地址,
Yii::$app->params['bUrl']
是配置在PHP里的域名地址
bapp/#/{$page}
是vue的hash路由的调用方式,具体可参看vue官方文档
$this->sessionQueryString();
是取的sessionid,这个读者能够改为本身系统里的登陆标记
客户端显示的全部h5都经过这个接口获取,对这个接口的参数有必要重点说明,webapp接收三个入参
route(必传)
route参数由前端定义,好比前端有一个商城的模块叫作mall,那么vue的router下应该会有一个mall.js,里面管理全部商城的页面分发,客户端想显示mall的页面就在调用webapp时用route=mall,再好比前端有一个活动页面的模块activity,那么vue的router下会有一个activity.js来管理全部活动页面的分发,客户端要显示活动页面必须传route=activity
2.page(非必传)
对于像mall这样的完整模块,客户端可能只须要显示mall的首页就能够了,那么page就不须要传,自动进入到vue的router/mall.js的默认页面,若是像活动模块,这里面的页面可能都不关联,可能有activity一、activity二、acitivity3等页面,客户端想显示activity2页面,就必须传page=activity2
3.addition(非必传)
用addition传的是附加参数,客户端在调用某个页面时,可能会带上一些用户信息,好比手机号,token,session等,这些参数都放在addition中
原生客户端经过get或post均可以调用这个接口取到页面,简单说下两种调用方式区别
GET:这里须要注意addition这个附加参数怎么拼到url里,例若有这种json
{
"mobile":"18512331232",
"info":{
"name":"jimmy",
"sex":"mail"
}
}
二维数组的get传参不少同窗都不知道,注意一下
http://xxx.xxx?addition[mobile]=18512331232&addition[info][name]=jimmy&addition[info][sex]=mail
这个地址在原生的webview里直接loadUrl便可
POST:全部参数都放在post体里边,接口返回的是最终须要显示的h5页面的代码,原生在取到这个h5代码以后
webview须要loadHtml显示
vue项目和yii项目的命名必须一致
vue的build项目必须放在yii的web下的新建文件下,文件夹名称必须和项目名称相同
yii项目控制器里创建Webapp的action做为客户端访问H5页面的惟一入口
vue的路由须要按照模块名称创建路由文件
后端代码核心就是actionWebapp,
前端代码给你们参考一下:https://github.com/ahuchjm/Vue_Bapp.git
祝生活愉快!!!