本文转自http://blog.csdn.net/joshua_hit/article/details/59635160

继续搞Vuejs的前端,在之前我已经在Windows系统上配置好了一个初始的vue-cli页面,目前我需要做的工作,就是开始写代码,学习增删页面,加入输入框按钮什么的。另外希望能尽快学会如何通过API取数据,感觉上,能学会这些东西,就能达到一项技术2/8原则里边那个8了。

为了实现这个目的,我上网看了一系列的博客教程,照着抄了很多代码,最后都没办法用。我怀疑原因可能是大家用的版本不一样,感觉上Vue发展速度很快,导致的结果就是每个人写的风格都不一样,后来费了好大力,终于算是自己摸索出了一些结果。搞定了增删按钮以及页面跳转。

我们先回溯一下上一次的进度:刚刚使用vue-cli建立了一个项目,这个项目内似乎东西很多,但是我们只需要关注src文件夹下的东西就行了,运行npm run dev以后,浏览器会自动弹出一个页面,如下: 
这里写图片描述
而目前的文件夹目录如下: 
这里写图片描述

我们要做的,就是开始理解Vue增删页面的模式,组件和路由(就是网页链接URL)的跳转模式。

大致理解Vue设计思想

首先要理解的是vue的设计理念是怎样的?在我眼里,组件化是vue最为成功的一项涉及。组件化这个特性把一整个网站都打散成了很小的一个又一个部分。举个例子,看目前的目录下,有三个文件:整个项目目录下的index.htm,src目录下的App.vue,和components文件夹下的Hello.vue.

理解这三者的关系很重要,Index是一个最外层的网站框架,它其实什么都没有,有一个head,head里边可以定义一些CSS一类的,然后body部分完全是空的,它仅仅载入了一个名字叫做app的vue module.

所以说App.vue这个东西,就是嵌套在index.html中的。然后我们在看App.vue文件写了些什么?

// App.vue file
<template>
  <div id="app">
    <img src="./assets/logo.png">
    <router-view></router-view>
  </div>
</template>

<script>
export default {
  name: 'app'
}
</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>

额外说一句,vue文件都是这个模式,一共由三个部分构成:上边的<template>包含有最终用户看到的按钮框框;中间的 <script>定义了这个组件(module)所用到的数据和函数;后边的<style>定义了这个组件的样式等等。

所以我们暂时只关注最上边的<template>,其中只有两句代码比较核心:一行插入了一个图片,另一行写的是<router-view></router-view>。在这里,大概能猜到,App.vue里其实也差不多是空的,它只是给页面上添加了一个Logo而已,实质性的文章,都没有添加。那么我们看到的页面上的文字到底是哪里来的?它们全部在Hello.vue文件里。App.vue调用了Hello.vue这个组件,并将它显示在了Logo的下方,并且,是通过router来控制的显示,而不是直接插入组件。

最后,我们打开router文件夹下的index.js:

import Vue from 'vue'
import Router from 'vue-router'
import Hello from '@/components/Hello'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      name: 'Hello',
      component: Hello
    }
  ]
})

这个router文件是针对App.vue的路由,对应的内容,全部都会显示在刚才看到的那一行<router-view></router-view>中,在这里,App.vue会自动寻找这一些组件,比如,在目前的index.js中,path显示的是”/”对吧?这就意味着,当页面打开到App.vue,而没有增加其他的url后缀的时候 (http://localhost:8080/#/),App.vue会自动载入Hello这个组件,加载在那个Logo的下面。

如果还不能理解,下面我们做一个小实验:

你修改path的值为“/Hello”,那么你只有在(http://localhost:8080/#/Hello)才会重新看到刚才那个页面。而在(http://localhost:8080/#/)目录下,你会发现,只有一个logo,其他什么都没有。 
这里写图片描述

稍微总结一下
  1. 上述的小实验已经充分证明了,index.html, App.vue, Hello.vue之间的关系。一般来说,index.html是不用动的(顶多增加一些css头文件)。所以我们开始修改的其实文件就是App.vue,然后鉴于我们想要添加文件,所以需要修改router里边的index.js文件,最后鉴于我们要添加新页面和组件,我们还需要增加一些components文件夹里边的东西。
  2. 如果按照目前的index.js的结构,如果你怎么修改那个Hello.vue文件,或者增加其他组件,它们只有一个归宿:就是躺在App.vue里的那个Logo图像的下面。因为App.vue是父组件,而Hello.vue只不过是它的子组件。但是这并不意味着谁重要谁难写,因为如果你把App.vue里边那个logo那一行注释掉,App.vue就什么都无法呈现,仅仅是为Hello.vue以及未来的一些页面提供了一个承载框架而已。
  3. 未来开发完的网站里,用户感觉上可能是一个页面和一个url的单独对应,就像是曾经的每一个PHP文件对应每一个url一样,但实际上,可能很多页面,都像Hello.vue一样,仅仅是App.vue的子组件而已。
  4. 目前在App.vue里,有Hello组件;以后我们在Hello组件里,还可以插入其他的组件,当然不一定是这种使用router的办法,因为用这个模式,每一个组件都会有一个对应的url,如果你的页面上有三个tab,可能没有必要每一个tab对应一个url吧?但目前要理解的就是:我个人觉得Vue最核心的设计理念,就是把一个看起来很完整的页面,分散到了每一个组件,这个组件可能大道一个页面,Hello.vue,也可能小到一个按钮,最终我们看到的页面,是这一群组件的堆砌的结果,这样做的一大好处就是,每一个组件都可以单独进行与数据库和用户的交互,开发更为清晰。

Git 保存

做到目前位置,我们也没有存过档,可以用Github存一下档。(熟练的高手可以忽视这一段,我是小白),在自己的Github下新建一个叫做LearnVue的repositories。代码以后就上传到这个页面上。然后确保本机上安装了Git,没有的话下载安装一下,Windows上安装超简单的,安装完以后打开Gitbash,先将目录转到Front文件夹下,然后使用如下一些命令:

git init
git add .
git commit -m "My Vue Demo"
git remote add origin https://github.com/JoshuaTian/LearnVue.git
git push -u origin master

过程中会出现一个要求你登录的页面,直接登录就是了。截图如下(图中我的命令写错了一个,读者忽视就是,用上述的代码): 
这里写图片描述

然后再回到Github页面上,刷新一下,就能看到代码已经全部上传了。以后如果代码被改乱了,可以来Github上找目前的存档恢复(我常有这种问题)。

初学vue-router

继续,刚才我们通过修改index.js上的path,已经理解了,Hello.vue和App.vue的关系,以及网址和页面(或者说页面上的某一个部分)是如何对应上的。现在我们继续探索一下,如何在子页面上,添加路由。目前的局面是,App.vue组件(它确实只是一个组件)下有Hello.vue组件,而Hello.vue的位置,是App.vue组件里面那个Logo的下面,下面我们用最快的速度再作出三个页面:

修改router文件夹下的index.js文件:

// router/index.js
import Vue from 'vue'
import Router from 'vue-router'
import Hello from '@/components/Hello'
import Home from '@/components/Home'
import FirstPage from '@/components/FirstPage'
import SecondPage from '@/components/SecondPage'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/Hello',
      name: 'Hello',
      component: Hello
    },
    {
      path: '/Home',
      name: 'Home',
      component: Home
    },
    {
      path: '/FirstPage',
      name: 'FirstPage',
      component: FirstPage
    },
    {
      path: '/SecondPage',
      name: 'SecondPage',
      component: SecondPage
    }
  ]
})

在这个文件中,我们添加了三个路由,Home,FirstPage,SecondPage,现在cmd那边肯定在报错,因为我们还没有建立那个对应的那三个Page页面的vue文件。

然后我们去components文件夹下,建立三个vue文件:Home.vue,FirstPage.vue, SecondPage.vue. 内容几乎都一样,就三行,如下(每一个就只有中间的h1标签不同,其他都一样,中间那个分开写到三个页面里),这三个页面就是分别Home,FirstPage,SecondPage将要渲染到屏幕上的东西。

// components/Home.vue
<template>
  <h1> This is Home Page </h1>
  //<h1> This is First Page </h1>
  //<h1> This is Second Page </h1>
</template>

最后修改一下Hello.vue页面,我们需要在其中加入链接,这样就可以点击某个按钮转移到新的界面了。(我多删了一些东西),让页面看起来更清爽一些:

<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <h2>Essential Links</h2>
    <ul>
      <router-link id="Home" to="/Home">Home</router-link>
      <router-link id="FirstPage" to="/FirstPage">FirstPage</router-link>
      <router-link id="SecondPage" to="/SecondPage">SecondPage</router-link>
    </ul>
    <h2>Ecosystem</h2>
    <ul>
      <li><a href="http://localhost:8080/#/Home" target="_blank">Home</a></li>
      <li><a href="http://localhost:8080/#/FirstPage" target="_blank">FirstPage</a></li>
      <li><a href="http://localhost:8080/#/SecondPage" target="_blank">SecondPage</a></li>
    </ul>
  </div>
</template>

<script>
export default {
  name: 'hello',
  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>

上边这一段代码中,我添加了六个可以点击的连接,前三个用的是vue推荐的router-link方式,后三个用的是最传统的href的方式。我个人只用前者,之所以放在这里是做比较用的。然后页面就成了这个样子。 
这里写图片描述
现在,我们如果点击任何一个连接,就能看到跳转: 
这里写图片描述

可以看到,目前所有的页面,都是在那个Logo下面,这是因为Hello.vue,Home.vue,FirstPage.vue,SecondPage.vue,全部都是App.vue的下属组建。都是被放置在Logo下的,现在如果你去App.vue里把Logo删掉,它们就是看上去都完全不同的三个页面了。

刚才已经我们成功地学会了如何添加页面,这样以后做网站如果页面不够,就用这办法可以一个一个地加,如果想要添加那种完全依赖url驱动的网页,例如/user:1,/user:2这样的,我目前还不会,但应该不会太难。

下面我们尝试在一个子页面上添加组件:

严格来说,这句话是病句,因为Hello.vue就是一个组件,我们要做的,实在组件上再添加组件,那么路由因该怎么弄?刚才做的东西,就是可以让我们在App.vue这个父组件中更换页面了,那么如何在Hello.vue页面中做到更换?如果能实现这一步,网站的所有链接跳转就都能实现了,网站无非有两种,页面直接切换,或者页面中的某个部件发生替换(就像是我们刚才在Vue那个大Logo下替换Home, FirstPage一样),所以我们需要学会如何在Vue的任何一个页面上,更换添加组件。

下面以Home.vue为例。

再打开router文件夹下的index.js,在之前写过的Home下面添加一个children路由:

// router/index.js
import Vue from 'vue'
import Router from 'vue-router'
import Hello from '@/components/Hello'
import Home from '@/components/Home'
import FirstPage from '@/components/FirstPage'
import SecondPage from '@/components/SecondPage'
import FirstPart from '@/components/HomeComponents/FirstPart'
import SecondPart from '@/components/HomeComponents/SecondPart'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      name: 'Hello',
      component: Hello
    },
    {
      path: '/Home',
      name: 'Home',
      component: Home,
      children: [
        {
          path: '/',
          name: 'FirstPart',
          component: FirstPart
        },
        {
          path: 'SecondPart',
          name: 'SecondPart',
          component: SecondPart
        }
      ]
    },
    {
      path: '/FirstPage',
      name: 'FirstPage',
      component: FirstPage
    },
    {
      path: '/SecondPage',
      name: 'SecondPage',
      component: SecondPage
    }
  ]
})

写完以后是上边这样子,我们在Home的路由中,又添加了两个子路由,FirstPart和SecondPart. 这里FirstPart的路由是”/”,代表着是默认选择,否则的话,一打开Home页面,FirstPart和 
然后再Home.vue组件中添加几行:

 <template>
  <div>
    <h1> This is Home Page </h1>
    <router-link id="FirstPart" to="/Home">FirstPart</router-link>
    <router-link id="SecondPart" to="/Home/SecondPart">SecondPart</router-link>
    <hr>
    <router-view></router-view>
  </div>
</template>

这样,我们就规定了,从Home页面渲染的组件,都显示在<hr>那条线下面。 
最后我们去到Components文件夹下,建立一个小文件夹HomeComponents(不建也行,自己找得到就好),在其中新建两个文件,FirstPart.vue和SecondPart.vue,内容几乎一致:

// components/HomeComponents/FirstPart.vue
<template>
  <div>
    <h2> This is First Part </h2>
  </div>
</template>

好了,然后再刷新页面,转到Home页面上,就可以看到: 
这里写图片描述
这样,我们就成功地在Home页上又添加了两个小的页面。

学会这一步以后,我们就可以随意地增删页面,而且页面上也可以添加更多的组件,一层一层地嵌套。在这里,我都是在用路由router来连接一个又一个的组件。而其实如果某个组件只有一个button一类的情况,用这种办法实在是没有必要。基本上,这种办法就适合架设比较大的一些页面:

例如:我学Vue的目的是为了架设一个个人网站,我大概有主页,博客页,项目页,关于页,简历页等等,这些大页面毫无疑问是需要用这种路由来假设的。假如在我的项目页里,只有四五个项目,每一个项目都是那种占满整个网页的图表,那么我就可以在项目页里,再开4-5个路由单独指向每一个项目。其余的应该没有必要,直接在Vue中添加组件就行。

下面的部分,就是有关于如何在Vue中直接Import组件。

直接Import组件

我们继续,鉴于我是想要写一个个人网站,现在我假设想要添加五个页面:主页,博客目录页,项目展示页,用户注册登录页,简历页,关于页。

虽然只有六个页面,但是要想做好,要想的东西挺多的,因为vue不像是php,不能写了一半页面了,才开始想下一半页面该怎么做,而是一开始就要想清楚,每一个页面的架构是怎样的,甚至于,每一个图表,每一个按钮最终会放在哪一个组件中?用写文章来类比,原本用php写网页,就像是写流水账一样,写到中间下半部再怎么设计结尾都可以。但是用vue,就必须要先规定死,这篇文章,开头是哪一个组件?中间是哪一个组件?结尾是哪一个组件?某一些更细的组件(例如一列排比句)应该放在中间组件的哪一个部位等等。在这里写文档,我就先不这么认认真真地设计思考了,先尽快搭出框架来。

引用一些CSS模板

到现在要开始做页面了,如果纯靠手来code整个页面,实在是太累了,所以可以使用一些现成的页面组件。这里写的组件或者模板,和前文写的组件完全不是一个意思啊!这里的组件的意思是,BootstrapElementiView一类的东西。打开一看就懂了,都是一些已经写得很漂亮很漂亮的网页组件代码片段,只用引用相关的CSS文件和JavaScript文件就能用。

有关于Vue的这类组件,似乎TalkingData的iView和饿了吗的Element做的最好。具体谁更好,我也不知道……随便抓了(Element)用起来,反正都没用过,有这方面经验的同学可以告诉我。

首先打开CMD或者CMDer,在Front文件夹下,输入:

npm install element-ui -save

这样的话Element组件就被安装到了Project里,打开main.js文件,在其中加入:

import Vue from 'vue'
import ElementUI from 'element-ui' //New Added
import 'element-ui/lib/theme-default/index.css' //New Added
import App from './App'
import router from './router'

Vue.config.productionTip = false

Vue.use(ElementUI) //New Added

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  template: '<App/>',
  components: { App }
})

这样我们就可以在整个项目都是用这一套组件了。

写出导航条

首先我们要写一个导航条,应该写在哪里呢?其实写在Hello.vue或者App.vue中严格来说都可以,但是如果写在Hello.vue中,以后添加Home, Register, Document, About等等页面,你都需要添加一次。所以还是写在App.vue中比较合适。

我们先在components文件夹中新建一个AppComponents的文件夹,专门用来放置被直接加载到App.vue中的组件,然后在其中添加一个Navbar.vue文件,我们要在其中添加导航条。

直接打开Element的页面开始抄袭。把整个导航条复制到我们Navbar.vue文件中。要稍微做一些调整,比如,添加<template>。具体的文件如下:

// components/AppComponents/Navbar.vue
<template>
  <el-menu theme="dark" :default-active="activeIndex"
  class="el-menu-demo" mode="horizontal" @select="handleSelect">
    <el-menu-item index="1">Home</el-menu-item>
    <el-menu-item index="2">Article</el-menu-item>
    <el-submenu index="3">
      <template slot="title">Projects</template>
      <el-menu-item index="3-1">Shiny</el-menu-item>
      <el-menu-item index="3-2">LearnVue</el-menu-item>
      <el-menu-item index="3-3">OtherProject</el-menu-item>
    </el-submenu>
    <el-menu-item index="4">Login</el-menu-item>
    <el-menu-item index="5">Resume</el-menu-item>
    <el-menu-item index="5">About</el-menu-item>
  </el-menu>
</template>

<script>
  export default {
    data () {
      return {
        activeIndex: '1',
        activeIndex2: '1'
      }
    },
    methods: {
      handleSelect (key, keyPath) {
        console.log(key, keyPath)
      }
    }
  }
</script>

然后,直接修改App.vue(因为导航条是要被放在App.vue里,这样所有的页面都能看到,而不用重新在每一个页面都重写)。改成这样:

// App.vue
<template>
  <div id="app">
    <mynavbar></mynavbar>
    <img src="./assets/logo.png">
    <router-view></router-view>
  </div>
</template>

<script>
import mynavbar from './components/AppComponents/Navbar.vue'

export default {
  name: 'app',
  components: {
    mynavbar
  }
}
</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: 0px;
}
</style> 

简单来说就是三步:

  1. import 那个组件。
  2. 添加到mynavbar到export中。
  3. 在div最上方写:<mynavbar></mynavbar>
  4. (修改一下下边的Style里边的那个margin-top为0px.)

然后我们再打开http://localhost:8080,就已经变成了: 
这里写图片描述

无论你怎么点击那些Home,FirstPage,界面会换导航条都不会动的。当然如果你点击导航条上的那些东西,也是什么变化都不会有的,因为上边什么都还没有做。

通过这种办法,我们只需要两步,就可以将一个组件添加到某一个大组件上,而不需要像之前一样很麻烦地调用路由。

以后我们的页面基本上都是一堆组件的堆砌。用这种办法,我们就可以耐心地一点一点把巨大的页面架构起来。这种办法,比起曾经的PHP确实麻烦许多,但是如果项目大了,项目分离就很容易,每个人只需要负责一个组件就行了,完事儿了汇总在一起,就是一堆module的import。这就是使用Vue的目的。

OK,通过这种办法,构建页面,转换路由已经没有问题了,下面还剩下的问题大概有几个:

1. 如何使用API调用数据。 
2. 组件间通信,比如,目前的导航条,默认选择是Home,如果我换到了其他的网址,如何自动调整Navbar。 
3. 如何部署上线。

Logo

前往低代码交流专区

更多推荐