如何使用Vue 2构建简单的单页面应用程序

2020-12-23 10:39发布

7条回答
-绝世帅逼
2楼 · 2020-12-23 18:05

请采纳


vue 构建单页应用

Part1 of this tutorial dealt with the basics of building a single page application, with page linking automatically done by Vue. In this tutorial, you will learn how to:

本教程的第1 部分介绍了构建单页应用程序的基础知识,以及由Vue自动完成的页面链接。 在本教程中,您将学习如何:

  • pass parameters alongside the routes, and


    在路线旁边传递参数,以及

  • use route guards to protect routes and block off non-authenticated users from visiting the site.


    使用路由防护器来保护路由,并阻止未经身份验证的用户访问该站点。

Starting off from the end of the last tutorial, head over to the GitHub repository to clone and continue with the application.

从上一教程的结尾开始,转到GitHub存储库以克隆并继续该应用程序。

你会建造什么? ( What will you build? )

You are going to build on the existing project done in Part 1, add navigation guards and a route to pass parameters.

您将在第1部分中完成的现有项目的基础上,添加导航保护和传递参数的路线。

Here is a pictorial view of what we will be building.

这是我们将要构建的图形视图。

将参数传递给路线 ( Passing parameters to routes )

In Vue, parameters can be passed to a route by simply putting the : attribute before the parameter name. This is somewhat similar to the routing mechanism in Laravel. If you are familiar with Laravel, the {} annotation is used to specify a route.

在Vue中,只需将:属性放在参数名称之前,就可以将参数传递到路由。 这有点类似于Laravel中的路由机制。 如果您熟悉Laravel,则{}批注用于指定路线。

Look at the example below, taken from the Vue router documentation.

看下面的例子,摘自Vue路由器文档。

{ path: '/user/:id', component: User }

From the example, it can be said that the route will give the result of /users/2 , or any integer in place of 2. Whatever content the parameter holds will be referred to as the “id”, which can be accessed using $route.params.id in the User component, which was declared as its component. Let’s begin!

从该示例可以说,该路由将给出/users/2的结果,或代替/users/2任何整数。无论该参数包含什么内容,都将称为“ id”,可以使用$route.params.id进行访问。 User组件中的$route.params.id ,已声明为其组件。 让我们开始!

创建参数路径 (Creating the parameter route)

Create a new component in the src\components folder called Param.vue , and copy the following contents into it:

src\components文件夹中创建一个名为Param.vue的新组件,并将以下内容复制到其中:

//src\components\Param.vueexport default {    name: 'Param',    data () {        return {        UserInput :''        }     },     methods:{        GoToRoute : function(){        this.$router.push({ name: 'Paramdetails', params: { id: this.UserInput }})        }    }}

In the above piece of code, a param component was defined, which is the template that holds a text box and a button.

在上面的代码中,定义了一个param组件,这是一个包含文本框和按钮的模板。

Now, go to the main.js file, import the Param component, as well as create a path that handles the route.

现在,转到main.js文件,导入Param组件,并创建一个处理路线的路径。

Just above the Const routes block of code, add the following import:

Const routes代码块上方,添加以下导入:

//main.jsimport Param from './components/Param

After doing the above and importing the param component, replace the routes block with this:

完成上述操作并导入了param组件后,请用以下命令替换routes块:

//main.js//define your routesconst routes = [//route for the home route of the webpage{ path: '/', component: Hello },//route for the about route of the webpage{ path: '/about', component: About }, //route for the param route of the webpage{ path: '/param', component: Param }]

Notice that in the above piece of code, the only difference that occurred was the addition of the param route. However, there is one more step to go so that the route can be shown with the about and home links.

注意,在上面的代码段中,发生的唯一区别是添加了param路由。 然而,有一个步骤去,这样的路线可以与显示abouthome的联系。

Use the router link tag in our App.vue file, and add the following line of code, just after the “about” link:

使用我们App.vue文件中的router链接标签,并在“ about”链接之后添加以下代码行:

Param Link

Take a look at the homepage, it should look like this:

看一下主页,它应该如下所示:



Notice that the param link is just after the “about” link. Click on the param link, and you should see the following:

请注意, param link位于“ about”链接之后。 单击参数链接,您应该看到以下内容:



Open up the developer's tool in the console. If you click on the button, you will likely encounter this error.

在控制台中打开开发人员的工具。 如果单击该按钮,则可能会遇到此错误。

[vue-router] Route with name 'Paramdetails' does not exist

This is because, in the code above, the method attached to the button triggers this:

这是因为在上面的代码中,按钮上附加的方法触发了此操作:

this.$router.push({ name: 'Paramdetails', params: { id: this.UserInput }}), which has not defined any route called paramdetails that accepts parameters.

this.$router.push({ name: 'Paramdetails', params: { id: this.UserInput }}) ,它没有定义任何称为paramdetails接受参数的路由。

The next step is to create the component that handles the route. Create a new file in src/components called paramedetails.vue, and paste the following contents into it.

下一步是创建处理路线的组件。 在src/components创建一个名为paramedetails.vue的新文件,并将以下内容粘贴到其中。

    The paremeter value that was passed to me is: {{ $route.params.id }}     export default {    name: 'paramdetails'    }

This creates a component that holds a span element, which also prints out the parameter that was passed to it. For this to work, add this new component to the routes.

这将创建一个包含span元素的组件,该元素还将打印出传递给它的参数。 为此,请将这个新组件添加到路由中。

Just above the Const routes block of code, add the following import:

Const routes代码块上方,添加以下导入:

//main.js//import paramdetails componentimport paramdetails from './components/paramdetails'

After doing the above, and importing the paramdetails component, replace the routes block with this:

完成上述操作后,导入paramdetails组件,用以下paramdetails替换routes块:

//main.js   //define your routes    const routes = [    //route for the home route of the web page    { path: '/', component: Hello },    //route for the about route of the web page    { path: '/about', component: About },     //route for the param route of the web page    { path: '/param', component: Param },    //route for the paramdetails passing in params    { path: '/Paramdetails/:id', component: paramdetails, name: 'Paramdetails' }    ]

Notice that the last route has two new adjustments, which was not visible in other routes. The first adjustment is the : id, which is the placeholder for the routes you are passing in. The second adjustment is the name object in the route object.

请注意,最后一条路线有两个新的调整,在其他路线中不可见。 第一个调整是: id ,它是您传入的路由的占位符。第二个调整是在路由对象中的name对象。

To understand the name property in the object, know that just like any other router, the Vue router contains the concept of naming routes. Instead of remembering the full URL of the new route, the shorter way of calling routes is by naming the routes. Also, take a look back at the GoToRoute method in the param component, you will see that the router object is being pushed, which identifies the route by name.

要了解对象中的name属性,请知道与其他路由器一样,Vue路由器也包含命名路由的概念。 代替记住新路由的完整URL,调用路由的较短方法是命名路由。 另外,回顾一下param组件中的GoToRoute方法,您将看到正在推送路由器对象,该对象通过名称标识路由。

Now, click on the param link link, and type in 52 in the text box, for example. Then click the go to route button, and you should see a page like this:

现在,单击param link ,然后在文本框中输入52。 然后单击go to route按钮,您应该看到如下页面:



That is it! You have just passed in your first route to the component. Super easy, isn't it?

这就对了! 您刚刚进入了通往组件的第一条路线。 超级容易,不是吗?

使用路由卫士 ( Using route guards )

A route guard is a watcher that watches for changes in the routes and performs some actions, either before the route is transitioned into the next one, or after the route has been transitioned. Route guards can be used to protect routes against non-authenticated users from visiting the site. Vue router has global guards, per-route guards, as well as component guards.

路由守卫是一种观察者,负责监视路由中的更改并执行某些操作,既可以在路由转换到下一条之前,也可以在路由转换之后执行。 路由保护器可用于保护路由,防止未经身份验证的用户访问该站点。 Vue路由器具有全局防护,按路由防护以及组件防护。

There are two major global routes produced by Vue router namely: beforeEach and afterEach guards. As the name implies, the “beforeEach” is performed before a new route is transitioned, as opposed to the “afterEach” guard.

Vue路由器产生两条主要的全局路由,分别是beforeEachafterEach警卫。 顾名思义,“ beforeEach”是在转换新路由之前执行的,与“ afterEach”后卫相反。

Per-routes guards can be added to the route object of the particular route to be guarded as a callback, while the “in-component” guards are defined in the components that handle those routes. For the purpose of this tutorial, stick to the “beforeEach” global route.

可以将每个路由保护措施添加到要保护的特定路由的路由对象中,作为回调,而“组件内”保护措施在处理这些路由的组件中定义。 就本教程而言,请遵循“ beforeEach”全局路线。

Open the main.js file, and immediately after the routes constant, add the following:

打开main.js文件,并在路由常量之后立即添加以下内容:

//main.js//place the router guardrouter.beforeEach((to, from, next) => {    //check if the path user is going to is our param path    if(to.path == '/param'){        //check if the user item is already set        if(localStorage.getItem('user')==undefined){            //prompt for username            var user = prompt('please enter your username');            //prompt for password            var pass = prompt('please enter your password');            //check if th username and password given equals our preset details            if (user == 'username' && pass == 'password'){            //set the user item            localStorage.setItem('user', user);            //move to the route            next();            }else{            //alert the username and pass is wrong            alert('Wrong username and password, you do not have permission to access that route');            //return, do not move to the route            return;            }         }     }     next()})

The “router.beforeEach” function was called and it takes three arguments that are passed to it by the Vue router. The to parameter refers to the object of the path to be accessed, while the from parameter refers to the object of the previous path.

调用了“ router.beforeEach”函数,该函数接受Vue路由器传递给它的三个参数。 to参数是指要访问的路径的对象,而from参数是指先前路径的对象。

Check if the “to.path” is /param, which is the path for the route to be protected. If the path corresponds to the one to be protected, check the “localStorage” data holding the user details to see if it is defined. If the “localStorage” data is not defined, prompt for the username and password, and create the “localStorage” data. If it is defined, the function continues and the route is visible to the user.

检查“ to.path”是否为/param ,这是要保护的路由的路径。 如果该路径与要保护的路径相对应,请检查包含用户详细信息的“ localStorage”数据以查看是否已定义。 如果未定义“ localStorage”数据,则提示输入用户名和密码,然后创建“ localStorage”数据。 如果已定义,该功能将继续并且该路线对用户可见。



Note: The next function must be called so that the router can process the user to the next page. If the function isn't called, a blank screen could come up. In this tutorial, a raw string of username and password was used for the authentication details. However, a lot more can be done, such as requesting user authentication via a server.

注意:必须调用下一个功能,以便路由器可以将用户处理到下一页。 如果未调用该函数,则可能会出现空白屏幕。 在本教程中, usernamepassword的原始字符串用于身份验证详细信息。 但是,可以做更多的事情,例如通过服务器请求用户身份验证。

结论 ( Conclusion )

You should now be able to pass parameters to routes, know what named routes are, and how to create them. Also, the types of route guards, as well as an implementation for the “beforeEach” route guard was explained.

现在,您应该能够将参数传递给路由,知道什么是命名路由,以及如何创建它们。 此外,还说明了路由防护的类型以及“ beforeEach”路由防护的实现。

Now, you should be able to create a single page application, register routes, pass in parameters to the routes, as well as guarding the routes. On these premises, you can begin to build awesome single page applications.

现在,您应该能够创建一个单页应用程序,注册路由,将参数传递给路由以及保护路由。 在这些前提下,您可以开始构建出色的单页应用程序。


小小收藏家
3楼 · 2020-12-23 21:00

在对Vue和webpack有了一定了解后,我们就可以开始利用所了解的东西做一个简单的webapp了,不了解的同学可以看下我的前两篇关于vue和webpack的基本应用:
webpack+vue起步
利用webpack和vue实现组件化

我是大脸猫
4楼 · 2020-12-24 10:27

使用 Vue 构建单页应用程序。

Vue.js 是一个构建交互式Web界面的库。 它为 数据反应式(data-reactive) 组件提供了一个简单而灵活的API。

为了本教程的目的,术语 Vue 指的是 Vue 2.X 版本,除非另有说明。

我们将构建什么

让我们快速了解一下我们正在构建的内容,如图:

完整的示例代码:https://github.com/samuelayo/vue-spapt1

通过本教程希望你已经掌握:

  1. Vue 的基础知识。

  2. 如何创建 Vue 组件。

开始使用 Vue CLI

为了方便起见,并跳过将 ES6 编译为 ES5 的 webpack 的配置过程,我们会使用 vue cli 。如果您没有安装 Vue cli,我们可以通过执行以下操作进行安装。

sudo npm install -g vue-cli

安装 vue-cli 之后,是时候创建一个 vue 项目了。 为此,我们运行以下命令。

注意:为了本教程的目的,在运行下面的命令时,当问我代码是否 linting 时,我选择了否。

代码 linting 将确保代码的正确缩进,以及空格也不会被保留。但是我喜欢在我的代码中保留空格,以保持代码的美观。

vue init webpack spa

在上面的命令中,我们会注意到两个陌生的单词 webpack 和 spa 。

这个命令中的 webpack 指的是我们想要使用的项目脚手架的模板名称,它是 vue-cli 用来帮我们构建项目模板的。还有不同的模板可以使用,有关这方面的更多信息,你可以访问 这里 。

此命令中的 spa 指的是创建应用程序的目录名称。运行上述代码后,我们需要进入该应用程序目录,并安装模块:

// 进入创建应用程序的目录
  cd spa
// 安装所需的 npm 模块
  npm install
// 运行开发服务
  npm run dev

运行上面的这些命令后,打开 http://localhost:8080 ,我们应该可以看到:

安装和配置 Vue router

现在我们设置并准备开始我们的单页应用程序。但是,我们还需要安装一个依赖,名为 vue-router 。

vue-router 是 Vue 官方提供的 router(路由) 。它与 Vue.js core(核心) 深度整合,使 Vue.js 构建单页应用变得轻而易举。功能包括:

  1. 嵌套路由 / 视图映射

  2. 模块化,基于组件的路由配置

  3. 路由参数,查询,通配符

  4. Vue.js transition(过渡) 系统提供的视图过渡效果

  5. 精细的导航控制

  6. 与自动的激活 CSS 类链接

  7. HTML5 history(历史记录)模式 或 哈希模式,在 IE9 中自动回退

  8. 可定制的 Scroll(滚动) 行为

如果你以前使用过 angular ,或者你有任何 angular 知识,那么你会发现 vue-router 类似于 angular router ,或者如果你有任何 react 知识,它和 react-router 也很类似。

我们使用 vue-router 的主要原因是它允许我们在 页面/路由 之间进行切换,而不会 刷新/重新 加载页面。

尽管如此,我们来看看如何安装它。

我们可以通过运行以下命令来安装它。

npm install vue-router --save

现在让我们进入 src/main.js 来配置应用程序,以使用 router(路由) 。

复制以下代码,并替换为 src/main.js 内容:

// 通过 `import` 命令加载 Vue 构建版本(runtime-only 或 standalone),
// 该构建版本已在webpack.base.conf中设置了别名。
// 导入 vue 实例
import Vue from 'vue'
// 导入 App 组件
import App from './App'
// 导入 vue router(路由)
import VueRouter from 'vue-router'
// 告诉 vue 使用这个 router(路由)
Vue.use(VueRouter)
// 定义你的 router(路由)
const routes = []

// 创建 router 实例并传递 `routes` 选项
// 您可以在这里传递其他选项,
// 但现在让我们保持简单。
const router = new VueRouter({
  routes, // `routes: routes` 的简写
  mode: 'history'
})
//实例化 vue 实例
new Vue({
// 定义根组件的选择器
  el: '#app',
  // 根组件的 template 
  template: '',
  // 声明根组件可以访问的组件 
  components: { App },
  // 传入 router 到 vue 实例
  router
}).$mount('#app')// app 上装载 router

让我们快速看看上面的代码。我们从 node modules 导入 Vue 类,然后我们还导入了 App 组件。

App 组件是由 vue cli 创建的默认组件。然而,我们导入它作为我们的根组件。

之后,我们再导入 vue-router ,然后告诉 Vue 类,它可以通过使用 vue.use(vuerouter) 来使用 vue-router 。

在下一行中,我们定义一个 routes 的常量,现在,我们将其设置为一个空数组。但是,routes 应该是一个对象数组,其中每个对象表示路径。不过,我们很快会看到。

接下来我们要做的是创建我们的 router(路由) 。我们可以传递两个参数给 Vue 路由的实例。

第一个参数是我们上面声明的 routes 数组,另一个参数作为模式。需要说明的是,这里我们把 mode 参数设置为'history',以防止我们的 URL 中包含 # 标记,这也被证明是不利于 SEO 的,当 URL 中包含 # 标记时。

之后,我们创建一个新的Vue实例,我们将详细配置传入根组件,以及声明 router(路由) 的装载节点。

在此刻,如果我们重启应用服务,我们会注意到,似乎没有任何变化。但是,我们现在已经设置了路由器。

接下来的下一步是用 router(路由) 插槽  标签替换我们的App组件的内容,里面每一个组件匹配的视图将被渲染。

现在打开你的 src/App.vue 文件,并将其替换为以下内容:



[removed]
export default {
  name: 'app',
}
[removed]

如果我们看看上面的代码,我们会注意到与 vue cli 自动生成的代码有一些差异,这些差异包括:

  • router-view 标签被放置在了 template 内,用于渲染视图。

  • 删除 hello 组件的 import 语句。

  • 在 script 标签中删除了组件代码块。

这些组件因为不再需要而被删除,但最重要的是添加的 router(路由) 视图标签,如上所述。

此时,如果我们重新加载我们的应用,我们会看到一个空的页面。

设置 router(路由)

现在让我们继续添加 hello 组件作为主页的组件,并添加路径到我们的 routes 数组中。

打开你的 main.js 文件,并通过以下方式替换常量 routes 数组块代码:

// 导入 hello 组件
import Hello from './components/Hello'
// 定义路由
const routes = [
  // 定义应用的根 URL
  { path: '/', component: Hello }
]

如果我们看看上面的代码,我们导入了默认的 hello 组件,并为其分配路径,将其作为处理我们根路径的组件,因此,如果我们重新加载我们的页面,现在应该可以看到,如图:

从上图可以看出,Vue 的 logo 不见了,那是因为在我们替换 App 组件的内容时,删除了图像。

现在我们再定义一个 router(路由) ,因此,让我们再创建一个组件。

所以在 src/components 文件夹内创建一个名为 About.vue 的文件,将以下内容复制到 About.vue 文件中:



[removed]
export default {
  name: 'about'
}
[removed]

现在来看看上面的组件。该组件在模板中保存一些文本,一旦我们打开关于页面的链接,它将被渲染。但是,我们仍然需要添加新的组件,并设置 router(路由) 路径,然后才能查看。

要做到这一点,打开你的 main.js ,并用下面的代码替换常量 routes 块代码:

// 导入 hello 组件
import Hello from './components/Hello'
// 导入 about 组件
import About from './components/About'
// 定义路由
const routes = [
  // 主页路由
  { path: '/', component: Hello },
  // about 页面路由
  { path: '/about', component: About }
]

在上面的代码中,现在唯一的区别是 导入了 about 组件和添加了 router(路由) 路径。

如果我们现在打开 http://localhost:8080/about,我们会看到 about 组件的文本会被渲染。

使用路由链接

但是,这不是我们想要的。单页面应用的目的是使页面不再需要重新加载。为了这样,我们需要使用  标签。

让我们打开 App.vue 文件,然后添加路由链接。所以在组件的  声明之前,让我们添加两个路由链接:

Home
About

上面的代码会为我们创建两个锚点标签,并动态路由,使页面不需要重新加载。

如果你重新加载你的应用程序,我们会注意到上面添加了两个新的链接。点击这些链接,视图就会改变,并且页面不会重新加载。

在此刻,您的应用程序应该如下图所示。

在下图中,注意上面放置的两个链接,并且该页面不会重新加载。

结论

这篇文章介绍了如何创建一个简单的单页应用程序。

但是,您可以通过以下方式使其变得更加复杂:

  • 添加更多路由

  • 传递路径参数

  • 使用路由保护,设置未经认证的用户可访问路由。


梵梵
5楼 · 2020-12-24 20:01

app很简单,使用vuejs自不必说,组件开发模块管理使用vue-loader、webpack,页dao面切换以及过场动画使zhuan用vue-router,在shuapp开发过程只需关注app的数据走向即可,另外可以搭配各类UI库让你的应用更加美观,正如楼上答过的,使用SUI或Framework7都可以,我使用的是Framework7一个分支版本light7(因为后续的功能补充可能用到jQuery。如果涉及数据后台同步可以配合后端语言进行开发,我选用了Google现成的Firebase作为数据存储端。

灰机带翅膀
6楼 · 2020-12-26 17:58

前言

我们将会选择使用一些vue周边的库vue-clivue-router,vue-resource,vuex

1.使用vue-cli创建项目
2.使用vue-router实现单页路由
3.用vuex管理我们的数据流
4.使用vue-resource请求我们的node服务端
5.使用.vue文件进行组件化的开发
PS:本文node v6.2.2 npm v3.9.5 vue v2.1.0 vue-router v2.0.3 vuex v2.0.0

最终我们将会构建出一个小demo,不废话,直接上图。

安装

1.我们将会使用webpack去为我们的模块打包,预处理,热加载。如果你对webpack不熟悉,它就是可以帮助我们把多个js文件打包为1个入口文件,并且可以达到按需加载。这就意味着,我们不用担心由于使用太多的组件,导致了过多的HTTP请求,这是非常有益于产品体验的。但我们并不只是为了这个而使用webpack,我们需要用webpack去编译.vue文件,如果没有使用一个loader去转换我们.vue文件里的style、js和html,那么浏览器就无法识别。

2.模块热加载是webpack的一个非常碉堡的特性,将会为我们的单页应用带来极大的便利。
通常来说,当我们修改了代码刷新页面,那应用里的所有状态就都没有了。这对于开发一个单页应用来说是非常痛苦的,因为需要重新在跑一遍流程。如果有模块热加载,当你修改了代码,你的代码会直接修改,页面并不会刷新,所以状态也会被保留。

3.Vue也为我们提供了CSS预处理,所以我们可以选择在.vue文件里写LESS或者SASS去代替原生CSS。

4.我们过去通常需要使用npm下载一堆的依赖,但是现在我们可以选择Vue-cli。这是一个vue生态系统中一个伟大创举。这意味着我们不需要手动构建我们的项目,而它就可以很快地为我们生成。

首先,安装vue-cli。(确保你有node和npm)

npm i -g vue-cli

然后创建一个webpack项目并且下载依赖

vue init webpack vue-tutorial


cd vue-tutorial

npm i

接着使用 npm run dev 在热加载中运行我们的应用

这一行命令代表着它会去找到package.jsonscripts对象,执行node bulid/dev-server.js。在这文件里,配置了Webpack,会让它去编译项目文件,并且运行服务器,我们在localhost:8080即可查看我们的应用。


这些都准备好后,我们需要为我们的路由、XHR请求、数据管理下载三个库,我们可以从vue的官网中找到他们。另外我们使用bootstrap作为我的UI库

npm i vue-resource vue-router vuex bootstrap --save

初始化(main.js)

查看我们的应用文件,我们可以在src目录下找到App.vuemain.jsmain.js将会作为我们应用的入口文件而App.vue会作为我们应用的初始化组件。先让我们来完善下main.js

// src/main.jsimport Vue from 'vue'import VueRouter from 'vue-router'import VueResource from 'vue-resource'import App from './App'import Home from './components/Home'import 'bootstrap/dist/css/bootstrap.css'Vue.use(VueRouter)Vue.use(VueResource)const routes = [{path : '/',component : Home},{path : '/home',component : Home}];const router = new VueRouter({routes});/* eslint-disable no-new */// 实例化我们的Vuevar app = new Vue({el: '#app',router,...App,});复制代码

这有两个与1.0不同的地方

一、vue-router路由的参数由对象统一变为了数组要注意。还有则是实例化vue的el参数已经不能设置htmlbody了,因为在vue2中是会替换我们指定的标签

二、我们必须在实例化vue的时候指定渲染什么组件,以前我们是通过路由来指定如router.start(App, '#app'),而在vue2中则不需要了

可以发现我们在main.js里使用了两个组件App.vueHome.vue,稍后让我们具体实现它们的内容。

而我们的index.html只需要保留

即可,我们的Vue在实例化时设置了el : '#app' 所以会替换这标签,为我们App组件的内容

//index.html
复制代码

我们的初始化就到这结束了,接下来让我们开始创建组件。

创建首页组件

首先我们在App.vue里为我们的应用写个顶部导航。

// src/App.vue复制代码

除了我们的navbar以外,我们还需要一个.container去放我们其余需要展示的信息。
并且在这里我们要放一个router-view标签,vue-router的切换就是通过这个标签开始显现的。

在这有个与1.0不同的地方

以前我们可以直接通过写a标签 然后写v-link属性进行路由跳转,在vue2中改为了写标签再写对应属性(to)进行跳转

接着,我们需要创建一个Home.vue作为我们的首页

// src/components/Home.vue复制代码

不出意外的话,你可以看见如下效果


创建侧边栏组件

目前我们首页左侧还有一块空白,我们需要它放下一个侧边栏去统计所有计划的总时间。

// src/App.vue//...
//...复制代码
[removed]import Sidebar from './components/Sidebar.vue'export default {components: { 'sidebar': Sidebar },}[removed]复制代码

Sidebar.vue我们需要通过store去获取总时间,我们的总时间是共享的数据

// src/components/Sidebar.vue[removed]export default {computed: {time() {return this.$store.state.totalTime}}}[removed]复制代码

创建计划列表组件

然后我们需要去创建我们的时间跟踪列表。

// src/components/TimeEntries.vue复制代码

关于template的解释,都写在一起了,再看看我们的script

// src/components/TimeEntries.vue[removed]export default {name : 'TimeEntries',computed : {plans () {// 从store中取出数据return this.$store.state.list}},methods : {deletePlan(idx) {// 稍后再来说这里的方法// 减去总时间this.$store.dispatch('decTotalTime',this.plans[idx].totalTime)// 删除该计划this.$store.dispatch('deletePlan',idx)}}}[removed]复制代码

别忘了为我们的组件写上一些需要的样式

// src/components/TimeEntries.vue复制代码

既然我们的数据是共享的,所以我们需要把数据存在store

我们在src下创建个目录为store

store下分别创建4个js文件actions.js,index.js,mutation-types.js,mutations.js

看名字也就知道这4个分别是做啥用的了,建议大家多阅读阅读vuex的文档,多姿势多动手实践,慢慢的也就能理解了。

// src/store/index.jsimport Vue from 'vue'import Vuex from 'vuex'Vue.use(Vuex);// 先写个假数据const state = {totalTime: 0,list: [{name : '二哲',avatar : 'https://sfault-avatar.b0.upaiyun.com/147/223/147223148-573297d0913c5_huge256',date : '2016-12-25',totalTime : '6',comment : '12月25日晚上,陪女朋友一起过圣诞节需要6个小时'}]};export default new Vuex.Store({state,})复制代码

由于新增了页面和store 在我们的入口js文件里配置下

// src/main.jsimport store from './store'import TimeEntries from './components/TimeEntries.vue'//... const routes = [{path : '/',component : Home},{path : '/home',component : Home},{path : '/time-entries',component : TimeEntries,}];var app = new Vue({el: '#app',router,store,...App,});复制代码

不出意外的话,你可以在/time-entries 路由下看见这样的页面


通过vue-Devtools我们可以发现我们的store已经构造好了并且成功从store获取了数据

创建任务组件

这个比较简单我们直接给出代码

// src/components/LogTime.vue[removed]export default {name : 'LogTime',data() {return {date : '',totalTime : '',comment : ''}},methods:{save() {const plan = {name : '二哲',image : 'https://sfault-avatar.b0.upaiyun.com/888/223/888223038-5646dbc28d530_huge256',date : this.date,totalTime : this.totalTime,comment : this.comment};this.$store.dispatch('savePlan', plan)this.$store.dispatch('addTotalTime', this.totalTime)this.$router.go(-1)}}}[removed]复制代码

这个组件很简单就3个input输入而已,然后就两个按钮,保存我们就把数据push进我们store的列表里

LogTime属于我们TimeEntries组件的一个子路由,所以我们依旧需要配置下我们的路由,并且利用webpack让它懒加载,减少我们首屏加载的流量

// src/main.js//...const routes = [{path : '/',component : Home},{path : '/home',component : Home},{path : '/time-entries',component : TimeEntries,children : [{path : 'log-time',// 懒加载component : resolve => require(['./components/LogTime.vue'],resolve),}]}];//...复制代码

vuex部分

在vue2.0中废除了使用事件的方式进行通信,所以在小项目中我们可以使用Event Bus,其余最好都使用vuex,本文我们使用Vuex来实现数据通信

相信你刚刚已经看见了我写了很多this.$store.dispatch('savePlan', plan) 类似这样的代码,我们再次统一说明。

仔细思考一下,我们需要两个全局数据,一个为所有计划的总时间,一个是计划列表的数组。

src/store/index.js 没啥太多可介绍的,其实就是传入我们的state,mutations,actions来初始化我们的Store。如果有需要的话我们还可能需要创建我们的getter在本例中就不用了。

接着我们看mutation-types.js,既然想很明确了解数据,那就应该有什么样的操作看起,当然这也看个人口味哈

// src/store/mutation-types.js// 增加总时间或者减少总时间export const ADD_TOTAL_TIME = 'ADD_TOTAL_TIME';export const DEC_TOTAL_TIME = 'DEC_TOTAL_TIME';// 新增和删除一条计划export const SAVE_PLAN = 'SAVE_PLAN';export const DELETE_PLAN = 'DELETE_PLAN';复制代码
// src/store/mutations.jsimport * as types from './mutation-types'export default {// 增加总时间[types.ADD_TOTAL_TIME] (state, time) {state.totalTime = state.totalTime + time},// 减少总时间[types.DEC_TOTAL_TIME] (state, time) {state.totalTime = state.totalTime - time},// 新增计划[types.SAVE_PLAN] (state, plan) {// 设置默认值,未来我们可以做登入直接读取昵称和头像const avatar = 'https://sfault-avatar.b0.upaiyun.com/147/223/147223148-573297d0913c5_huge256';state.list.push(Object.assign({ name: '二哲', avatar: avatar }, plan))},// 删除某计划[types.DELETE_PLAN] (state, idx) {state.list.splice(idx, 1);}};复制代码

最后对应看我们的actions就很明白了

// src/store/actions.jsimport * as types from './mutation-types'export default {addTotalTime({ commit }, time) {commit(types.ADD_TOTAL_TIME, time)},decTotalTime({ commit }, time) {commit(types.DEC_TOTAL_TIME, time)},savePlan({ commit }, plan) {commit(types.SAVE_PLAN, plan);},deletePlan({ commit }, plan) {commit(types.DELETE_PLAN, plan)}};复制代码

我们的actions其实就是去触发事件和传入参数啦

加了这三个文件后我们的store终于完整了,更新下我们的代码

// src/store/index.js 完整代码import Vue from 'vue'import Vuex from 'vuex'import mutations from './mutations'import actions from './actions'Vue.use(Vuex);const state = {totalTime: 0,list: []};export default new Vuex.Store({state,mutations,actions})复制代码

this.$store.dispatch('savePlan', plan)当执行了这样的方法就会调用actions.js里的savePlan方法,而savePlan又会触发 mutations里的 types.SAVE_PLAN 最后修改数据视图更新

PS:在这有个技巧就是,在mutations里都是用大写下划线连接,而我们的actions里都用小写驼峰对应。

个人理解这其实就是一个发布订阅的模式

mutation-types 记录我们所有的事件名

mutations 注册我们各种数据变化的方法

actions 则可以编写异步的逻辑或者是一些逻辑,再去commit
我们的事件

如果有getter 我们可以把一些需要处理返回的数据放在这即可,不进行业务操作

最后别忘了在我们的main.js里使用我们的store

// src/store/main.jsimport store from './store'// ...var app = new Vue({el: '#app',router,store,...App,});复制代码

开始体验下你自己的任务计划板吧!

最后

通过本文,我们可以学习到许多关于vue的特性。

1.了解了vue-cli脚手架

2.初步对webpack有了一些了解和认识

3.如何用.vue愉快的开发

4.使用vuex进行组件通信

5.路由(子路由)的应用

6.使用 vue-devtools 观察我们的数据


相关问题推荐

  • 回答 2

    Statement的execute(String query)方法用来执行任意的SQL查询,如果查询的结果是一个ResultSet,这个方法就返回true。如果结果不是ResultSet,比如insert或者update查询,它就会返回false。我们可以通过它的getResultSet方法来获取ResultSet,或者通过getUpda...

  • 回答 22

    忙的时候项目期肯定要加班 但是每天加班应该还不至于

  • 回答 108
    已采纳

    虽然Java人才越来越多,但是人才缺口也是很大的,我国对JAVA工程师的需求是所有软件工程师当中需求大的,达到全部需求量的60%-70%,所以Java市场在短时间内不可能饱和。其次,Java市场不断变化,人才需求也会不断增加。马云说过,未来的制造业要的不是石油,...

  • 回答 5
    已采纳

    工信部证书含金量较高。工信部是国务院的下属结构,具有发放资质、证书的资格。其所发放的证书具有较强的权威性,在全国范围内收到认可,含金量通常都比较高。 工信部证书,其含义也就是工信部颁发并承认的某项技能证书,是具有法律效力的,并且是国家认可的...

  • 回答 70
    已采纳

    学Java好不好找工作?看学完Java后能做些什么吧。一、大数据技术Hadoop以及其他大数据处理技术都是用Java或者其他,例如Apache的基于Java 的 HBase和Accumulo以及ElasticSearchas。但是Java在此领域并未占太大空间,但只要Hadoop和ElasticSearchas能够成长壮...

  • 回答 16
    已采纳

    就是java的基础知识啊,比如Java 集合框架;Java 多线程;线程的五种状态;Java 虚拟机;MySQL (InnoDB);Spring 相关;计算机网络;MQ 消息队列诸如此类

  • 回答 12

    #{}和${}这两个语法是为了动态传递参数而存在的,是Mybatis实现动态SQL的基础,总体上他们的作用是一致的(为了动态传参),但是在编译过程、是否自动加单引号、安全性、使用场景等方面有很多不同,下面详细比较两者间的区别:1.#{} 是 占位符 :动态解析 ...

  • 回答 62

    没问题的,专科学历也能学习Java开发的,主要看自己感不感兴趣,只要认真学,市面上的培训机构不少都是零基础课程,能跟得上,或是自己先找些资料学习一下。

  • 回答 4

    1、反射对单例模式的破坏采用反射的方式另辟蹊径实例了该类,导致程序中会存在不止一个实例。解决方案其思想就是采用一个全局变量,来标记是否已经实例化过了,如果已经实例化过了,第 二次实例化的时候,抛出异常2、clone()对单例模式的破坏当需要实现单例的...

  • 回答 5

     优点: 一、实例控制  单例模式会阻止其他对象实例化其自己的单例对象的副本,从而确保所有对象都访问唯一实例。 二、灵活性  因为类控制了实例化过程,所以类可以灵活更改实例化过程。 缺点: 一、开销  虽然数量很少,但如果每次对象请求引用时都要...

  • 回答 4

    这个主要是看你数组的长度是多少, 比如之前写过的一个程序有个数组存的是各个客户端的ip地址:string clientIp[4]={XXX, xxx, xxx, xxx};这个时候如果想把hash值对应到上面四个地址的话,就应该对4取余,这个时候p就应该为4...

  • 回答 6

     哈希表的大小 · 关键字的分布情况 · 记录的查找频率 1.直接寻址法:取关键字或关键字的某个线性函数值为散列地址。即H(key)=key或H(key) = a·key + b,其中a和b为常数(这种散列函数叫做自身函数)。...

  • 回答 6

    哈希表的大小取决于一组质数,原因是在hash函数中,你要用这些质数来做模运算(%)。而分析发现,如果不是用质数来做模运算的话,很多生活中的数据分布,会集中在某些点上。所以这里最后采用了质数做模的除数。 因为用质数做了模的除数,自然存储空间的大小也用质数了...

  • 回答 2

    是啊,哈希函数的设计至关重要,好的哈希函数会尽可能地保证计算简单和散列地址分布均匀,但是,我们需要清楚的是,数组是一块连续的固定长度的内存空间

  • 回答 3

     解码查表优化算法,seo优化

  • 回答 5

    1.对对象元素中的关键字(对象中的特有数据),进行哈希算法的运算,并得出一个具体的算法值,这个值 称为哈希值。2.哈希值就是这个元素的位置。3.如果哈希值出现冲突,再次判断这个关键字对应的对象是否相同。如果对象相同,就不存储,因为元素重复。如果对象不同,就...

没有解决我的问题,去提问