Na primeira parte do artigo sobre como criamos soluções de portal para os maiores empregadores da Rússia, a arquitetura foi descrita pelo back-end. Neste artigo, passaremos para o frontend.
Como já observado na primeira parte, nosso principal objetivo era desenvolver uma plataforma que possa ser facilmente dimensionada e mantida.A reutilização doFront é escrita principalmente no Vue.js e, como todo o portal é dividido em portlets, cada um deles é uma instância separada do Vue com seu próprio lado (Vuex), rota (Vue Router) e componentes. Cada uma dessas instâncias é movida para seu próprio repositório.Como o portlet está em seu repositório, surge a questão de como não escrever muito do mesmo tipo de código para portlets diferentes. Para resolver esse problema, transferimos tudo o que pode ser reutilizado para um repositório separado, que é então conectado via .gitmodules. No momento, existem dois desses submódulos.Um armazena funcionalidade comum: estes são componentes, serviços, constantes, etc. Temos este módulo chamado Vue-common.O segundo submódulo contém configurações para montagem, armazena configurações para webpack, além de carregadores e auxiliares necessários durante a montagem. Este módulo é chamado Vue-bundler.Para facilitar o trabalho com a API, os métodos REST também foram divididos em geral e local. No Vue-common, foram introduzidos métodos para obter uma lista de usuários do portal, métodos de administração, acesso ao sistema de arquivos do portal e outros. Todos os pontos de extremidade da API foram movidos para serviços separados, registrados no ponto de entrada e conectados à instância do Vue. Em seguida, eles podem ser usados em qualquer lugar do aplicativo.Cada serviço individual é registrado dentro do plug-in. O Vue possui uma função de uso integrada para conectar plug-ins. Leia mais sobre plugins no Vue aqui .O próprio plugin é inicializado assim:class Api {
constructor () {
this.instance = instance
Object.keys(commonServices).forEach(name => commonServices[name](this))
requireService.keys().forEach(filename => requireService(filename).default(this))
}
install () {
Vue.prototype.$api= this
}
}
export default new Api()
Além da inicialização:- A instância do cliente http é criada. Que define a baseURL do nosso back-end e os cabeçalhos
const instance = axios.create({
baseURL: '/example/api',
responseType: 'json',
headers: {
'Content-Type': 'application/json',
'Cache-Control': 'no-cache',
'Pragma': 'no-cache',
}
})
backend , axios.
- São criados serviços que armazenam as próprias solicitações
export default api => {
api.exampleService= {
exampleGetRequest(params) {
return api.instance.request({
method: 'get',
url: `example/get`,
params
})
},
examplePostRequest(data) {
return api.instance.request({
method: 'post',
url: `example/post`,
data
})
},
}
}
No vue-common, basta criar apenas um serviço desse tipo e já está registrado para cada portlet na classe Api - Serviços gerais e locais são registrados
const requireService = require.context('./service', false, /.service.js$/)
Nos componentes, eles são usados de maneira muito simples. Por exemplo:export default {
methods: {
someMethod() {
this.$api.exampleService.exampleGetRequest()
}
}
}
Se você precisar fazer solicitações fora do aplicativo, poderá fazer o seguinte:
import api from ‘@/api’
api.exampleService.exampleGetRequest()
DimensionamentoConforme observado acima, um pacote configurável separado é coletado para cada portal e cada pacote configurável possui seus próprios pontos de entrada. Em cada um deles, os componentes e ativos são registrados, a autorização é configurada para o desenvolvimento local e os plug-ins são conectados.Os componentes são registrados globalmente para cada aplicativo, local e geral.O registro do componente se parece com o seguinte:import _ from “lodash”
const requireComponent = require.context('@/components', true, /^[^_].+\.vue$/i)
requireComponent.keys().forEach(filename => {
const componentConfig = requireComponent(filename)
const componentName = _.upperFirst(
_.camelCase(/\/\w+\.vue/.exec(filename)[0].replace(/^\.\
)
Vue.component(componentName, componentConfig.default || componentConfig)
})
Às vezes, torna-se necessário que o portal que estamos desenvolvendo adicione funcionalidade exclusiva e, para isso, você precise escrever componentes exclusivos ou simplesmente implementar um componente de uma maneira diferente. É suficiente criar um componente em uma pasta separada, por exemplo / components-portal / * nome do portal * / *. Vue, e registrá-lo no ponto de entrada desejado, adicionando require.context não para uma pasta, mas para várias.const contexts = [
require.context('@/components', true, /^[^_].+\.vue$/i),
require.context('@/components-portal/example', true, /^[^_].+\.vue$/i)
]
contexts.forEach(requireComponent => {
requireComponent.keys().forEach(filename => {
const componentConfig = requireComponent(filename)
const componentName = _.upperFirst(
_.camelCase(/\/\w+\.vue/.exec(filename)[0].replace(/^\.\
)
Vue.component(componentName, componentConfig.default || componentConfig)
})
})
Se você definir o mesmo nome para o componente para um portal específico a partir da biblioteca geral de componentes, ele será simplesmente reescrito como uma propriedade do objeto e será usado como um componente para este portal.Ativos como ícones svg também são registrados globalmente. Usamos svg-sprite-loader para criar um sprite a partir de ícones svg e depois os usamos via <use: xlink: href = "# * icon name *" />Eles são registrados assim:const requireAll = (r) => r.keys().forEach(r)
const requireContext = require.context('@/assets/icons/', true, /\.svg$/)
requireAll(requireContext)
Para dimensionar não apenas a funcionalidade, mas também os estilos de componentes, implementamos um mecanismo para alterar os estilos de um portal específico. Os componentes de arquivo único especificam estilos na tag <style> e são usados por padrão. Para implementar estilos para um portal específico, é necessário registrá-los em outra tag