Vue.js Merge 2 files with methods - javascript

i have an api with routes about different topics, so i want to keep my api calls clean as possible. I try to import all the vue methods from 2 different files with 1 import.
What i tried do but not working is as following; I created 2 files that make api calls in vue methods: categories.js and expenses.js and i created an index.js file that wil import those files together. So on my main file i import the index.js file so i can use my methods from the expenses.js and categories.js file
I get the following: TypeError: this.getCategories is not a function
categories.vue
import * as API from '#/api'
export default {
mixins: [API],
mounted(){
this.getCategories()
}
}
index.js
import * as Categories from './categories.js'
import * as Expenses from './expenses.js'
export default {
Categories,
Expenses
}
categories.js
export default {
methods: {
getCategories(){
this.$http.get('api.example.com')
.then(response => {
// response
})
}
}
}
expenses.js
export default {
methods: {
getExpenses(){
this.$http.get('api.example.com')
.then(response => {
// response
})
}
}
}

Change your index.js to export an array:
import Categories from './categories.js'
import Expenses from './expenses.js'
export default [
Categories,
Expenses
]
Then changes the categories component to:
import API from '#/api'
export default {
mixins: API, // [...API, others, more] if using more mixins.
mounted(){
this.getCategories()
}
}

Related

Nuxt read module state inside a component

I've got a Nuxt application with a store directory that resembles this folder
https://nuxtjs.org/docs/2.x/directory-structure/store#example-folder-structure.
Imagine that I have a property isComplete in my module state inside the cart folder.
I get the following error that Property 'shop' does not exist on type 'RootState'.
How could I access this property in a Vue component ?
Component.vue
<script lang="ts">
import { defineComponent, onMounted } from '#nuxtjs/composition-api'
import { useStore } from '~/store'
export default defineComponent({
name: 'Component',
setup() {
const store = useStore()
onMounted(() => {
if (store.state.shop.cart.isComplete) {
// Execute some code
}
})
},
})
</script>
My store/index.ts has the following implementation
import { InjectionKey, useStore as baseUseStore } from '#nuxtjs/composition-api'
export interface RootState {}
export const state = () => ({})
export const injectionKey: InjectionKey<RootState> =
Symbol('vuex-injection-key')
export const useStore = () => {
return baseUseStore(injectionKey)
}
store/shop/cart/state.ts
export interface CartState {
isComplete: boolean
}
export const state = (): CartState => ({
isComplete: false,
})
Store state
Store files named state should have an object-returning method as its default export, so store/shop/cart/state.ts should contain export default state (where state is the method) as its last line. Otherwise, you'll see a warning in the browser console:
store/shop/cart/state.ts should export a method that returns an object
Or you could rename store/shop/cart/state.ts to store/shop/cart/index.ts (perhaps the original intent based on the exported state constant).
RootState type
There's no type inference available here, so the RootState needs to be explicitly typed to include the states of modules.
Import the CartState from the namespaced module.
Add a key named after each namespaced module, nested as needed (i.e., shop and then cart). Apply the CartState type for the cart key.
// store/index.ts
import type { CartState } from './shop/cart' 1️⃣
export interface RootState {
shop: {
cart: CartState, 2️⃣
}
}
GitHub demo

How to use $axios Nuxt module inside of setup() from composition API?

The docs say to use this.$axios.$get() inside of methods/mounted/etc, but that throws TypeError: _this is undefined when called inside of setup(). Is $axios compatible with the composition API?
To clarify, I'm specifically talking about the axios nuxt plugin, not just using axios generically. https://axios.nuxtjs.org/
So for instance, something like this throws the error above
export default {
setup: () => {
const data = this.$axios.$get("/my-url");
}
}
import { useContext } from '#nuxtjs/composition-api';
setup() {
const { $axios } = useContext();
}
Alright, so with the usual configuration of a Nuxt plugin aka
plugins/vue-composition.js
import Vue from 'vue'
import VueCompositionApi from '#vue/composition-api'
Vue.use(VueCompositionApi)
nuxt.config.js
plugins: ['~/plugins/vue-composition']
You can then proceed with a test page and run this kind of code to have a successful axios get
<script>
import axios from 'axios'
import { onMounted } from '#vue/composition-api'
export default {
name: 'App',
setup() {
onMounted(async () => {
const res = await axios.get('https://jsonplaceholder.typicode.com/posts/1')
console.log(res)
})
},
}
</script>
I'm not sure about how to import axios globally in this case but since it's composition API, you do not use the options API keys (mounted etc...).
Thanks to this post for the insight on how to use Vue3: https://stackoverflow.com/a/65015450/8816585

Why I could connect API via axios?

I created react app with Typescript and I made a request via axios.
Here is my original code.
// /src/axios.js
import axios from 'axios';
const instance = axios.create({
baseURL:"https://api.baseurl.org",
});
export default instance;
// /src/component.js
import React from "react";
import axios from "./axios";
...
const Component = ({ fetchUrl }) => {
async function fetchData() {
const request = await axios.get(fetchUrl);
}
...
};
...
I could get responses correctly, but don't know why I could make a request.
In axios.js file, I export instance, not axios.
In component.js file, I import axios.
I think I should import instance in component.js, that is, modify the file like this :
// /src/component.js modified
import React from "react";
import instance from "./axios";
...
const Component = ({ fetchUrl }) => {
async function fetchData() {
const request = await instance.get(fetchUrl);
}
...
};
...
I could get the same result correctly.
Two ways of using axios instance made correct results.
Why I could connect API with the original code?
In axios.js file, I export instance, not axios. In component.js file, I import axios.
You're using a default export, not a named export. The name you assign to it is completely up to the module doing the importing.
Consider:
const foo = 123;
export default foo;
export const bar = 456;
To import that you say:
import whatever_you_want_to_call_it, { bar as anything_you_like } from './export.mjs';
bar is a named export so you have to specify that it is bar you want to import (but giving it a different name is optional). The default export has to be given a name, but which name is entirely up to you.

Vue composition API use VueAxios?

I am in main.js importing vue-axios
main.js
import { createApp } from 'vue';
import axios from 'axios';
import VueAxios from 'vue-axios';
import App from './App.vue';
const app = createApp(App);
app.use(VueAxios, axios);
app.mount('#app');
and App.vue
export default {
name: 'App',
setup() {
axios.get('xxxx').then((res) => {console.log(res)}); // is not working
}
};
but it seems Vue composition API setup can't get axios? So it must be used in App.vue import axios from 'axios'?
import axios from 'axios';
export default {
name: 'App',
setup() {
axios.get('xxxx').then((res) => {console.log(res)});
}
};
My environment is vite
generally I'd do something like this ( except I modularize all the api calling into a "service" rather than inlining it into the view code.)
import axios from 'axios';
import {onMounted} from 'vue'
export default {
name: 'App',
setup() {
onMounted(async () => {
let res = await axios.get('xxxx')
console.log(res)
});
}
};
This wouldn't work in any version of Vue without an import:
axios.get(...)
Even in Vue 2, you have to use one of these if you use vue-axios:
this.axios.get(...)
this.$http.get(...)
Vue.axios.get(...)
The composition API has no this access in the component, so vue-axios doesn't help much.

React-router API - defining routes

I am trying to use the react-redux-firebase app as a base for my app.
I'm trying to add static pages to the footer links (no state) and then render them as the app expects.
I haven't seen this approach to setting up a route index.js before.
The generator creates this index file (to which I have tried to add the About route):
import CoreLayout from '../layouts/CoreLayout'
import Home from './Home'
import LoginRoute from './Login'
import SignupRoute from './Signup'
import ProjectsRoute from './Projects'
import AccountRoute from './Account'
import NotFoundRoute from './NotFound'
import AboutPage from "./About"
/* Note: Instead of using JSX, we recommend using react-router
PlainRoute objects to build route definitions. */
export const createRoutes = store => ({
path: '/',
component: CoreLayout,
indexRoute: Home,
childRoutes: [
AccountRoute(store),
LoginRoute(store),
SignupRoute(store),
ProjectsRoute(store),
AboutPage,
// AsyncRoute(store) // async routes setup by passing store
// SyncRoute, // sync routes just need route object by itself
/* Place all Routes above here so NotFoundRoute can act as a 404 page */
NotFoundRoute(store)
]
})
/* Note: childRoutes can be chunked or otherwise loaded programmatically
using getChildRoutes with the following signature:
getChildRoutes (location, cb) {
require.ensure([], (require) => {
cb(null, [
// Remove imports!
require('./Counter').default(store)
])
})
}
However, this is not necessary for code-splitting! It simply provides
an API for async route definitions. Your code splitting should occur
inside the route `getComponent` function, since it is only invoked
when the route exists and matches.
*/
export default createRoutes
This app layout is that all the views seem to be setup under the routes folder. Following that approach, I made an AboutPage folder within src/routes/About/components. That folder has a AboutPage folder with a js page and in index, as well as separate index.js file (similar to the HomePage component provided with the generated app). The nested index has:
import AboutPage from './AboutPage'
export default AboutPage
The src/routes/About/index.js
import AboutPage from './components/AboutPage/index.js'
// Sync route definition
export default {
component: AboutPage
}
I don't get any errors when I save this, but when I start the server and click the link, I just get a 404 error.
How do I add routes to this app?
I have tried a million different variations on the import statement in the routes/index.js - many of which produce no error but do not actually render the page.
The full setup is src/routes/About/components/AboutPage/AboutPage.js
class About extends React.Component {
componentDidMount() {
window.scrollTo(0, 0);
document.body.scrollTop = 0;
}
render() {
const { classes, ...rest } = this.props;
const imageClasses = classNames(
classes.imgCard,
classes.imgFluid
);
const navImageClasses = classNames(classes.imgRounded, classes.imgGallery);
return (
<div>
-- intentionally deleted copy --
</div>
);
}
}
export default withStyles(profilePageStyle)(About);
Then, src/routes/components/AboutPage/index.js:
import AboutPage from './AboutPage'
export default AboutPage
Then src/routes/About/index.js
import AboutPage from './components/AboutPage/index.js'
// Sync route definition
export default {
component: AboutPage
}
Then routes/index.js - shown as above.
I have read this several times- I can't make sense of it. If the child doesn't have state, then I don't see why a store would be relevant.
https://github.com/ReactTraining/react-router/blob/v3/docs/API.md#plainroute

Categories