考虑在你的下一个 Web 项目中使用 VueJS 吧!

阅读 4887
收藏 170
2017-01-23
原文链接:zhuanlan.zhihu.com

原文链接:Consider VueJS for Your Next Web Project

作者:Roman Kuba

VueJS是什么?

大致上,你可以把Vue(读音与view相同)理解为MV*当中的V层,如果非要和别的框架比较的话,你可以把Vue理解成为上手门槛很低的类React框架。不需要你学习JSX一类的奇葩语法,也不需要预编译,只要像往常引用类库一样,在你页面的header里面加一个vue的引用链接,就可以开始使用啦。而从Vue的模板标记里,你可能会找到Angular或Mustache等框架的影子。

接下来我们聊聊VueJS为什么这么有吸引力吧。

数据驱动 vs DOM驱动

解耦的思维方式在软件开发中很常见。一般在界面开发中,我们经常会以如下这种逻辑编写代码:

function textReturningFunction () {
  return 'Hello World!'
}

// 使用jQuery来在DOM中输出内容
$('.someElement').text(textReturningFunction())

在我刚开始工作的时候,经常会写出类似的代码。但你只要仔细考虑一下就会发现,这类代码离真正的解耦还有很大的差距。

在这样的代码中,JS逻辑的实现对你的DOM结构依赖是相当大的。例如你把DOM中的.someElement这个节点改名为.some_element之后,虽然Hello World!还能被返回,但是与DOM的绑定失效了,你的JS就无法正常运行了,这也就是所谓DOM驱动的JS编码方式。

我们再来拿VueJS实现与上述相同的逻辑:

HTML

<div class="app">
  <span class="someElement">
    {{ msg }}
  </span>
</div>

JS

new Vue({
  el: '.app',

  data: {
    msg: 'Hello World!'
  }
})

在这个用VueJS实现的例子中,最后会渲染出<span class="someElement">Hello World!</span>的结果,而你可以随意修改span的属性名,因为这段JS并不依赖它的属性名来查找操作DOM的内容。

整块代码中,我们只需要在声明Vue实例时指定.app容器,Vue就可以在其内部处理逻辑。

响应式(Reactivity)

Vue中所有的变量都是响应式的。这也就意味着他们都能被观察到,也能附加watchers在上面,当变量改变时就会通知触发相应的事件。你可以阅读Vue官方的文档中深入响应式原理这一篇。

为了方便你理解,我们可以拿Vue的实现同Angular的“脏检查”做对比。

在Angular中,某个数据发生改变时,它就会开始搜索这个改变,将所有新的数据与旧的比较完之后,再修改变化的部分,当应用架构复杂之后,这样的操作就相当耗费资源和时间了。

Vue使用的响应式数据系统在初始化时可能会耗用一些资源,但解决了之后的许多麻烦。

组件

Vue灵活简单的架构也沿用了组件的概念。组件就是简单并可以被重复利用的界面模块。当然其实现在所有流行的JS框架都沿用了组件化的思想。Web Components的解决方案出现也有些时日了。问题始终是浏览器范围的实现。

Vue通过提供一个独立于浏览器的组件系统来解决这个问题。你可以在官方文档组件了解更多。

我们为什么选择VueJS

在我们的应用中,我们需要开发一个交互非常重的页面,需要渲染服务器端控制台的输出给用户,有很多现实的问题需要解决:

  • 修复可能导致浏览器卡死的性能问题
  • 优化渲染效率
  • 让代码更加易读可用
  • 尽量减小引入新技术的成本

其实最早我们用的是Angular.我们需要从服务器传输大量控制台输出的字符串。之后再渲染到客户端的界面中。我们发现Angular渲染的效率并不够好。当数据达到一定量时,浏览器就会卡死。最终我们发现瓶颈在于Angular的scope而不是传输的数据量,因为Angular总是会追踪保存DOM所有的变化。

我们需要一个对DOM关注更少,而又不需要完全改变已有架构的工具。Vue看起来能满足我们的这些需求。

经过测试,使用Vue并没有发现明显的性能问题,渲染一万行内容都不在话下。权衡之后,我们就正式开始使用VueJS啦。

VueJS初步应用

第一步对Vue的应用,当然是要用它来重构页面。例如我们要渲染一个页面的侧边栏:

<!-- Application Example -->
<div id="app">
<aside>
<ul class="services">
<li v-for="service in services">
{{ service.name }}
</li>
</ul>
</aside>
</div>

发觉这段代码有多好读了吗?即使你从来没有接触过Vue,代码本身也很好理解。对于services数组当中的每个service对象,我们要渲染出一个包含service名称的li元素。

再来看看JS部分:

new Vue({
  el: '#app',

  data: {
    services: [
      {name: 'first service'},
      {name: 'second service'}
    ]
  }
})

在浏览器中运行之后就会得到:

<!-- Rendered HTML -->
<div id="app">
<aside>
<ul class="services">
<li>first service</li>
<li>second service</li>
</ul>
</aside>
</div>

接下来再引入Vue的组件实现:

<!-- Application Example -->
<div id="app">
<aside>
<ul class="services">
<!-- Placeholder for the component -->
<jet-service v-for="service in services" v-bind:service="service"></jet-service>
</ul>
</aside>
</div>

组件的实现方法也非常好理解:

//声明一个Vue组件
var JetServiceComponent = {
  // 声明组件属性,通过 v-bind:service="service" 来绑定数据
  props: ['service'], 
  // 组件输出的HTML模板
  template: `
    <li>
      <strong>{{ service.name }}</strong>
    </li>
  `
}

new Vue({
  el: '#app',

  data: {
    services: [
      {name: 'first service'},
      {name: 'second service'}
    ]
  },
  //注册Vue应用中要使用的组件
  components: {
    'jet-service': JetServiceComponent
  }
})

使用Vue的门槛非常低,你并不需要引入一大堆模板代码再开始。你只需要熟悉JS的对象和方法就可以把Vue用得很溜了。

VueJS深入应用

有时候我们会需要渲染一些包含复杂嵌套的数据,例如下面这个例子:

[
  { name: "some step", type: "step"},
  { name: "step group", type: "group_step", steps: [
    { name: "grouped step alpha", type: "step"},
    { name: "grouped step beta", type: "step"},
  ]}
]

这时组件就需要根据数据类型的不同来进行不同的调用和渲染,为了实现这个需求,我们需要应用计算属性和条件渲染的概念:

var JetStepsComponent = {
  name: 'jet-step',

  props: ['step'], 
  // 通过计算属性保存每次调用组件的数据类别
  computed: {
     isGroupStep: function () {
       return this.step.type === 'group_step'
     }
  },
  // 通过条件渲染标记对不同类别的数据返回不同的输出
  template: `
    <li>
      <span>{{ step.name }}</span>
      <ul v-if="isGroupStep">
        <jet-step v-for="step in step.steps" v-bind:step="step"></jet-step>
      </ul>
    </li>
  `
}

综上所述,Vue就是这么的简洁高效。

为什么VueJS对你有用?

这世上并没有能解决一切需求的完美框架。所有脱离上下文对比框架好坏的做法都是耍流氓。每个框架都有各自适用的场景。Vue对我来说高效又好用,它只专注于解决一个问题:将数据渲染到页面中。而与此同时,Vue的生态圈也在不断发展壮大:

  • 前端路由?你可以使用vue-router
  • Ajax 异步请求?vue-resource(不过官方不再推荐),还可以使用axios
  • 状态管理?Vuex
  • 自动化构建?vue-cli并且vue的单文件组件等功能也能与Webpack/Browserify很好地协同使用。

总之,现在Vue越来越火了。有任何好的意见或建议以及对Vue的观点或看法欢迎在评论区参与讨论。

评论