一、概述

EdgeGallery 旨在构建一个开源的、多用途的边缘计算平台,以支持MEC的各种用例和应用程序。EdgeGallery提供了一套工具、框架和资源,帮助开发者更容易地构建和部署边缘应用程序,从而利用MEC的潜力。

代码仓库:https://gitee.com/edgegallery

二、前端技术

Edgegallery前端技术栈主要是开源的Vue.js实现的页面构建,还有自己封装的组件库EdgeGallery,用于统一页面风格,路由模块是基于Vue-router实现的页面跳转,使用Vuex实现组件数据的状态管理。

属于前端的代码:

其中,appstore-fe是AppStore前端代码库,atp-fe是应用测试认证前台代码,developer-fe是开发者前端,mecm-fe是MECM的前台模块,user-mgmt-fe用户管理模块的前端,eg-view是组件库,用于统一界面风格。

1.EdgeGallery组件库

eg-view服务于EdgeGallery,主要用于规范化EdgeGallery界面风格。eg-view基于Element UI提供了一套适用于EdgeGallery平台的组件。官网地址 https://gitee.com/edgegallery/eg-view,也就是EdgeGallery基于Element UI封装了一套自己的组件库。

2.路由

Vue Router 是 Vue.js 的官方路由管理库,用于构建单页面应用程序(SPA)中的客户端端路由。它允许你定义前端应用的路由,将不同的 URL 映射到 Vue 组件,以实现页面之间的导航、跳转和切换,同时保持单页面应用的用户体验。

按需加载

// 导入Vue Router库
import VueRouter from 'vue-router';

// 创建路由实例
const router = new VueRouter({
  // 定义路由配置
  routes: [
    {
      // 定义路径和名称
      path: 'app/test/task',
      name: 'apttask',
      // 当访问该路径时,动态加载ATPTask组件
      component: () => import('./pages/myApp/ATPTask.vue')
    }
  ]
});

// 导出路由实例
export default router

这样做的好处是,只有当用户访问该路径时,才会加载对应的组件,而不是在应用启动时就加载所有组件。这样可以提高应用的性能,减少初始加载时间。

总结起来,这段代码的作用是创建一个Vue Router实例,并定义了一个按需加载的路由规则,当用户访问​​'app/test/task'​​路径时,会动态加载​​ATPTask​​组件。

路由传参

Vue Router 提供了两种路由传参的方式:

  1. 动态路由参数:使用冒号(:)表示一个动态的路由参数,例如 /user/:id。在组件中可以通过 $route.params.id 获取到这个参数的值。
  2. 查询参数:使用问号(?)表示一个查询参数,例如 /user?name=John。在组件中可以通过 $route.query.name 获取到这个参数的值。

下面是一个params传参示例:

首先,在路由配置中定义带有动态路由参数和查询参数的路由:

const routes = [ 
 // 动态字段以冒号开始,
         {     
         path: '/users/:username',   //路由的路径,参数会被传递给组件,以便在组件中使用。  
         name: 'UserHomePage'   //路由的名称       
         component: User   //User 是一个 vue 组件 
         },
         ]

就可以通过如下方式将username传递给目标路由组件:

router.push({
  name:'UserHomePage',  
  params: { 
      username:"zhangsan"
   }})

路由跳转成功后,地址栏的路径会变成 /users/zhangsan,在目标路由组件可以通过如下方式获取参数:

let { username } = this.$route.params;

下面是query传参

通过指定 query 参数来将数据传递到下一个页面:

router.push({
      name:'UserHomePage',  
      params: { 
         username:"zhangsan" 
               }  
      query: { 
         showAvatar: "true" 
             }
 })
 //导航到名为UserHomePage的路由,并传递了一个动态路由参数 username 和一个查询参数 showAvatar。

这个方式,是使用 URL 中的 search 字段来传递参数,路由跳转成功后地址栏的路径会变成 /users/zhangsan?showAvatar=true,在目标路由组件可以通过如下方式获取参数:

let { showAvatar } = this.$route.query;

目标路由组件可以通过​​this.$route.params.username​​来访问动态路由参数,通过​​this.$route.query.showAvatar​​来访问查询参数。

以上两种方式,都是通过路由地址来传递参数,他们有一些很明显的缺点

路由间的参数会以明文的方式暴露在URL中。

同样的,从另一方面考虑,也有它的优势

  • 刷新页面不会丢失参数
  • 路径参数让url 路径看起来更加有可读性,结构分明

路由守卫

路由守卫(Route Guards)是在路由导航过程中用于执行一些逻辑操作的函数或钩子。它们允许你在路由跳转之前、之后或者在路由变化时执行特定的任务,如身份验证、权限检查、数据加载等。路由守卫是用来控制路由导航和保护路由的重要工具。

在Vue Router中,通常有三种主要类型的路由守卫:

  1. 全局守卫(Global Before Guards): 全局守卫是在路由跳转之前和之后执行的守卫。它们可以用于执行全局的身份验证、权限检查等任务。常见的全局守卫是 beforeEach,afterEach 钩子。

有一个在用户未能验证身份时重定向到 ​​/login​​ 的示例:

router.beforeEach((to, from, next) => {
    if (to.name !== 'Login' && !isAuthenticated) 
             next({ name: 'Login' })//用于控制导航的行为。
             //调用 next 函数将路由重定向到名为 'Login' 的路由。这将强制用户跳转到登录页面。
     else next()
     //如果上述条件满足,则调用 next 函数继续正常的路由导航。
     })
  • ​to: Route​​: 即将要进入的目标 路由对象
  • ​from: Route​​: 当前导航正要离开的路由
  • ​next: Function​​: 执行效果依赖 next 方法的调用参数。
router.afterEach(route => {//在每次路由导航完成后执行
 //route参数包含了当前路由的信息,包括name、path等。
  Vue.nextTick((to, from) => {
  //用于在DOM更新后执行回调函数。在这里,确保了DOM已经更新完毕后再执行后续操作。
   ...
  })
  
})
  1. 路由独享守卫: 路由独享守卫是仅针对特定路由的守卫。你可以在路由配置中为每个路由定义自己的独享守卫。常见的路由独享守卫有 beforeEnter 钩子。

以下是一些常见的路由守卫的使用示例:

const router = new VueRouter({
  routes: [
    {
      path: '/admin',
      component: AdminPanel,
      beforeEnter: (to, from, next) => {
        // 路由独享守卫示例:检查用户是否有管理员权限
        if (userIsAdmin()) {
          next(); // 允许进入/admin
        } else {
          next('/login'); // 重定向到登录页面
        }
      }
    }
  ]
});
  1. 组件内守卫(In-Component Guards): 组件内守卫是直接放在组件中的守卫。它们用于执行特定组件的任务,例如在组件加载或销毁时执行一些逻辑。常见的组件内守卫有 beforeRouteEnterbeforeRouteUpdatebeforeRouteLeave 钩子。

3.状态管理

Vuex 是一个专门为 Vue.js 应用程序开发的状态管理模式和库。它允许在应用程序中有效地管理和共享状态,使得组件之间的通信和状态的管理更加容易和可维护。Vuex通常用于大型或复杂的Vue.js应用程序中,以解决组件之间共享数据和状态的问题。

以下是Vuex的主要概念和用法:

  1. State: State 是应用程序的数据仓库,它包含了应用程序的所有需要共享的状态信息。在Vuex中,State 是响应式的,这意味着当状态发生变化时,所有依赖于它的组件都会自动更新。
  2. Getters: Getters 允许你在组件中访问和计算 State 中的数据。你可以使用 Getter 来获取、过滤或计算 State 中的数据,而无需重复编写相同的代码。
  3. Mutations: Mutations 是用于修改 State 的同步方法。它们是唯一允许修改 State 的方式,以确保状态变化的可追踪性。通常,Mutation 函数会接受一个参数(State)和一个负载(Payload),用于进行状态的修改。
  4. Actions: Actions 用于处理异步操作,例如数据获取、API调用等。它们可以包含多个 Mutation,可以触发 Mutation 来修改 State。Actions 可以帮助将业务逻辑从组件中分离出来,使代码更加干净和可维护。
  5. Modules: 如果你的应用程序状态非常复杂,你可以将 State、Getters、Mutations 和 Actions 划分为多个模块,每个模块都有自己的状态和操作。这有助于组织和管理大型应用程序的代码。

如下是VueX的状态管理实例示意图:

  • 当用户与组件交互时,比如点击一个按钮,组件会调用一个Action。Action是一个异步操作,可以执行一些逻辑,然后触发Mutation。
  • Mutation是同步的,它会修改State中的数据,更新应用程序的状态。这些更改会自动反映在与State相关联的组件中。
  • 最终,组件会显示最新的状态,并将其呈现给用户。

整个流程是单向的,从View到Action,然后到Mutation,最后到State。这种严格的数据流使得状态管理更加可维护和可追踪,尤其在大型应用程序中。

Vuex的使用:

  1. 安装Vuex并在Vue应用中引入它。
  2. 定义应用程序的状态(State)。
  3. 创建 Getters 来获取 State 中的数据。
  4. 创建 Mutations 来修改 State 中的数据。
  5. 创建 Actions 来处理异步操作并触发 Mutations。
  6. 在组件中使用 Getters、Mutations 和 Actions 来访问和修改状态。

以下是一个简单的示例,展示了Vuex的基本用法:

// main.js
import Vue from 'vue';
import Vuex from 'vuex';
import store from './store';

Vue.use(Vuex);

new Vue({
  store,
  // ...
});
// store.js
import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    count: 0,
  },
  mutations: {
    increment(state) {
      state.count++;
    },
  },
  actions: {
    incrementAsync({ commit }) {
      setTimeout(() => {
        commit('increment');
      }, 1000);
    },
  },
});

<!-- MyComponent.vue -->
<template>
  <div>
    <p>Count: {{ count }}</p>
    <button @click="increment">Increment</button>
    <button @click="incrementAsync">Increment Async</button>
  </div>
</template>

<script>
export default {
  computed: {
    count() {
      return this.$store.state.count;
    },
  },
  methods: {
    increment() {
      this.$store.commit('increment');
    },
    incrementAsync() {
      this.$store.dispatch('incrementAsync');
    },
  },
};
</script>

这个示例中,创建了一个名为 "count" 的状态(State),定义了一个 Mutation 来增加 "count" 的值,以及一个 Action 来异步增加 "count" 的值。在组件中,使用计算属性从 Vuex 的状态管理中获取 count 的值。并使用 Mutations 和 Actions 来修改 "count" 的值。

Vuex是一个强大的状态管理库,用于在Vue.js应用程序中管理和共享状态。它帮助开发者组织和维护应用程序的状态,以实现更好的代码结构和可维护性。

4.数据请求

Axios 是一个流行的JavaScript库,用于进行HTTP请求。它可以在浏览器和Node.js环境中使用,使得向服务器发送HTTP请求和处理响应变得更加简单和方便。用于与后端服务器进行通信。

在Edge Gallery中,Axios主要负责以下功能:

  • GET请求:用于从服务器获取图片和视频资源的数据。
  • POST请求:用于向服务器提交图片和视频资源的上传请求。
  • PUT请求:用于更新服务器上的图片和视频资源。
  • DELETE请求:用于删除服务器上的图片和视频资源。

以下是一个简单的Axios示例,展示了如何使用Axios发送GET请求:

// 引入Axios库
import axios from 'axios'

// 发送GET请求
axios.get(url, {
      params: params,
      withCredentials: true,
      headers: {
        'Content-Type': 'application/json',
        'X-XSRF-TOKEN': getCookie('XSRF-TOKEN')
      }
    }).then(res => {
     // 处理成功响应
     ....
    }).catch(error => {
       // 处理请求失败
       ....
    })

在这个示例中,首先引入了Axios库,然后使用​​axios.get()​​方法发送GET请求,可以通过​​.then()​​处理成功的响应和​​.catch()​​处理请求失败的情况。

请求参数说明

参数

说明

url

表示要发送请求的目标URL。这是必需的参数,指定了服务器端资源的位置。

params

这是一个包含请求参数的对象。允许将数据发送到服务器,通常用于GET请求中的查询参数。例如,如果你要向服务器获取某个用户的信息,你可以将用户ID作为查询参数传递给服务器。

withCredentials

这是一个布尔值,用于指定是否发送跨域请求时携带凭证信息,例如Cookie。如果设置为​​true​​,则表示携带跨域请求的凭证信息,通常在需要与跨域资源共享的情况下使用。

headers

这是一个包含请求头信息的对象。请求头用于传递额外的信息给服务器,如Content-Type、授权令牌等。上述代码中,设置了两个请求头信息:'Content-Type' 和 'X-XSRF-TOKEN'。

  • ​'Content-Type': 'application/json'​​:告知服务器请求的主体是JSON格式的数据。
  • ​'X-XSRF-TOKEN': getCookie('XSRF-TOKEN')​​:用于传递XSRF令牌的请求头。XSRF(跨站请求伪造)令牌是一种安全机制,用于防止跨站点攻击。从Cookie中获取的,然后作为请求头的一部分发送到服务器,以确保请求的合法性。

5.API

对于EdgeGallery,与后端请求的 API一般存放在api.js文件夹中。

function acceptMsg (messageId) {//根据id获取信息
  let url = 'messages/' + messageId + '/action/download'//拼接URL
  return GET(url, '')//get请求
}

参考资料:

1.​​动态路由匹配 | Vue Router​

2.​​Vuex详解,一文彻底搞懂Vuex_Mr.指尖舞者的博客-CSDN博客​

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐