概述

事情是这样开始的,因为可能的一个潜在的迭代需求,需要修改一下支付页面的逻辑。听到我就有点怂了。因为页面逻辑复杂,加上我们使用的smarty模板引擎,所以最终的代码效果是,里面JS,CSS,HTML,smarty的条件各种乱入,眼花缭乱。并且,JS逻辑也是复杂的很,我都不敢保证自己这次折腾清楚了,下次还能清楚。

于是,萌生出了用Vue重写这部分的想法。这里,因为只是针对这一个支付页面,所以就直接引入Vue的JS来重写了。最终的效果和期望值一样,十分满意。看着干净清爽多了,额外优化了一下流程,体验丝滑。

本来问题到这一步就没了。但是,H5端是我之前负责的。里面的代码情况如何,有些地方逻辑混乱也是自己最清楚的。于是,又萌生了一个想法,想在我们这个项目中引入Vue,进行小范围复杂页面的重构。有了这个想法,就开始思考什么样的方式来做了。

最终的期望

我的目的并不是重构成一个SPA应用。仅仅只是在页面中利用Vue的特性重写之前的逻辑,抽象出公共的代码作为组件。并不需要考虑路由等。因此,自己的解决方式也是围绕着这两个方向出发。

思考过程

Webpack

我们的H5端是一个后端项目。所有的页面都是PHP后端进行渲染的。和WebApp不同,WebApp是基于JS模块构建起来的,而后端渲染是通过PHP执行生成最后的HTML。所以,从这一点上,就有区别。

自己做了几个Vue的WebApp,使用的典型开发方式是ES6 + Vue + Webpack的方式。这种方式的好处是,可以利用loader,将Vue的组件独立出来作为单独的.vue文件。然后,使用ES6的加载方式。特别爽,也是典型的WebApp应用的开发方式。所以沿着这个思路,我想的是,怎么在我们的项目中引入Webpack,打包这些组件,最后结合在实际的页面中。

如下就是上面的思路的最终目录结构

目录结构

MobileRoot是项目的服务器指向的目录。其中,app是项目中JS模块的目录,也就是所有组件等的目录。类似于WebApp中的srcassets目录是打包之后的输出目录。对应的,webpack配置如下

module.exports = {
  entry: {
    project: "./app/project.js",
    ...
    ...
  },
  output: {
      path: __dirname + '/assets',
      filename: "[name].bundle.js"
  },
}

这里为了页面需要,会将JS根据页面拆分一下。在PHP视图文件中,引入打包后的JS文件即可。

在Laravel5.3中,就是类似这种处理流程。这种的模式引入了webpack,NPM,开发上和WebApp的模式就很相似了。

然后这样的方式也有问题,团队里毕竟不是都会相关知识。并且,这种方式的结果是,将页面和JS划分开了。之前的开发是,直接在页面修改,直接刷新就可以看到效果。现在,增加了项目复杂度,多了打包构建这一步。不是所有的人都愿意接受这种方式。

smarty

回到刚才的初衷上。我需要的引入Vue,并且拆分模块作为单文件。这个是核心诉求。

然后,在看Vue中组件的知识

<div id="example">
  <my-component></my-component>
</div>
// 定义
var MyComponent = Vue.extend({
  template: '<div>A custom component!</div>'
})

// 注册
Vue.component('my-component', MyComponent)

// 创建根实例
new Vue({
  el: '#example'
})

看到这里,心里就想到了一个点,我完全可以使用smarty的include方式来作为组件的模块加载。所以,最后的解决方式也异常简单。将组件写在一个单独的文件里

<!-- components/VList.vue  -->
<template id="v-list">
<div><button @click="sayHello">sayHello</button></div>
</template>

<script type="text/javascript">
var VList = Vue.extend({
  template: '#vue-list',
  methods: {
    sayHello: function () {
      alert('hello world');
    }
  }
});
</script>
<style>
button {
  background: #f03;
  color:#fff;
}
</style>

然后在需要的页面中,这种方式使用

<!-- 引入组件  -->
<{include file="./components/VList.vue"}>

<div id="app">
  <v-list></v-list>
</div>

<script type="text/javascript">
new Vue({
  el: '#app',
  components: {
    'v-list': VList
  }
})
</script>

需要注意的是,因为现在的方式,组件定义放在文件里面,其他人引入时并不知道组件的定义变量。所以,需要人为约定一下,让组件的名字和注册的组件名保持一致。这样在引入的时候,其他人看到文件名,就知道怎么使用了。

如上,就解决了自己的想法。并且,很简单,不需要去学习其他的模块知识,开发方式也和之前保持一样。

最后

Vue这种MVVM框确实颠覆了自己之前页面开发的方式,并且效果出众。以前各种DOM耦合,十分的丑陋。

上面的方式只是引入了Vue作为页面开发的基础。未来可能会有更多的需求,有某一个页面逻辑体验更加复杂了,也是考虑引入路由等。

其实我是认为第一种方式更未来。前端现在有很多很好的开发工具,像scss这类,可以很大的提高开发效率。引入webpack是使用这类工具的开端,替我们节省了很多时间。

参考资料