Vue的结构与Vuex和特定于组件的数据Vue的结构与Vuex和特定于组件的数据(Vue struc

2019-05-12 11:05发布

我看到很多采用这种结构Vue.js项目:

├── main.js
├── api
│   └── index.js
│   └── services           #containing files with api-calls
│       ├── global.js
│       ├── cart.js
│       └── messages.js
├── components
│   ├── Home.vue
│   ├── Cart.vue
│   ├── Messages.vue
│   └── ...
└── store
    ├── store.js
    ├── actions.js  #actions to update vuex stores
    ├── types.js
    └── modules
        ├── global.js
        ├── cart.js
        └── ...

(这种结构的一个例子是“ Jackblog ”)。

因此,例如, Cart.vue想要更新inCart在Vuex数据。 要做到这一点,将车进口actions.js

import { inCart } from '../../store/actions'

actions.js进口API的index.js ,因此它可以连接到API。 然后它会更新Vuex存储值。

好了,这是明显的对我。 但现在,我想在上工作Messages.vue模块。 该模块应连接到API,以及让所有的消息,但没有必要对结果存储在Vuex。 需要该数据的唯一成分是Messages.vue本身,所以应该存储在组件的data()只。

问:我无法导入actions.jsMessages.vue因为动作不应该更新Vuex。 但我不能移动actions.jsapi目录,因为这将打破,在商店目录中的数据添加到存储中的所有文件的逻辑。 除此之外,逻辑应放在里面Messages.vue 。 例如,当API返回一个错误,本地error的常数应设置。 所以,它不能由一个单独的文件来处理。

是什么使API调用,并将它们存储在vuex或本地推荐应用结构data() 在哪里放置的行动文件,该API文件,等等? 当寻找到Jackblog例如,它仅支持Vuex数据。 如何重组这支持?

Answer 1:

我使用爱可信作为HTTP客户端作出API调用,我创建了一个gateways在我的文件夹中src文件夹,我的文件为每个后端,营造爱可信情况下 ,像以下

myApi.js

import axios from 'axios'
export default axios.create({
  baseURL: 'http://localhost:3000/api/v1',
  timeout: 5000,
  headers: {
    'X-Auth-Token': 'f2b6637ddf355a476918940289c0be016a4fe99e3b69c83d',
    'Content-Type': 'application/json'
  }
})

这些相同的情况下,在两个部件和vuex行动来获取数据,以下是两种方式的细节。

填充成分数据

如果正在使用只在组件中的数据,比如你的情况下Messages.vue ,您可以将来自像下面的API获取数据的方法:

export default {
  name: 'myComponent',
  data: () => ({
    contents: '',
    product: []
  }),
  props: ['abc'],
  methods: {
    getProducts (prodId) {
       myApi.get('products?id=' + prodId).then(response => this.product = response.data)
       },
       error => {
          console.log('Inside error, fetching products failed')
          //set error variable here
       })
    }
    ..... 

填充Vuex数据

如果你是一个奉献在保持产品的相关数据vuex模块 ,你可以派遣从组件的方法,该方法将在内部调用后端API和填充数据在存储中的动作,代码看起来类似如下:

代码组件:

methods: {
 getProducts (prodId) {
     this.$store.dispatch('FETCH_PRODUCTS', prodId)
  }
}

代码vuex店:

import myApi from '../../gateways/my-api'
const state = {
  products: []
}

const actions = {
  FETCH_PRODUCTS: (state, prodId) => {
    myApi.get('products?id=' + prodId).then(response => state.commit('SET_PRODUCTS', response))
  }
} 

// mutations
const mutations = {
  SET_PRODUCTS: (state, data) => {
    state.products = Object.assign({}, response.data)
  }
}

const getters = {
}

export default {
  state,
  mutations,
  actions,
  getters
}


Answer 2:

简短的回答:考虑Jackblog例子 - 你只需要输入“API”从组件,并直接使用的API。 不导入动作。 在Messages.vue,忘了商店。 你不需要的行动层,这是联系在一起的商店。 你只需要提供API。


龙答:在一个项目中,我们有以下几点

  1. 一个Ajax库包装提供一个命名函数remote接受两个参数:一个字符串和一个对象。 该字符串告诉我们正在努力实现(例如,“saveProductComment”)和对象是有效载荷(参数名称和值,被发送到服务器)。

  2. 每个应用模块可以包含“routes.js”文件,该文件映射上面一个路由配置中的“字符串”。 例如: saveProductComment: 'POST api/v1/products/{product_id}/comment'

注意:我使用术语“应用模块”单个.js或者.vue这被视为“模块”通过或的NodeJS文件的WebPack。 我打电话“应用模块”包含与特定的域(例如:“购物车”模块,“帐户”模块,“意见”模块, 等等 )的应用程序代码,一个完整的文件夹。

  1. 从任何地方,我们可以调用remote('saveProductComment', { product_id: 108, comment: 'Interesting!' })并返回一个Promise 。 该包装使用路由配置,以建立正确的要求,同时也解析响应和处理错误。 在任何情况下, remote函数总是返回一个Promise

  2. 每个应用程序模块也可以提供自己的商店模块 ,我们定义的初始状态,基因突变,行动和相关模块干将。 我们正在使用的状态管理代码术语“经理人”。 例如,我们可以有一个“commentsManager.js”文件,提供商店模块采取的“意见”的照顾。

  3. 在管理中,我们使用remote功能,使内Vuex 行动的API调用。 我们从远程返回的承诺,但我们也重视它,其处理结果的回调。 在回调,我们称之为突变功能提交的结果:


newProductComment ({ commit }, { product, contents }) {
    return remote('saveProductComment', {
        product_id: product.id,
        comment: contents
    })
    .then(result => {
        commit('SOME_MUTATION', result.someProperty)
    })
}

现在,如果我们想用直接Vuex范围外相同的API调用,而是一个组件内,我们只需要在Vue公司组件的方法使用类似的代码。 例如:

export default {
    name: 'myComponent',
    data: () => ({
        contents: '',
        someData: null
    }),
    props: ['product'],
    methods: {
        saveComment () {
            remote('saveProductComment', {
                product_id: this.product.id,
                comment: this.contents
            })
            .then(result => {
                this.someData = result.someProperty
            })
        }
    }
}

在应用结构来看,真正的问题对我们来说是:

  • 具有该应用适当地划分成不同的顾虑; 我们所说的“应用模块”; 对于每个具体的事情一个模块

  • 我们有一个包含文件夹的每个“应用程序模块”一个“模块”的文件夹

  • 一个特定的“应用程序模块文件夹”里面,我们有路由配置在routes.js ,映射所述远程函数的第一参数的路由配置; 我们的自定义代码挑HTTP方法,内插URL,做各种花哨的东西,正确的适合我们的需求; 但应用程序代码的任何地方在剩下的,我们只是它在简单的方法: remote('stuffNeededToBeAccomplished', { dataToAccomplishTheNeed })

  • 换句话说,繁重的工作是在映射,并在Ajax库包装(可用于实际的请求的任何Ajax库); 注意,这是完全独立的使用Vue公司/ Vuex的

  • 我们有Vuex店也分为模块; 通常,应用程序模块中,我们有使用其中定义的路由对应的存储模块

  • 在主入口点,我们导入了应用模块; 每个模块的index.js需要注册在阿贾克斯包装和Vuex(商店模块两种路线的护理的话,我们只需要导入,并采取进一步的行动,以对Ajax和现有可用路由商店模块在Vuex)



文章来源: Vue structuring with Vuex and component-specific data