JavaScript 풀스택 튜토리얼을 직접 살펴보세요

coldplay.xixi
풀어 주다: 2020-06-16 17:01:03
앞으로
2618명이 탐색했습니다.

JavaScript 풀스택 튜토리얼을 직접 살펴보세요

1년 전에 Vuejs 전자책이 출시된 이후로 며칠 동안 손을 대지 못했습니다. 이제 프로젝트 때문에 JavaScript 풀스택 개발을 사용해야 합니다. 그러므로 이 풀스택 환경을 구축해야 합니다.

전체 시리즈는 천천히 천천히 이야기하는 저의 일관된 스타일을 채택할 것입니다. 학습한 후에는 제가 언급한 전체 시리즈의 지식을 습득하고 직접 복사할 수 있는 코드 템플릿을 얻을 수 있으며, 프로젝트.

프런트엔드의 복잡성

많은 사람들이 JavaScript 개발을 무시합니다. 이것은 단지 장난감일 뿐이고 스크립트와 태그 몇 개만 있으면 됩니다. 이렇게 말할 때 그들은 다리를 꼬거나 팔을 껴안을 수도 있습니다.

하지만 아직 프론트엔드가 빠르게 발전하고 있기 때문에 환경을 구축하는데 있어서 선택의 여지도 많고, 스스로 해야 할 일도 많습니다. 그래서 실제로는 그렇게 간단하지 않습니다. 이 기사의 그림을 통해 프런트 엔드의 복잡성을 엿볼 수 있습니다. 2018년 최신 프론트엔드 개발자.

많은 정보를 읽었으며 그 중 많은 정보가 이 그림의 기술 중 하나를 설명하고 있습니다. 풀 스택을 설명하는 정보도 있겠지만 너무 복잡한 경우가 많습니다. 이 기사는 일련의 기사를 통해 JavaScript의 전체 스택 개발을 파노라마로 보여주려고 시도하며 초보자가 기술을 빠르게 이해할 수 있도록 전체 시리즈를 진행합니다.

개요

따라서 기사에는 다음이 포함됩니다.

  1. Vuejs 스캐폴딩을 사용하여 CRD 사용자 인터페이스를 빠르게 구축하세요. vuex를 사용하여 상태를 관리하고 vue-router를 사용하여 라우팅을 관리합니다.
  2. Mongodb를 사용하여 백엔드 CRD 서비스를 저장하고 제공하세요.
  3. Nodejs를 사용하여 백엔드 CRD 서비스를 구축하세요.
  4. Fecth|Axios를 사용하여 백엔드 CRD 서비스에 액세스
  5. bulfy의 구성 요소 미화 방법 사용
  6. 풀 스택 서비스 통합

CRD는 생성, 읽기 및 삭제를 의미합니다. 대상 데이터 개체는 다음과 같은 Todo 개체입니다.

{id:1,subject:"Loving"}

여러 데이터 개체인 경우 다음과 같습니다.

[
  {id:1,subject:"Loving"},
  {id:1,subject:"Writing"},
  {id:1,subject:"Preying"}
]
로그인 후 복사

이 JS 개체는 기능, 모듈 및 개체 집합 사이는 물론, 네트워크 경계를 넘어 메모리에서 하드 디스크까지 간단하고 평범한 흐름을 보입니다. Mongodb에 저장되고 Mongodb에서도 추출되어 사용자 인터페이스, HTTP 클라이언트 및 HTTP 서버로 전달됩니다.

앱 전체가 기계처럼 보입니다. 코드가 기계를 구동한다고 할 수도 있지만, 데이터가 기계를 구동한다고도 할 수 있습니다.

Vuejs 스캐폴딩을 사용하여 Todo 앱 인터페이스를 빠르게 구축하세요

우리는 TODO 애플리케이션을 만들자고 제안했습니다. 다음과 같습니다.

JavaScript 풀스택 튜토리얼을 직접 살펴보세요

사용자는 편집 상자와 목록을 볼 수 있습니다.

  1. 편집 상자에 새 할일 프로젝트를 추가하고 Enter를 눌러 목록에 추가하세요
  2. 목록의 각 프로젝트에는 버튼을 클릭하여 현재 프로젝트를 삭제하세요

환경 요구 사항

빌드에 대해 말하자면. JS 풀스택 개발 환경에는 많은 것들이 포함됩니다. 큰 선택은 다음과 같습니다:

  1. Vuejs는 프런트 엔드에 사용됩니다
  2. Nodejs는 백엔드에 사용됩니다
  3. Mongodb는 저장에 사용됩니다.

큰 선택이 이루어지면 작은 패키지는 일련의 기술, 특히 Vuejs에 해당하고 라우팅, 상태 및 구성 요소를 관리하기 위한 해당 기술 수단이 있는 프런트 엔드가 필요합니다. 직접 맞추는 것은 여전히 ​​​​매우 번거롭습니다.

다행히 Vuejs에는 위의 구성 요소를 프로젝트에 통합할 수 있는 프런트 엔드 스캐폴딩 도구 vue-cli도 있습니다. 가장 기본적인 vue-cli 프로젝트 스캐폴딩을 생성하려면 이제 약 160M의 공간이 필요합니다. 내 컴퓨터와 네트워크에서는 완료하는 데 2분 30초가 걸립니다.

前端 Vuejs

  1. vue-router,前端路由管理
  2. vuex,前端数据管理,专业一点的说法,就是状态管理,这些数据,可能是属性,数组,对象等等,可以跨组件访问,而不像是data函数那样提供的数据只能被本组件访问,可以想到,稍微大一点的前端工程都必须前端状态管理的。
  3. axios,前端HTTP访问,以promise的形式,封装了类似fetch,AJAX的能力
  4. buefy,前端微型框架,可以使用自定义标签使用自定义组件,并且CSS框架为Bulma
  5. Bulma,尽管使用了微框架,只是让对CSS framework的了解降到最低,但是不是说就不需要了解了。还是得学习的。Bulma相对于老牌的Bootstrap,是不需要依赖于JS框架,也没有任何JS代码,因此可以和任何一框架很好的结合,比如这里的Vuejs。这就是我选择它的原因

后端 cli-service

为了给前端开发提供工具链和开发便利性,我们常常需要webpack&babel。有了它们,就可以使用ES6的语法,以及代码更新后自动刷新等。这些都是非常便利的特性,用了就离不开的。有了vue-cli,对webpack&babel的了解可以降到最低,但是也不能不学,稍微需要一些定制的配置,也是必须要掌握的,起码得知道如何启动一个开发服务器,已经发布build,还有把前端服务经过proxyChain跳转到后端服务去等等。所幸是在这个教程内,你不需要学习太多就可以把案例跑起来。

App Server + Mongodb

接下来看后端,一般习惯就是使用Nodejs+Express.js的搭配。这个没有多少说的,都是老东西了。为了访问Mongodb,也需要一套框架,基于Callback的,或者基于Promise+Await+Async的,也是需要选择的。

为了便于理解,我会用一个最小的案例完成整个开发过程,就是案例在现实中并不存在,但是也是有用的,就是你可以当它们是模板,直接拷贝代码,然后填充你的内容。天下代码一大抄嘛,没有什么不对的,毕竟这些写代码是最快的。这个案例的数据模型就是对一个{id,name}的对象进行CRD(创建删除列表)。

安装运行环境

安装环境相对简单,特别是如果使用Mac OS X的话。有一些工具链可以帮助快速搭建环境。当然Windows也并不多麻烦就是了,它常常提供的是一个安装程序,大部分时间,你需要的就是点击下一步。

这里以MAC为例,讲解安装。

mongodb

安装和运行Mongodb Daemon:

brew install mongodb
mongodb
로그인 후 복사
로그인 후 복사

   

访问验证,首先执行Mongodb Shell:

mongo
로그인 후 복사
로그인 후 복사

   

输入命令,查询数据库清单:

> show dbs
local           0.000GB
로그인 후 복사
로그인 후 복사

   

能够看到这些信息,说明mongodb安装成功。

Node.js

安装并验证:

$brew install nodejs
$node -v
10.7.0
로그인 후 복사

   

能够看到这些信息,说明Node.js安装成功。

开始前端编码

安装编码环境

首先安装vue-cli,方法和一般的NPM模块一样的,我们安装的版本是3.0:

npm i @vue/cli
로그인 후 복사

   

查看版本:

vue -V
3.0.0
로그인 후 복사

   

看到如下信息,说明成功。然后创建App的脚手架代码:

vue create todoapp
로그인 후 복사

   

注意,在此创建过程中,命令行会指示你做出选择,我们会选择Manual select feature,然后选择router和vuex,其他不选。然后并执行此代码:

cd todoapp
npm run serve
로그인 후 복사

   

可以在浏览器中访问localhost:8080看到Vue的启动画面。说明创建脚手架成功。

此时,vue-cli已经帮助安装了vuex和router的模块依赖。本节一次性的安装全部剩余的全部NPM依赖,免得以后用一个安装一个,麻烦而且啰嗦。

  npm install buefy --save
npm install axios --save
로그인 후 복사

   

buefy是一个基于Bulma的Vuejs用户界面组件库。这次的UI的CSS方案,使用Bulma,Vuejs如果想要以定制组件的形式去使用它的话,那么需要安装Buefy模块。实际上,我研究过Bulma和 Bootstrap,还写了一本免费的电子书,我觉得Bulma相对于Bootstrap的优势在于1.不依赖任何JS框架2.用户接口设计更加简明。这就是我现在选择使用Bulma的原因。

Axios是一个封装了HTTPClient的库,提供了promise接口。我们使用它访问后端的HTTP Server的数据。之前提到的数据对象,就是由Axios提取到客户端,也会是通过Axios把数据对象提交到服务器的。

前端编码

首先,我们从状态开始。我们之前提到的Vuex,是Vuejs管理状态的官方插件。所谓的状态,就是应用程序的数据对象们。也就是我们提到的Todo对象和Todo对象集合。我们在App用户界面上看到的很多数据都是来自于状态对象。状态对象在src/store.js。不仅仅是的应用状态信息,还有和对这些的操作函数。既然需要一个todo项目清单,因此应该加入如下代码:

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const defaultTodo = [
      {id:1,subject:'Eating'},
      {id:2,subject:'Loving'},
      {id:3,subject:'Preying'},
    ]
function indexById(todos,id){
  for (var i = 0; i  {
      context.commit("JavaScript 풀스택 튜토리얼을 직접 살펴보세요d", link)
    },
    remove: (context, link) => {
      context.commit("remove", link)
    },
    reloJavaScript 풀스택 튜토리얼을 직접 살펴보세요: (context) => {
      context.commit("reloJavaScript 풀스택 튜토리얼을 직접 살펴보세요")
    }
  }
})
로그인 후 복사

   

其中的state.todos属性,就是我们的主要的数据对象了。state.msg这是提供了一个App的标题字符串。mutations属性内是对数据修改提供的方法,比如

  1. 我们需要添加一个todo,使用JavaScript 풀스택 튜토리얼을 직접 살펴보세요d()方法,相应的
  2. 删除一个todo,使用remove()方法
  3. 刷新一个todo列表,就会使用loJavaScript 풀스택 튜토리얼을 직접 살펴보세요()方法

有时候,对数据的修改可能是比较消耗时间的,因此为了避免阻塞客户端的主线程,这个对象也提供了异步的方法,actions对象内就是对应修改操作的异步方法,这里的方法功能上和mutations一致,但是是异步的。Vuex提供了类似:

context.commit()
로그인 후 복사

   

的语法,提供和actions和mutations方法的对接。第一个参数是mutations的方法名称,之后的参数最为mutations方法的参数传递给mutations方法。

特别说下,mutations内的JavaScript 풀스택 튜토리얼을 직접 살펴보세요d()方法,其中用户界面会提供一个Todo.subject属性,而ID是需要自动生成的,我们这里临时使用subject的值作为id,就是一个偷懒,只要subject不要输入重复,也暂时可以蒙混过关。因为知道本项目内的后台存储会采用Mongodb,在Mongodb内插入一个新的对象后,会自动生成一个ID,我们的Todo对象的id会采用这个ID。这里就没有必要自己生成了。

在src/views/home.vue内,粘贴为如下代码:

<template>
  <p>
    </p>
<h1>{{msg}}</h1>
    <newtodo></newtodo>
    <todolist></todolist>
  
</template>
<script>
import NewTodo from &#39;@/components/NewTodo.vue&#39;
import TodoList from &#39;@/components/TodoList.vue&#39;
import {mapState,mapActions} from &#39;vuex&#39;
export default {
  name: &#39;home&#39;,
  computed:mapState([&#39;todos&#39;,&#39;msg&#39;]),
  components: {
    TodoList,NewTodo
  },
  data(){
      return{newtodo:&#39;&#39;}
  },
  methods:{
      ...mapActions([
      &#39;remove&#39;,
      &#39;JavaScript 풀스택 튜토리얼을 직접 살펴보세요d&#39;
    ]),
      JavaScript 풀스택 튜토리얼을 직접 살펴보세요d1:function(){
          this.JavaScript 풀스택 튜토리얼을 직접 살펴보세요d(this.newtodo)
          this.newtodo = &#39;&#39;
      }
  }
}
</script>
로그인 후 복사

   

...mapState,mapActions的解说。

就是说,我们这个Todo App划分为为两个组件,其中一个组件负责显示编辑框,并接受回车事件,把新的Todo项目加入到应用状态内。另外一个组件负责显示全部Todo项目,并接受删除事件,删除指定的Todo项目。它们分别是NewTodo组件和TodoList组件:

<newtodo></newtodo>
<todolist></todolist>
로그인 후 복사

   

这两个组件的代码实现,分别在文件src/components/NewTodo.vuesrc/components/TodoList.vue内。NewTodo代码:

<template>
  <p>
    </p>
<form>
        <input>
    </form>
  
</template>
<script>
import {mapState,mapActions} from &#39;vuex&#39;
export default {
  name: &#39;newtodo&#39;,
  computed:mapState([&#39;todos&#39;,&#39;msg&#39;]),
  data(){
      return{newtodo:&#39;&#39;}
  },
  methods:{
      ...mapActions([
      &#39;JavaScript 풀스택 튜토리얼을 직접 살펴보세요d&#39;
    ]),
      JavaScript 풀스택 튜토리얼을 직접 살펴보세요d1:function(){
          this.JavaScript 풀스택 튜토리얼을 직접 살펴보세요d(this.newtodo)
          this.newtodo = &#39;&#39;
      }
  }
}
</script>
로그인 후 복사

   

TodoList代码:

<template>
  <p>
    </p>
<ul>
      <li>
        {{todo.subject}}<button>remove</button>
      </li>
    </ul>
  
</template>
<script>
import {mapState,mapActions} from &#39;vuex&#39;
export default {
  name: &#39;todolist&#39;,
  computed:mapState([&#39;todos&#39;,&#39;msg&#39;]),
  components: {
  },
  methods:{
    ...mapActions([
      &#39;remove&#39;,&#39;reloJavaScript 풀스택 튜토리얼을 직접 살펴보세요&#39;
    ])
  },
  mounted(){
    this.reloJavaScript 풀스택 튜토리얼을 직접 살펴보세요()
  }
}
</script>
<style>
</style>
로그인 후 복사

   

在src/main.js文件内,添加如下代码,引入Buefy:

import Buefy from 'buefy'
import 'buefy/lib/buefy.css'
Vue.use(Buefy)
로그인 후 복사

   

现在可以使用Buefy组件了。我们可以把NewTodo组件内的标准的input变成组件化的input,把标签换成b-input即可。代码如下:

<b-input></b-input>
로그인 후 복사

   

现在看浏览器,input变成了比较有吸引力的Bulma风格的控件了。访问网络使用axios。需要首先找到src/home.vue在代码的开头部分引用此库:

import axios from 'axios'
로그인 후 복사

   

在Vue单页组件内使用此库了。比如在src/home.vue内代码对象中加入新方法:

mounted(){
  var url  = 'https://api.coindesk.com/v1/bpi/currentprice.json'
  axios ({
        url:url,
        method: 'get',
    })
    .then( res => {console.log(res.data.chartName)} )
    .catch( err => cosole.error(err))
}
로그인 후 복사

   

我们来看看适应效果。启动cli-service:

npm run serve
로그인 후 복사

   

然后打开浏览器,输入地址localhost:8080,如果可以在浏览器内看到我们期望的用户界面,并且都可以看到console打印了Bitcoin,那么就说明用户界面代码和初步的访问HTTP网络的axios代码以及状态管理功能都是成功了的。

后端编码

现在,我们已经可以看到UI了,但是用户界面内的数据来自于客户端,而不是来自于服务器。我们的数据当然应该来源于服务器的了。因此我们需要启动给一个自己的服务器,这个服务器可以接受客户在界面上录入的新的Todo对象,也可以提供后端数据库内的Todo清单。

为了测试的目的,常常需要准备一个todo应用的后台JSON服务,可以通过HTTP方式,提供todo项目的增加删除修改和查询。

这样的服务器,使用了nodejs作为服务器端,并且使用了两个node模块,可以使用npm安装它们:

npm install express body-parser

body-parser是一个中间件,可以解析请求内容并把解析结果放到req.body属性内。最常见的做法就是解析json内容。

代码如下(文件名为:jsonserver.js):

  var express = require('express');
  var app = express();
  var path = require('path')
  var bodyParser = require('body-parser')
  app.use(bodyParser.json())
  var todos = []
  var public = path.join(__dirname, '/')
  app.use('/',express.static(public))
  const defaultTodo = [
    {id:1,subject:'Eating'},
    {id:2,subject:'Loving'},
    {id:3,subject:'Preying'},
  ]
  function rs(){
    todos = defaultTodo
  }
  function indexById(id){
    for (var i = 0; i <p>   </p><p>可以使用命令执行:</p><p>node jsonserver.js</p><h2 data-id="heJavaScript 풀스택 튜토리얼을 직접 살펴보세요ing-14">Curl命令验证</h2><p>可以通过curl命令验证服务的有效性:</p><ol>
<li>
<p>GET操作</p>
<pre class="brush:php;toolbar:false"> $curl http://localhost:8081/todo/1
 $curl http://localhost:8081/todos
로그인 후 복사
  • DELETE操作

      $ curl -X "DELETE" http://localhost:8081/api/todo/1
    로그인 후 복사
  • POST操作

    $curl -X POST  -H "Content-Type: application/json" -d '{"subject":"s4"}' http://localhost:8081/api/todo
    로그인 후 복사
  • 前端HTML验证

    创建一个index.html文件,并放置到和jsonserver.js代码同一目录,代码如下:

    <a>todos</a>
    <a>todo/1</a>
    <button>remove 1</button>
    <button>create</button>
    <script>
      function remove(){
        fetch (
          &#39;/api/todo/1&#39;,
          {
            method: &#39;DELETE&#39;,
          }
        )
        .then( res => console.log(res.json()))
        .catch( err => cosole.error(err))
      }
      function create(){
        fetch (
          &#39;/api/todo&#39;,
          {
            method: &#39;POST&#39;,
            heJavaScript 풀스택 튜토리얼을 직접 살펴보세요ers: {
              &#39;Content-Type&#39;: &#39;application/json&#39;
            },
            body: JSON.stringify({id: "4", subject: "s4"})
          }
        )
        .then( res => console.log(res.json()))
        .catch( err => cosole.error(err))
      }
    </script>
    로그인 후 복사

       

    可以提供创建,删除,列表的测试,其中部分结果在console内显示。

    说起来,JS访问HTTP的库真的是不少,这里 提到的库都有9种。其中的fetch api使用起来非常的简洁趁手,可是它不支持IE。如果你需要支持IE的话,使用Axios更好。这就是为什么Vuejs官方推荐Axios的原因吧:

    The Fetch API is a powerful native API for these types of requests. You may have heard that one of the benefits of the Fetch API is that you don’t need to loJavaScript 풀스택 튜토리얼을 직접 살펴보세요 an external resource in order to use it, which is true! Except… that it’s not fully supported yet, so you will still need to use a polyfill. There are also some gotchas when working with this API, which is why many prefer to use axios for now. This may very well change in the future though.
    로그인 후 복사

       

    axios访问方法

    相比fetch,使用axios必须依赖于外部文件。为了方便,我们直接使用unpkg网站提供的库文件。

    axios的语法和fetch的大同小异,看着也是比较简洁美观的。以下代码,把create和remove函数的内部实现换掉,其他不变。

    <script></script>
    <a>todos</a>
    <a>todo/1</a>
    <button>remove 1</button>
    <button>create</button>
    <script>
      function remove(){
        axios ({
            url:&#39;/api/todo/1&#39;,
            method: &#39;DELETE&#39;,
        })
        .then( res => console.log(res.json()))
        .catch( err => cosole.error(err))
      }
      function create(){
        axios ({
            method: &#39;POST&#39;,
            url:&#39;/api/todo&#39;,
            heJavaScript 풀스택 튜토리얼을 직접 살펴보세요ers: {
              &#39;Content-Type&#39;: &#39;application/json&#39;
            },
            data: JSON.stringify({subject: "s4"})
        })
        .then( res => console.log(res.json()))
        .catch( err => cosole.error(err))
      }
    </script>
    로그인 후 복사

       

    现在,后端也是可以跑起来了的。

    整合:前端后端

    建立cli-service到App Server的通道

    每次执行命令:npm run serve,都会启动vue定制脚手架的服务器代码,它会提供不少方便开发的特性。但是我希望一部分URL可以转发到我自己的服务器内。比如把所有的/api打头的URL全部转过来。只要在工程根目录内加入此文件vue.config.js,录入如下内容:

    module.exports = {
      devServer: {
        proxy: {
          "/api": {
            target: "http://localhost:8181",
            secure: false
          }
        }
      }
    };
    로그인 후 복사

       

    我们自己的测试服务器在这里:

    var http = require('http');
    http.createServer(function (req, res) {
      res.write('Hello World!'); 
      res.end(); 
    }).listen(8181);
    로그인 후 복사

       

    我们的定制服务器,就可以监听8181的本地机器端口,等待客户端的匹配的URL转发过来,并转发我们服务器的响应代码到客户端。

    但是正常开发过程中,是需要自己的服务器端代码的,如何在利用Vue脚手架服务器的方便性的基础上,加入自己的代码呢。做法是另外做一个定制的服务器,然后让vue定制脚手架的服务器转发URL到此服务器。

    为了测试的目的,我们把函数mounted修改为:

    mounted(){
      var url  = '/api/1'
      axios ({
            url:url,
            method: 'get',
        })
        .then( res => {console.log(res.data)} )
        .catch( err => console.error(err))
    }
    로그인 후 복사

       

    即可看到浏览器console内打印Hello World!

    整合前端到后端

    我们已经通过配置,要求cli-service转移全部api打头的URL到App Server。只要在工程根目录内加入此文件vue.config.js,录入如下内容:

    module.exports = {
      devServer: {
        proxy: {
          "/api/*": {
            target: "http://localhost:8181/api",
            secure: false
          }
        }
      }
    };
    로그인 후 복사

       

    现在,我们可以修改前端的Axios使用代码,分别替代前端代码的数据装入、数据删除、数据添加的代码,让这些代码可以支持网络操作。为了避免网络操作代码和业务逻辑代码混合在一起,我决定包装三个网络操作函数,并把它们放置到src/store.js文件内:

    import axios from 'axios'
    function httpJavaScript 풀스택 튜토리얼을 직접 살펴보세요d(subject,cb){
      axios ({
            method: 'POST',
            url:'/api/todo',
            heJavaScript 풀스택 튜토리얼을 직접 살펴보세요ers:[{'Content-Type':'application/json'}],
            data: {subject:subject}
          })
          .then( res => cb(res.data))
          .catch( err => console.error(err))
    }
    function httpremove(id,cb){
      axios ({
            url:'/api/todo/'+id,
            method: 'delete',
          })
          .then( res => {
              cb()
          })
          .catch( err => console.error(err))
    }
    function httpreloJavaScript 풀스택 튜토리얼을 직접 살펴보세요(cb){
      axios ({
            url:'/api/todos',
            method: 'get',
          })
          .then( res => {
              cb(res.data)
          })
          .catch( err => console.error(err))
    }
    로그인 후 복사

       

    分别完成添加、删除、查找的任务,当完成工作后,都会调用一个callback函数,在此函数内,可以消费访问网络后得到的响应数据。

    然后把文件内src/store.js的mutations对象改成如下代码:

     mutations: {
      JavaScript 풀스택 튜토리얼을 직접 살펴보세요d(state,subject){
        httpJavaScript 풀스택 튜토리얼을 직접 살펴보세요d(subject,function(todo){
          state.todos.push(todo)
        })
      },
      remove(state,id){
        httpremove(id,function(){
          state.todos.splice(indexById(state.todos,id),1)  
        })
      },
      reloJavaScript 풀스택 튜토리얼을 직접 살펴보세요(state){
        httpreloJavaScript 풀스택 튜토리얼을 직접 살펴보세요(function(todos){
          // console.log(todos)
          state.todos = todos
        })
        // state.todos = defaultTodo
      }
    },
    로그인 후 복사

       

    最后,在TodoList内加入一个新函数,并通过mapActions引入src/store.js的loJavaScript 풀스택 튜토리얼을 직접 살펴보세요()函数到当前对象内:

      methods:{
        ...mapActions([
          'remove','loJavaScript 풀스택 튜토리얼을 직접 살펴보세요'
        ])
      },
      mounted(){
        this.loJavaScript 풀스택 튜토리얼을 직접 살펴보세요()
      }
    로그인 후 복사

       

    以便在启动后调用this.loJavaScript 풀스택 튜토리얼을 직접 살펴보세요()装入它。

    整合:后端和数据库

    要完成后端到数据库的整合,需要做如下的修改:

    1. 原本在后端App Server内Todo数据数组,现在应该从Mongodb获得
    2. 原本在添加Todo对象的时候只是添加到AppServer对象内,现在需要同时写入Mongodb
    3. 原本在删除时只是从数组删除,现在需要同时在Mongodb内删除

    因此,现在我们需要添加三个函数,分别做针对Mongodb的获取清单、添加和删除的工作:

    var mongo = require('mongodb')
    function insertDoc(subject,callback){
      const connectionString = 'mongodb://localhost:27017';
      (async () => {
          const client = await MongoClient.connect(connectionString,
              { useNewUrlParser: true });
          const dbo = client.db('todos');
          try {
             var res = await dbo.collection('todo').insertOne(
              {subject:subject})
             callback(undefined,res.insertedId)
          }
          catch(err){
            callback(err)
          }
          finally {
              client.close();
          }
      })().catch(err => console.error(err));
    }
    function deleteDoc(_id,callback){
      const MongoClient = mongo.MongoClient;
      const connectionString = 'mongodb://localhost:27017';
      (async () => {
          const client = await MongoClient.connect(connectionString,
              { useNewUrlParser: true });
          const dbo = client.db('todos');
          try {
                  var myquery = {_id:new mongo.ObjectID(_id)}
                  var r = await dbo.collection("todo").deleteMany(myquery)
            }
            catch(err){
            callback(err)
          }
          finally {
                client.close();
                callback()
            }
      })().catch(err => console.error(err));
    }
    function allDoc(callback){
      const MongoClient = mongo.MongoClient;
      const connectionString = 'mongodb://localhost:27017';
      (async () => {
          const client = await MongoClient.connect(connectionString,
              { useNewUrlParser: true });
          const dbo = client.db('todos');
          try {
                 var r = await dbo.collection("todo").find().toArray()
                 var ts = []
                 for (var i = 0; i  console.error(err));
    }
    로그인 후 복사

       

    这三个函数的功能和使用方法如下:

    1. 函数allDoc会从Mongodb内获取全部todo集合,并通过callback传递这个集合给调用者函数。
    2. 函数deleteDoc会从Mongodb内删除指定id的todo条目,完成删除后,通过callback通知调用者。
    3. 函数deleteDoc会向Mongodb内添加一个todo条目,完成添加后,通过callback通知调用者,并传递新的todo对象给调用者。

    这里的代码本身并不复杂,但是因为涉及到如何访问Mongodb,因此涉及到比较多的概念,这里不做具体的解释,你可以先把它们用起来。如果完成了本教程后,希望对Mongodb的访问做具体了解的话,可以查看后文附录的“Mongodb快速参考”。

    并且和App Server对应的代码接驳,把原来的路由代码替换如下:

    app.delete('/api/todo/:id', function (req, res) {
      var userkey = req.params.id
      deleteDoc(userkey,function(){
        todos.splice(indexById(userkey),1)
        res.end( JSON.stringify(todos));
      })
    })
    app.get('/api/todos', function (req, res) {
      allDoc(function(err,todos){
        res.end( JSON.stringify(todos));  
      })
    })
    app.post('/api/todo', function (req, res) {
      insertDoc(req.body.subject,function(err,_id){
        var obj ={id:_id,subject:req.body.subject}
      todos.push(obj)
      res.end(JSON.stringify(obj))
        rs()
      })
    })
    로그인 후 복사

       

    Mongodb快速参考

    本文会把一个对象todo对象(有属性{id,name})存储到Mongodb,做查询删除的测试(Create Remove Delete = CRD)。这个测试包括使用Mongodb Shell,使用CallBack古典风格的访问代码,以及使用Await/Async的现代风格的代码。完成这个这个验证后,就可以掌握最初步的Mongodb了。

    我使用的Nodejs是10.7 。操作系统环境为Mac OS X High Sierra。

    准备环境

    安装和运行Mongodb Daemon

    brew install mongodb
    mongodb
    로그인 후 복사
    로그인 후 복사

       

    访问验证

    首先执行Mongodb Shell:

    mongo
    로그인 후 복사
    로그인 후 복사

       

    输入命令,查询数据库清单:

    > show dbs
    local           0.000GB
    로그인 후 복사
    로그인 후 복사

       

    创建一个数据库

    use todos
    로그인 후 복사

       

    (若database不存在,则会创建一个,此时若不做任何操作直接退出,则MongoDB会删除该数据库)

    db.todos.insert({id:1,name:"reco"})
    db.todos.insert({id:2,name:"rita"})
    로그인 후 복사

       

    查询 :

    db.todos.find()
    
    { "_id" : ObjectId("5b727c0846b6c71a98d3af52"), "id" : 1, "name" : "reco" }
    { "_id" : ObjectId("5b727c7046b6c71a98d3af53"), "id" : 2, "name" : "reta" }
    로그인 후 복사

       

    删除记录:

    db.todo.remove({id:1})
    로그인 후 복사

       

    删除数据库

    db.todo.drop()
    로그인 후 복사

       

    使用nodejs方式访问Mongodb

    使用nodejs执行类似Shell对对象的CRD,代码如下:

    var MongoClient = require('mongodb').MongoClient;
    var url = "mongodb://localhost:27017/todos";
    MongoClient.connect(url, function(err, db) {
      if (err) throw err;
      console.log("Database created!");
      var dbo = db.db("todos");
      // var myobj = { id: 1, name: "reco" };
      // dbo.collection("todo").insertOne(myobj, function(err, res) {
      //   if (err) throw err;
      //   console.log("1 document inserted");
      //   db.close();
      // });
       var myobj = [
        { id: 1, name: 'reco'},
        { id: 2, name: 'rita'},
      ];
      dbo.collection("todo").insertMany(myobj, function(err, res) {
        if (err) throw err;
        console.log("Number of documents inserted: " + res.insertedCount);
        dbo.collection("todo").find({}).toArray(function(err, result) {
          if (err) throw err;
          console.log(result);
            var myquery = { id: 1 };
          dbo.collection("todo").deleteMany(myquery, function(err, obj) {
            if (err) throw err;
            console.log("document deleted");
            db.close();
          });
        });    
      });
    })
    로그인 후 복사

       

    代码非常简单,无需更多解释。此代码使用了mongodb模块,需要首先安装:

    npm init -y
    npm i mongodb --save
    로그인 후 복사

       

    然后使用node index.js运行即可看到效果:

    Database created!
    Number of documents inserted: 2
    [ { _id: 5b72ab9e3245f169ef5f43d2, id: 1, name: 'reco' },
      { _id: 5b72ab9e3245f169ef5f43d3, id: 2, name: 'rita' } ]
    document deleted
    로그인 후 복사

       

    利用高级异步特性

    使用Await/Async特性,可以有效的减少代码中的回调地狱现象。同样的功能,可以使用这样的代码:

    const MongoClient = require('mongodb').MongoClient;
    const connectionString = 'mongodb://localhost:27017';
    (async () => {
        const client = await MongoClient.connect(connectionString,
            { useNewUrlParser: true });
        const dbo = client.db('todos');
        try {
           var res = await dbo.collection('todo').insertMany(
            [{id:1,name:"reco"}, {id:2,name:"rita"}]);
           console.log("Number of documents inserted: " + res.insertedCount);
           var r = await dbo.collection("todo").find().toArray()
           console.log(r);
           var myquery = { id: 1 };
         var r = await dbo.collection("todo").deleteMany(myquery)
         console.log("document deleted");
        }
        finally {
            client.close();
        }
    })().catch(err => console.error(err));
    로그인 후 복사

       

    执行此代码,输出如下:

    Number of documents inserted: 2
    [ { _id: 5b72ae8a1c674a6ac1c5aa6e, id: 1, name: 'reco' },
      { _id: 5b72ae8a1c674a6ac1c5aa6f, id: 2, name: 'rita' } ]
    document deleted
    로그인 후 복사

       

    Vuejs快速参考

    Vuejs本身要学的还真不少,这也是我会编写一本书来介绍它的原因。但是说到入门的话,我倒是写过一篇简单的介绍文章。不妨去阅读看看。

    上面的文章,也就对Vuejs了解个大概,提起一个兴趣。如果真的想要学习Vuejs的话,还是得看书的。这里也放一个我的书的广告,欢迎参阅。

    JavaScript 풀스택 튜토리얼을 직접 살펴보세요
    购买

    问题索引

    麻雀虽小五脏俱全,虽然是一个小小的示例的应用,但是每样技术也都需要用到,遇到的技术问题也是要一个个的解决的。这里列出我遇到的问题,作为索引,也算记录我在写作过程中解决的问题,也可以作为你学习完毕后的一个查漏补缺的索引,在这里重新看到问题,然后使用代码验证自己对问题的理解和学习。

    1. 使用Nodejs如何搭建一个RESTFUL的服务?
    • 如何把cli-service中来自客户端但是需要去应用服务器的URL访问转移到应用服务器?
    • 如何解析前端提交的Json?
    • 如何打包Json到响应内?
    • 如何创建一个唯一的ID?本来是用于创建一个唯一ID,这样就不必使用MongoDB生成的ObjectID了,因此插入效率会更高。但是,最后还是按惯例采用了Mongo的了。
    1. 如何加入新的单页组件?
    • 在哪里插入获取服务端数据的代码?
    1. 如何使用Buefy?
    • 在Vuejs应用中内使用Buefy?
    • 在Vuejs单页组件内使用Buefy?
    • 如何关闭input的自动完成特性?这个自动完成每次当你输入的时候,都会显示一个曾经的输入的列表,真的很烦。
    1. 如何在组件之间共享状态?
    • 为何需要共享前端状态?
    • 如何区别使用同步和异步状态操作?
    • 如何映射状态操作到组件内,以方便组件对方法的调用?
    1. 如何访问Mongo?
    • 如何安装Mongo,并快速验证Mongo?
    • 如何命令行插入、删除、列表一个Collection?
    • 有哪些访问Mongo的Nodejs库,差别在哪里?
    • 如何使用Await风格的代码做插入删除和列表?
    • 如何获取插入项目后的项目ID?
    • 如何使用ObjectId查询对应的项目?
    1. 如何访问网络,包括curl、axios、fetch等几种方法?
    • 如何提交Get请求?
    • 如何提交Put请求?
    • 如何在Body内提交json?
    • 如何指定请求头内容类型为json?
    • 如何获取响应中的Json数据?

    参考文章

    这个App虽然很小,但是并非一次写成的,我之前已经完成了若干个更加细小的、特定方面的文章,也写了一些代码。当然外部参考肯定也是不少,特别是Medium和Stack Overflow网站,对我支持很多。这里列出关键的一些参考文章。

    1. Vuex는 여기에서 상태를 관리하는 데 사용됩니다. Vuex가 무엇인지에 대한 기사를 이미 많이 읽었고 리뷰가 있습니다. 물론 제가 준 케이스들은 좀 꺼려지는데, 실제 케이스는 Vuex가 필요하지 않고 컴포넌트 내의 상태만 사용하는 것입니다.
    2. Mongodb를 사용하여 백엔드 CRD 서비스를 저장하고 제공합니다.
    3. Nodejs를 사용하여 {id, name} 개체에 대한 백엔드 CRD 서비스를 구축합니다. AJAX
    • JSON 서버 준비 및 액세스
    • vuejs API 서버 개발 치트 시트
    • serveraxios-put에 대한 Axios PUT 요청 -request -to-server
    1. Fecth|Axios를 사용하여 백엔드 CRD 서비스에 액세스하세요. 이 기사에서는 네트워크 라이브러리에 액세스하는 여러 가지 방법을 나열하고 글로벌 관점을 제공하므로 이점을 누릴 수 있습니다. [http 요청을 만들기 위한 Fetch 대 Axios.js

    ](medium.com/@thejasonf.…

    1. buefy를 사용하여 구성 요소를 아름답게 만드는 방법. 이것은 매우 틈새이므로 공식 문서만 볼 수 있습니다.

      추천 튜토리얼: "JavaScript 기본 튜토리얼"

    위 내용은 JavaScript 풀스택 튜토리얼을 직접 살펴보세요의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

    관련 라벨:
    원천:juejin.im
    본 웹사이트의 성명
    본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
    인기 튜토리얼
    더>
    최신 다운로드
    더>
    웹 효과
    웹사이트 소스 코드
    웹사이트 자료
    프론트엔드 템플릿