用Vue构建Ionic混合APP(一):Vue语法 vs Angular语法

移动书包 7个月前 300次点击 来自 Vue

通过关于 Stencil 的介绍以及Ionic向web components的转变,我们知道很快就将可以使用任何自己喜欢的框架来搭建Ionic应用。以前我们会受到Ionic总是和Angular绑在一起的限制,不过这里的“限制”并不是什么贬义词,对搭建移动应用来说,Angular是一个伟大的框架,而且我觉得未来Ionic还是会采用Angular作为默认框架。

不过,现在我们总算是有的选择了。选项之一就是现在很流行的 Vue 。你也许会问,为什么我要使用Vue替代Angular来开发Ionic应用呢,我现在并不会讨论这个问题,因为我只能说, 如果比起Angular你更喜欢Vue的话,就继续看下去吧

Vue团队发表过一篇比较几个框架的文章a guide that compares Vue to other frameworks,写的还是比较客观公正的。 Angular和Vue之间最主要的区别其实是Angular更加结构化和组织严密,Vue更加灵活和轻量化 。Angular几乎提供了一切封装好的你需要的东西,开发者很难偏离他们设计好的结构,Vue需要你自己去填补这些空白不过给了你更多的选择空间。

值得注意的是,使用Vue构建Ionic应用要比使用Angular更有挑战性,因为现在Ionic还处于转向web components的早期阶段,而Ionic+Angular已经稳定了很久了。

学习Ionic/Vue

以前在学习Ionic的时候,Ionic和Angular之间的不同并不是很重要。甚至如果你对Ionic和Angular都是完全陌生的话你也许只是在“学习Ionic”,然后一路填补你需要的那些Angular知识。当构建Ionic应用的时候,实质上几乎可以说你是在构建“Ionic化”的Angular应用。

不过Ionic确实做了些改动,基本上都是关于路由这块的。Ionic改了Angular的路由来支持他们自己的以手机为核心的push/pop风格的导航。因为这个原因,如果你只了解Angular的开发,不能啥也不做就直接过渡到Ionic应用的开发。

当使用Vue来开发Ionic的时候这就不会是个问题了,因为不会有任何Ionic的特殊处理去改变Vue的默认工作机制,你可以使用最普通的Vue路由机制,Ionic的组件只是放在那里而已。

在Vue里你也可以仍然使用Ionic里面的NavController的push/pop风格导航(因为NavController也会被转成web component),不过最好的方式还是使用普通Vue的方式。

鉴于以上这些原因,我认为在学习Vue时候最大的意义就是首先不需要考虑任何因为Ionic而带来的特殊问题(不过你最好还是知道这些东西在Ionic里是什么含义,还有和Angular有什么不同)。

在这个系列教程里,我将介绍构建Ionic/Vue混合应用的基础知识,不过如果你已经有Ionic/Angular开发基础最好,如果不是的话,这个教程不一定适合你,因为会有大量的和Angular作比较的地方。

开始

和Angular一样,Vue也提供了CLI工具来方便的创建Vue应用,必要的东西都会帮你装好,我们现在快速的通过安装CLI来创建一个新的Vue项目,然后简短的介绍一下基本的项目结构。

安装Vue CLI

npm install -g vue-cli

创建新的Vue项目:

vue init webpack my-project

这样我们就使用Webpack模板创建了一个新的Vue项目,它已经有了所有的webpack配置,开发环境,还有其他更多的默认配置。项目创建好了之后你可以进入目录:

cd my-project

然后安装需要的包

npm install

安装好之后你可以开启应用

npm run dev

应用结构(简短介绍)

最开始我想把重点放在Angular和Vue的语法差异上,不过我认为先理解一下项目结构应该很有帮助。我们先简单的过一下,之后还会详细的谈这些。

其实Vue应用的结构和Angular应用大同小异——都是有一个包含了其他所有组件(每一个可能还会有各自的组件等等)的根组件,就是树状结构的组件。

现在看看Vue应用的 index.html

<div id="app"></div>

你的Vue应用将建立在这个基础之上。然后我们看看 src/main.js

import Vue from 'vue'
import App from './App'

Vue.config.productionTip = false

new Vue({
  el: '#app',
  template: '<App/>',
  components: { App }
})

你可以看到我们在 #app 标签上创建了一个新的Vue应用,App只是又一个普通的组件(使用组件属性设置),有自己的模板。我们又一次看到这个机制和Angular是多么相似——我们的根组件是App。我们可以在 src/App.vue 看到这个组件,它是这样的:

<template>
  <div id="app">
    <img src="./assets/logo.png">
    <HelloWorld/>
  </div>
</template>

<script>
import HelloWorld from './components/HelloWorld'

export default {
  name: 'app',
  components: {
    HelloWorld
  }
}
</script>

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

这里有所有你可以在Angular应用的组件看到的东西:

  • 一个定义视图的模板
  • 定义应用逻辑的Javascript
  • 样式的定义

不过当构建Angular应用时,这三件事情都是在独立分开的文件里做的:

  • some-component.html
  • some-component.ts
  • some-component.scss

在这里所有东西都放在一个文件里。我们也引入了已经在 App组件 里添加过的 HelloWorld组件 (正如我们在 Angular里 做的一样)。 HelloWorldApp 的子组件,你可以在 src/components/HelloWorld.vue 看到它:

<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <h2>Essential Links</h2>
    <ul>
      <li><a href="https://vuejs.org" target="_blank">Core Docs</a></li>
      <li><a href="https://forum.vuejs.org" target="_blank">Forum</a></li>
      <li><a href="https://chat.vuejs.org" target="_blank">Community Chat</a></li>
      <li><a href="https://twitter.com/vuejs" target="_blank">Twitter</a></li>
      <br>
      <li><a href="http://vuejs-templates.github.io/webpack/" target="_blank">Docs for This Template</a></li>
    </ul>
    <h2>Ecosystem</h2>
    <ul>
      <li><a href="http://router.vuejs.org/" target="_blank">vue-router</a></li>
      <li><a href="http://vuex.vuejs.org/" target="_blank">vuex</a></li>
      <li><a href="http://vue-loader.vuejs.org/" target="_blank">vue-loader</a></li>
      <li><a href="https://github.com/vuejs/awesome-vue" target="_blank">awesome-vue</a></li>
    </ul>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data () {
    return {
      msg: 'Welcome to Your Vue.js App'
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h1, h2 {
  font-weight: normal;
}

ul {
  list-style-type: none;
  padding: 0;
}

li {
  display: inline-block;
  margin: 0 10px;
}

a {
  color: #42b983;
}
</style>

基本上和根组件里的东西差不多,只不过稍微复杂了一点点。 data() 方法定义的 msg 的值可以被用于模板里面,使用和Angular相同的语法 {{ }} (稍后我们再详细说这个)。同时在style模块里面的 scoped 属性的意义是指这个样式只用于这个组件。

上面只是快速了解Vue应用的工作机制,不过你应该对大致的结构和跟Angular的比较有了更好的了解。

Angular语法 VS Vue语法

尽管Vue和Angular是完全不同的两个框架,当你开始深入它们的语法差别时,你会有回家的感觉,因为它们的含义和语法都很相似,所以如果你已经熟悉了Angular,学习Vue是非常非常简单的。

在这部分,我们会看看Vue和Angular在模板语法上的相同和差异。许多Vue的模板语法借鉴了Angular的灵感,所以你会发现大量的相似点。

数据绑定 (Data Binding)

Angular里我们可以在模板里绑定所有类的成员变量,在Vue里我们可以为组件绑定任何data()方法里面定义的值:

export default {
  name: 'HelloWorld',
  data () {
    return {
      msg: 'Welcome to Your Vue.js App'
    }
  }
}

这样就定义了一个可以在模板里使用的msg变量,在Angular里为了绑定这个变量,我们会使用方括号,比如::

<span [title]="msg">

但是在Vue里我们需要使用v-bind:

<span v-bind:title="msg">

你也可以像在Angular里一样,使用双括号在模板里渲染数据:

{{ msg }}
条件 (Conditional Rendering)

Angular里面有个很强大的功能,根据特定条件实现简单的控制显示或者不显示,或者通过循环数据创建新的DOM元素。Vue也实现了相同的功能。

在Angular里如果你想根据特定条件显示一个元素,我们可以使用 *ngIf 指令:

<div *ngIf="someBoolean"></div>

在Vue里我们使用 v-if:

<div v-if="someBoolean"></div>

在Angular里如果我们想通过循环数据来为他们每个渲染元素,我们会使用*ngFor指令:

<div *ngFor="let article of articles">
    {{ article.title }}
</div

在Vue里我们使用v-for:

<div v-for="article in articles">
    {{ article.title }}
</div>

在这两个情况下,我们都可以使用和Angular相同的插值语法访问这些数据。还有一些可用选项,比如在模板里使用if/esle条件,我们暂且不谈。

事件绑定 (Event Binding)
大多数应用都需要监听和处理事件——比如点击一个元素。在Angular里,你会这样做:

<button (click)="doSomething()"></button>

再说一次Vue和它很相似,用v-on代替就可以(或者也可以使用@):

<button @click="doSomething"></button>

通过传递方法的名字,组件会注入doSomething方法。我们还没有在例子里创建方法,它大概是这个样子的:

export default {
  name: 'HelloWorld',
  data () {
    return {
      msg: 'Welcome to Your Vue.js App'
    }
  },
  methods: {
    doSomething() {
        this.msg = 'We did it!';
    }
  }
}

属性Props
Vue里的prop其实就是Angular里的Input,是一种从父组件给子组件传递数据的方法。在Angular里你可能会这样定义Input:

@Input('myInput') myInput;

然后你可以在父组件里给它绑定值:

<my-component [myInput]="someValue"></my-component>

Vue里面我们可以在需要传递数据的组件里定义props,创建一个props,我们像下面这样修改一下组件:

export default {
  name: 'HelloWorld',
  props: ['myProp'],
  data () {
    return {
      msg: 'Welcome to Your Vue.js App'
    }
  }
}

这样我们就可以通过props属性来给HelloWorld组件传递数据:

<HelloWorld myProp="hello!"/>

然后就可以在HelloWorld组件里面使用这个传过来的值了,我们可以在模板里把它渲染出来:

<h2>{{ myProp }}</h2>

屏幕上应该会显示”hello!“。

插入器语法(Slots)

我想介绍的最后一个概念是slots,它在Angular里也有这么个概念。在Angular里我们使用它来映射一些内容到组件的模板里面。举个简单的例子:

<h2>Some content is going to be injected below!</h2>
<ng-content></ng-content>
<h2>Some content is going to be injected above!</h2>

如果我们在一个组件的模板里添加这些元素,那么向该组件引入的任何内容都会被注入到标签ng-content所在的位置,比如我们写一个组件然后引入的话:

<my-component>
We'll do it live!
</my-component>

那这个组件的模板内容就会变成:

<h2>Some content is going to be injected below!</h2>
We'll do it live!
<h2>Some content is going to be injected above!</h2>

Vue里的Slots几乎和上面所做的事情一模一样,我们只是用slots替代ng-content。如果我们在一个组件的模板里添加下面这个:

<slot></slot>

然后我们给那个组件添加些内容之后引入它:

<HelloWorld>
  Put me in the slot!
</HelloWorld>

这样”Put me in the slot!“就会被注入进模板里面slots的位置。

总结

每当我们接触一个新的框架总是会有大量的东西需要学习,而且你不得不花时间在基础知识上绕来绕去,但是如果你已经很熟悉Angular的话,你就已经跨出学习Vue的一大步了。

因为尽量保持简单的原因,我这篇文章里提到的东西不一定都是最好的实践,如果你能熟悉一下Vue的官方编码风格指导将会大有脾益。

在后续的教程我们会继续学习Vue的重要概念和完全使用Vue来搭建一个Ionic应用。

目前暂无回复
关于 广告投放
©2016 - 2018 V4.1.6 Powered by 北京雏森科技有限公司