Api 使用Vuex和组件特定数据构建Vue
我看到很多Vue.js项目使用这种结构:Api 使用Vuex和组件特定数据构建Vue,api,structure,vue.js,directory-structure,vuex,Api,Structure,Vue.js,Directory Structure,Vuex,我看到很多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.
├── 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
└── ...
(此结构的示例为“”)
因此,例如,Cart.vue
希望更新Vuex中的incontat
数据。为此,购物车导入actions.js
:
从“../../store/actions”导入{incontat}
actions.js
导入api的index.js
,以便它可以连接到api。然后更新Vuex存储中的值
好的,我明白了。但是现在,我想处理Messages.vue
模块。此模块还应连接到api以获取所有消息,但无需将结果存储在Vuex中。唯一需要数据的组件是Messages.vue本身,因此它应该只存储在组件的data()
中
问题:我无法在Messages.vue中导入actions.js
,因为该操作不应更新Vuex。但是我不能将actions.js
移动到api
目录,因为这打破了将所有添加数据到存储的文件都放在存储目录中的逻辑。除此之外,逻辑应该放在Messages.vue
中。例如,当api返回错误时,应设置一个本地error
-常量。因此,它不能由单独的文件处理
进行api调用并将其存储在vuex或localdata()
中的建议应用程序结构是什么?将操作文件、api文件等放置在何处?查看Jackblog示例时,它仅支持Vuex数据。如何重新构造它以支持两者?我使用HTTP客户端进行API调用,我在src
文件夹中创建了一个gateways
文件夹,我为每个后端创建了文件,如下所示
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数据
如果您在专用数据库中维护产品相关数据,
您可以从组件中的方法发送操作,该操作将在内部调用后端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
})
}
.....
组件中的代码:
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
}
简短回答:考虑Jackblog示例-您只需要从组件导入“api”,并直接使用api。不要导入操作。在Messages.vue中,忘记商店。您不需要绑定到存储的actions层。你只需要API
详细回答:在一个项目中,我们有以下几点
一个Ajax库包装器,提供一个名为remote
的函数,该函数接受两个参数:字符串和对象。字符串告诉我们要实现什么(例如,“saveProductComment”),对象是有效负载(要发送到服务器的参数名称和值)
每个应用程序模块可能包含一个“routes.js”文件,该文件将上面的“字符串”映射为路由配置。例如:saveProductComment:'postapi/v1/products/{product\u id}/comment'
注意:我不是将术语“app module”用于NodeJS或Webpack视为“模块”的单个.js
或.vue
文件。我称之为“应用程序模块”是一个完整的文件夹,其中包含与特定域相关的应用程序代码(例如:“购物车”模块、“帐户”模块、“评论”模块等等)
我们可以从任何地方调用remote('saveProductComment',{product_id:108,comment:'interest!'})
,它返回一个承诺。包装器使用路由配置来构建正确的请求,它还解析响应并处理错误。在任何情况下,remote
函数总是返回一个Promise
每个应用程序模块还可以提供自己的存储模块,我们在其中定义与模块相关的初始状态、突变、操作和获取程序。我们将“管理者”一词用于州管理代码。例如,我们可以有一个“commentsManager.js”文件,提供存储模块来处理“评论”
在管理器中,我们使用remote
函数在Vuex操作中进行API调用。我们从remote返回承诺,但我们还附加了处理结果的回调。在回调中,我们调用变异函数来提交结果:
现在,如果我们想在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
})
}
}
}
就应用程序结构而言,对我们来说真正重要的是:
- 将应用程序正确划分为不同的关注点;我们称之为“应用程序模块”;每件具体的事情一个模块
- 我们有一个“模块”文件夹,其中包含每个“应用程序模块”的文件夹
- 在一个特定的“app module文件夹”中,我们在
routes.js
中有routes配置,将远程函数第一个参数映射到路由配置;我们的自定义代码选择HTTP方法,插入URL,做各种花哨的事情,适当地适合我们的需要;但是在剩下的应用程序代码中,我们只是以简单的方式使用它:remote('stuffeedtobecompleted',{datatocompletheneed})
- 换句话说,繁重的工作在映射和Ajax库包装中(您可以使用任何Ajax库来处理实际请求);请注意,这与使用Vue/Vuex完全无关
- 我们有Vuex