Following the previous two, below we achieve the right menu, HTTP communication, routing.

Js + Nuxt.js + Element + Vuex + open source JS drawing library, to create your own online drawing software, the final effect: topology.le5le.com. If you feel good, feel free to like the article and open source library, so that we are more motivated to do well!

Source code for this tutorial is Github

directory

  • Building a project framework, Tutorial 1
  • Vuex, Tutorial two
  • Right menu, tutorial three
  • HTTP communication, Tutorial three
  • Routing, Tutorial three

Right-click menu

The principle of the right menu is simple: customize the HTML onContextMenu event:

<div id="topology-canvas" class="full" @contextmenu="onContextMenu($event)"></div>
Copy the code

Shield the default right-click menu event, calculate the right mouse position, pop up a div custom menu can be our own

onContextMenu(event) {
      event.preventDefault()
      event.stopPropagation()

      if (event.clientY + 360 < document.body.clientHeight) {
        this.contextmenu = {
          left: event.clientX + 'px',
          top: event.clientY + 'px'
        }
      } else {
        this.contextmenu = {
          left: event.clientX + 'px',
          bottom: document.body.clientHeight - event.clientY + 'px'
        }
      }
    }
Copy the code
<div class="context-menu" V-if ="contextmenu.left" :style="this.contextmenu"> <ul> <li> <li>  </ul> </div>Copy the code

In this project, a right-click menu component “CanvasContextMenu” is encapsulated, passing the Canvas instance and selected property data through the parent component

 props: {
    canvas: {
      type: Object,
      require: true
    },
    props: {
      type: Object,
      require: true
    }
  }
Copy the code

Where, the props attribute means:

Functions: {node: null, // Check for nodes. Line: null, // Check for nodes: null, // Check for multiple nodes. Multi: false, // Check for multiple nodes. False // Whether the selected object is locked}Copy the code

Then, we call the corresponding canvas interface function based on menu events and properties props, refer to the development documentation

HTTP communication

Instead of writing a back-end service from scratch, we use topology.le5le.com online interface service.

Proxy configuration

First, we need to add the HTTP proxy configuration to nuxt.config.js so that HTTP requests in the development environment are automatically forwarded to topology.le5le.com to get real data.

 axios: {
    proxy: true
  },
  proxy: {
    '/api/': 'http://topology.le5le.com/',
    '/image/': 'http://topology.le5le.com/'
  },
Copy the code

Proxy indicates that all requests starting with/API/and /image/ are automatically forwarded to topology.le5le.com/. Other requests are not forwarded. Typically, we use the prefix/API/to indicate that this is a back-end interface request, not a static resource request; /image/ represents a static resource image request.

The user login

1. Add the user profile picture and nickname in the upper right corner

Since user information is not currently shared across multiple pages, add user data directly to the top navigation bar and data in layouts/ Default

data() { return { about: false, license: false, joinin: false, lineNames: ['curve', 'polyline', 'line'], arrowTypes: [ '', 'triangleSolid', 'triangle', 'diamondSolid', 'diamond', 'circleSolid', 'circle', 'line', 'lineUp', 'lineDown' ], user: null } } <el-submenu index="user" v-if="user"> <template slot="title"> <el-avatar src="https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png" :size="24" ></el-avatar> {{user.username}} </template> <el-menu-item @click="onSignOut"> Exit </el-menu-item> </el-submenu> <el-menu-item V-if ="! User "> < a @ click =" onLogin "> register/login < / a > < / el menu - item >Copy the code

Large projects may need to use VUEX to store user data

2. Log in

Here, we skip the login page and go directly to the online login page account.le5le.com to share the login status.

All subdomain names of LE5le.com share the login status of le5le.com by sharing the token in the cookie. First, we modify the host file on the local computer and add a subdomain local.le5le.com to the local computer:

127.0.0.1 local.le5le.com
Copy the code

How to modify the host file, please Google.

Then, we changed http://localhost:3000/ to local.le5le.com:3000/ to open our development page in the browser. At this point, we can click “Login/Register” in the upper right corner to login.

2.1 Open the web page for the first time and check whether the user has logged in

On LE5le.com, JWT is used to authenticate users. The token value of JWT is stored in cookies to facilitate sub-domain shared login. Then add the Authorization: token value to each HTTP request headers, and the backend service can authenticate the user.

When a web page is initialized for the first time, you simply request the backend service/API /user/profile to get the user. If the interface/API /user/profile returns user data, the user has logged in. If 401 is returned, you are not logged in. Here, we first determine whether there is a token under the cookie in the request user interface. Refer to the default. Vue:

async getUser() {
      if (this.$cookies.get('token')) {
        this.user = await this.$axios.$get('/api/user/profile')
      }
},
Copy the code

Async and await come in pairs. “Await” means that the function must await the result of the await function before continuing to execute the code. Typically used to wait for the result of an asynchronous request to avoid callbacks. This is possible without asynchrony.

To automatically add a token from a cookie to headers each time a request is made, we need to write an HTTP request interceptor.

2.2 HTTP Interceptors

The purpose of the HTTP interceptor is to automatically handle some global common operation for us every time a request and data is returned. Such as the authentication token addition here.

2.2.1 Create a plugins/axios.js plug-in file to implement the HTTP interceptor through the AXIos plug-in.

Export default function({$axios, app, redirect}) { Add Authorization to headers $axios.setToken(app.$cookie.get ('token')) $axios.onResponse(response => {// Unified error handling. If an error field is found, a NOTICE /error error message is sent. If (response.error) {app.store.com MIT ('notice/error', {text: Response.error})}}) $axios.onerror (error => {// Check whether the interface is faulty by code status code. Const code = parseInt(error.response && error.response.status) if (code === 401) {// Login required App.store.com MIT ('notice/error', {text: 'please login! Else if (code === 500) {app.store.mit ('notice/error', code === 403)} else if (code === 500) {app.store.com ('notice/error', {the text: error. The response. The error | | 'service errors, please try again later! '})}})}Copy the code

Configure loading axios plug-in in 2.2.2 nuxt.config.js

plugins: ['@/plugins/element-ui', '@/plugins/axios'],
Copy the code

2.2.3 Adding cookie Plug-in Because we need to read cookies, so install a cookie plug-in for easy use.

yarn add cookie-universal-nuxt --save
Copy the code

Nuxt. Config. Js

modules: [
   // Doc: https://axios.nuxtjs.org/usage
   '@nuxtjs/axios',
   'cookie-universal-nuxt'
 ],
Copy the code

We can then use it directly in plugins/axios.js and (default).vue.

Route, add a home page list page

Nuxt.js does not need to write router.js. The convention is that the vue file under Pages is the route. It’s easier. Let’s add a new index. Vue home page and change the original index. Vue to workspace. The new index. Vue:

<template> <div class="page-list"> <div> <div class="nav"> <label> </label> </div> <div class="flex wrap"> <div class="topo" v-for="(item, index) of data.list" :key="index" :title="item.desc" @click="onOpen(item)" > <div class="image"> <img :src="item.image" /> </div> <div class="ph15 pv10"> <div class="title line one" :title="item.name">{{ item.name }}</div> <div class="desc line two mt5" :title="item.desc">{{ item.desc }}</div> <div class="flex mt5"> <div class="full flex middle"> <el-avatar src="https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg" :size="24" ></el-avatar> <span Class ="ml5">{{item.username}}</span> </div> <span class="hover pointer MR15 "title=" like "> < I class="iconfont" :class="{'iconfont icon-appreciate':! item.stared, 'iconfont icon-appreciatefill':item.stared}" ></i> <span class="ml5">{{ item.star || 0 }}</span> </span> <span Class ="hover pointer" title=" hover "> < I class="iconfont" :class="{'iconfont ':! item.favorited, 'iconfont icon-likefill':item.favorited}" ></i> <span class="ml5">{{ item.hot || 0 }}</span> </span> </div> </div> </div> </div> </div> <div> <el-pagination @current-change="getList" :current-page="search.pageIndex" :page-size="8" layout=" prev, pager, next, jumper, total" :total="data.count" ></el-pagination> </div> </div> </div> </template> <script> export default { data() { return { data: { list: [], count: 0 }, search: { pageIndex: 1, pageCount: 8 } } }, created() { this.getList() }, methods: { async getList() { this.data = await this.$axios.$get( `/api/topologies? pageIndex=${this.search.pageIndex}&pageCount=${this.search.pageCount}` ) }, onOpen(item) { this.$router.push({ path: '/workspace', query: { id: item.id } }) } } } </script>Copy the code

Vue contains: 1. GetList Obtains the list data of the home page. This.$router.push({path: ‘/workspace’, query: {id: item.id}})

Routing details: zh.nuxtjs.org/guide/routi…

The last

Since then, a small project was completed, including: framework building, plug-in, VUex, identity authentication, HTTP communication, routing and other functions.

The functional details of the whole project are not perfect yet. Welcome to mention PR:

Full details can be found at:topology.le5le.com/ ,Development of the document. Add to the list of contributors! Also welcome to add group discussion:

How to contribute

Pr on GitHub: 0. Read the development documentation to learn about related attributes.

  1. Fork warehouse to own name
  2. Make changes locally and submit them to your own Git repository
  3. Find the “Pull Request” button in your fork repository and submit it

Open source project is not easy, welcome everyone to participate, to 【The article,Making open source libraryClick on the star to like, or sponsor the server: