vue.js Data Pre-Fetching Problems - vue.js

I'm building an app following guide https://ssr.vuejs.org/en/data.html.
So i have structure:
server.js
const express = require('express');
const server = express();
const fs = require('fs');
const path = require('path');
const bundle = require('./dist/server.bundle.js');
const renderer = require('vue-server-renderer').createRenderer({
template: fs.readFileSync('./index.html', 'utf-8')
});
server.get('*', (req, res) => {
bundle.default({url: req.url}).then((app) => {
const context = {
title: app.$options.router.history.current.meta.title
};
renderer.renderToString(app, context, function (err, html) {
console.log(html)
if (err) {
if (err.code === 404) {
res.status(404).end('Page not found')
} else {
res.status(500).end('Internal Server Error')
}
} else if (context.title === '404') {
res.status(404).end(html)
} else {
res.end(html)
}
});
}, (err) => {
res.status(404).end('Page not found')
});
});
server.listen(8080);
store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex);
import axios from 'axios';
export function createStore() {
return new Vuex.Store({
state: {
articles: [
]
},
actions: {
fetchArticlesList({commit}, params) {
return axios({
method: 'post',
url: 'http://test.local/api/get-articles',
data: {
start: params.start,
limit: params.limit,
language: params.language
}
})
.then((res) => {
commit('setArticles', res.data.articles);
});
},
},
mutations: {
setArticles(state, articles) {
state.articles = articles;
}
}
})
}
router.js
import BlogEn from '../components/pages/BlogEn.vue';
import Vue from 'vue';
import Router from 'vue-router';
export function createRouter() {
return new Router({
mode: 'history',
routes: [
{
path: '/en/blog',
name: 'blogEn',
component: BlogEn,
meta: {
title: 'Blog',
language: 'en'
}
},
});
}
main.js
import Vue from 'vue'
import App from './App.vue'
import {createRouter} from './router/router.js'
import {createStore} from './store/store.js'
import {sync} from 'vuex-router-sync'
export function createApp() {
const router = createRouter();
const store = createStore();
sync(store, router);
const app = new Vue({
router,
store,
render: h => h(App)
});
return {app, router, store};
}
entry-server.js
import {createApp} from './main.js';
export default context => {
return new Promise((resolve, reject) => {
const { app, router, store } = createApp()
router.push(context.url)
router.onReady(() => {
const matchedComponents = router.getMatchedComponents()
if (!matchedComponents.length) {
return reject({ code: 404 })
}
Promise.all(matchedComponents.map(Component => {
// This code not from manual because i want load this in my content-component
if (Component.components['content-component'].asyncData) {
return Component.components['content-component'].asyncData({
store,
route: router.currentRoute
})
}
// This code from manual
// if (Component.asyncData) {
// return Component.asyncData({
// store,
// route: router.currentRoute
// })
// }
})).then(() => {
context.state = store.state
resolve(app)
}).catch(reject)
}, reject)
})
}
entry-client.js
import Vue from 'vue'
import {createApp} from './main.js';
const {app, router, store} = createApp();
if (window.__INITIAL_STATE__) {
store.replaceState(window.__INITIAL_STATE__)
}
router.onReady(() => {
router.beforeResolve((to, from, next) => {
const matched = router.getMatchedComponents(to)
const prevMatched = router.getMatchedComponents(from)
let diffed = false
const activated = matched.filter((c, i) => {
return diffed || (diffed = (prevMatched[i] !== c))
})
if (!activated.length) {
return next()
}
Promise.all(activated.map(c => {
if (c.asyncData) {
return c.asyncData({ store, route: to })
}
})).then(() => {
next()
}).catch(next)
})
app.$mount('#app')
});
Components
BlogEn.vue
<template>
<div>
<header-component></header-component>
<div class="content" id="content">
<content-component></content-component>
<div class="buffer"></div>
</div>
<footer-component></footer-component>
</div>
</template>
<script>
import Header from '../blanks/Header.vue';
import Content from '../pages/content/blog/Content.vue';
import Footer from '../blanks/Footer.vue';
export default {
data() {
return {
};
},
components: {
'header-component': Header,
'breadcrumbs-component' : Breadcrumbs,
'content-component' : Content,
'footer-component': Footer
},
};
</script>
Content.vue
<template>
<section class="blog">
<div v-for="item in articles">
<p>{{ item.title }}</p>
</div>
</section>
</template>
<script>
export default {
data() {
let obj = {
};
return obj;
},
asyncData({store, route}) {
let params = {
start: 0,
limit: 2,
language: 'ru'
};
return store.dispatch('fetchArticlesList', params);
},
computed: {
articles () {
return this.$store.state.articles;
}
}
};
</script>
When i load page /en/blog
My DOM in browser looks like
<div id="app">
<div id="content" class="content">
<!-- There is should be loop content -->
<div class="buffer"></div>
</div>
<footer></footer>
</div>
But! When i look at source code page and html that server sends to me its OK.
<div id="app">
<div id="content" class="content">
<section class="blog">
<div><p>Article Title</p></div>
<div><p>Article Title 2</p></div>
</section>
<div class="buffer"></div>
</div>
<footer></footer>
</div>
Thats not all. I have other pages in my app that i dont show here. When i move at any page and go to "/en/blog" after that DOM is ok.
What's wrong here?

Related

Vuejs & Auth0 : I need to reload page to be Authenticated

I'm a beginner in Vue, and I implemented Auth0 to my Web App using Vue3.
My issue: after logging in, my API call to retrieve data get an unauthorized error 403. If I reload the page, everything is working fine.
What should I do to avoid reloading the page to get authenticated directly?
Here are my scripts:
Main.js
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import './index.css'
import dayjs from 'dayjs'
import Datepicker from 'vue3-date-time-picker'
import 'vue3-date-time-picker/dist/main.css'
import { setupAuth } from './auth/index.js'
import authConfig from './auth/config.js'
function callbackRedirect(appState) {
router.push(appState && appState.targetUrl ? appState.targetUrl : '/' );
}
setupAuth(authConfig, callbackRedirect).then((auth) => {
let app = createApp(App).use(router);
app.config.globalProperties.$dayjs = dayjs;
app.component('Datepicker', Datepicker);
app.use(auth).mount('#app');
})
My App.vue script:
<template>
<div v-if="isAuthenticated">
<NavBar />
<router-view/>
</div>
</template>
<script>
import NavBar from './components/NavBar.vue'
export default {
components: { NavBar },
data(){
return {
isAuthenticated: false,
}
},
async mounted(){
await this.getAccessToken()
},
methods: {
async getAccessToken(){
try {
const accessToken = await this.$auth.getTokenSilently()
localStorage.setItem('accessToken', accessToken)
this.isAuthenticated = true
} catch (error) {
console.log('Error occured while trying to retrieve Access Token...', error)
}
},
},
}
</script>
and my Home.vue loading the data:
<template>
<div class="home">
<div class="py-10">
<header>
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<h1 class="text-3xl font-bold leading-tight text-gray-900">Monitoring Dashboard</h1>
</div>
</header>
<main>
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
<h3 class="m-5 text-lg leading-6 font-medium text-gray-900">Main KPIs</h3>
<div class="md:grid md:grid-cols-3 md:gap-6">
<div v-for="(item, index) in stats" :key="index" class="md:col-span-1">
<div class="bg-white p-5 border-gray-50 rounded-lg shadow-lg mb-5">
<span class="text-sm font-medium text-gray-500 truncate">{{ item.name }}</span>
<p class="mt-1 text-3xl font-bold text-gray-900">{{ parseFloat(item.stat.toFixed(2)) }}</p>
</div>
</div>
</div>
</div>
</main>
</div>
</div>
</template>
<script>
import _ from 'lodash'
import ProductsService from '../services/products.service'
export default {
name: 'Home',
data(){
return{
user: '',
products: '',
stats: '',
}
},
async mounted(){
await this.readProducts()
await this.buildStats()
},
methods: {
async readProducts(){
let temp = null
try {
temp = await ProductsService.readProducts()
this.products = temp.data
} catch (error) {
console.log('Error: cannot retrieve all products...')
}
},
async buildStats(){
//Nb products
const nbProducts = this.products.length
//Nb offers & Uniq NbRetailers
let nbOffers = 0
let retailers = []
for(let product of this.products){
for(let offer of product.offers){
retailers.push(offer.retailer)
nbOffers += 1
}
}
const nbRetailers = _.uniq(retailers).length
this.stats = [
{ name: 'Number of Retailers', stat: nbRetailers },
{ name: 'Number of Products', stat: nbProducts },
{ name: 'Number of Offers', stat: nbOffers },
]
},
},
watch: {
products: function(){
this.buildStats()
}
}
}
</script>
My ./auth/index.js file:
import createAuth0Client from '#auth0/auth0-spa-js'
import { computed, reactive, watchEffect } from 'vue'
let client
const state = reactive({
loading: true,
isAuthenticated: false,
user: {},
popupOpen: false,
error: null,
})
async function loginWithPopup() {
state.popupOpen = true
try {
await client.loginWithPopup(0)
} catch (e) {
console.error(e)
} finally {
state.popupOpen = false
}
state.user = await client.getUser()
state.isAuthenticated = true
}
async function handleRedirectCallback() {
state.loading = true
try {
await client.handleRedirectCallback()
state.user = await client.getUser()
state.isAuthenticated = true
} catch (e) {
state.error = e
} finally {
state.loading = false
}
}
function loginWithRedirect(o) {
return client.loginWithRedirect(o)
}
function getIdTokenClaims(o) {
return client.getIdTokenClaims(o)
}
function getTokenSilently(o) {
return client.getTokenSilently(o)
}
function getTokenWithPopup(o) {
return client.getTokenWithPopup(o)
}
function logout(o) {
return client.logout(o)
}
export const authPlugin = {
isAuthenticated: computed(() => state.isAuthenticated),
loading: computed(() => state.loading),
user: computed(() => state.user),
getIdTokenClaims,
getTokenSilently,
getTokenWithPopup,
handleRedirectCallback,
loginWithRedirect,
loginWithPopup,
logout,
}
export const routeGuard = (to, from, next) => {
const { isAuthenticated, loading, loginWithRedirect } = authPlugin
const verify = () => {
// If the user is authenticated, continue with the route
if (isAuthenticated.value) {
return next()
}
// Otherwise, log in
loginWithRedirect({ appState: { targetUrl: to.fullPath } })
}
// If loading has already finished, check our auth state using `fn()`
if (!loading.value) {
return verify()
}
// Watch for the loading property to change before we check isAuthenticated
watchEffect(() => {
if (loading.value === false) {
return verify()
}
})
}
export const setupAuth = async (options, callbackRedirect) => {
client = await createAuth0Client({
...options,
})
try {
// If the user is returning to the app after authentication
if (
window.location.search.includes('code=') &&
window.location.search.includes('state=')
) {
// handle the redirect and retrieve tokens
const { appState } = await client.handleRedirectCallback()
// Notify subscribers that the redirect callback has happened, passing the appState
// (useful for retrieving any pre-authentication state)
callbackRedirect(appState)
}
} catch (e) {
state.error = e
} finally {
// Initialize our internal authentication state
state.isAuthenticated = await client.isAuthenticated()
state.user = await client.getUser()
state.loading = false
}
return {
install: (app) => {
app.config.globalProperties.$auth = authPlugin
},
}
}

Vue-router navigation Guard

I wanna make a router guard but I don't know why I cant.
setAuthentication ==true if part is okay but else part is not.
I want KrediForm page cant reachable only when setAuthentication is true
This code must be work but it won't work ı don't know why
Is there another way to make a router guard
IF you don't understand pls contact me
Now I have this code
<template>
<div>
<h1>Login page</h1>
<input type="text" name="username" v-model="input.username" placeholder="Username" />
<input type="password" name="password" v-model="input.password" placeholder="Password" />
<button type="button" #click="login">Login</button>
</div>
export default {
name: 'Login',
data() {
return {
input: {
username: "",
password: ""
}
}
},
methods: {
login() {
if(this.input.username == "admin" && this.input.password == "pass") {
this.$store.commit("setAuthentication", true);
this.$router.replace({ name: "KrediForm"});
// HERE WORKS FOR ME
} else {
console.log("The username or password is not correct");
}
}
}
}
main.js file
import { createApp } from 'vue';
import Vue3Autocounter from 'vue3-autocounter';
import VuePaycard from "vue-paycard";
import router from "#/router";
import Vuex from 'vuex'
import App from './App.vue';
import "#/assets/css/starter_style.css";
import "#/assets/css/main.css";
import veProgress from "vue-ellipse-progress";
const store = new Vuex.Store(
{
state: {
authenticated: false
},
mutations: {
setAuthentication(state, status) {
state.authenticated = status;
}
}
}
)
const app = createApp(App);
app.component('vue3-autocounter', Vue3Autocounter)
app.use(router);
app.use(Vuex);
app.use(veProgress);
app.use(VuePaycard);
app.use(store);
app.mount("#app");
router.js this is what trouble me the last few days
import {createRouter, createWebHistory} from "vue-router";
import store from '#/main'
const routes = [
{
name: "KrediForm",
path: "/Kredi_Form",
component: () => import("#/views/Kredi_Form"),
<!-- HERE MY ISSUE -->
beforeRouteEnter: (to, from, next) => {
if(store.state.authenticated == true) {
next({name: 'Login'});
console.log
} else {
next();
}
}
},
{
name: "DownloadSection",
path: "/DownloadSection",
component: () => import("#/views/DownloadSection")
},
{
name: "deneme",
path: "/deneme",
component: () => import("#/views/deneme"),
},
];
const router = createRouter({
routes,
history: createWebHistory()
});
// Template must be like
// router.beforeEach((to, from, next) => {
// if(loggedIn && to.path !== '/login') {
// next();
// } else {
// next('/login');
// }
// })
export default router;
first i think you are using pre-route guard wrong. keyword in here is beforeEnter and not beforeRouteEnter based on docs.
also you need to export and import properly like this:
export
export const store = ...
import
import {store} from '#/main'
this
solved my problem, copy that

How to call a namespaced Vuex action in Nuxt

I am building an app using NUXT js. I am also using the store module mode because using classic mode returned some depreciation issue.
The PROBLEM is I get [vuex] unknown mutation type: mobilenav/showmobilenav error in my console.
so below are my stores
store/index.js
export const state = () => ({
})
export const mutations = ({
})
export const actions = ({
})
export const getters = ({
})
store/mobilenav.js
export const state = () => ({
mobilenav: false
})
export const mutations = () => ({
showmobilenav(state) {
state.mobilenav = true;
},
hidemobilenav(state) {
state.mobilenav = false;
}
})
export const getters = () => ({
ismobilenavvisible(state) {
return state.dropdown;
}
})
the VUE file that calls the mutation
<template>
<div class="bb" #click="showsidenav">
<img src="~/assets/svg/burgerbar.svg" alt="" />
</div>
</template>
<script>
export default {
methods: {
showsidenav() {
this.$store.commit("mobilenav/showmobilenav");
console.log("sidenav shown");
},
},
}
</script>
<style scoped>
</style>
Here is a more detailed example on how to write it.
/store/modules/custom_module.js
const state = () => ({
test: 'default test'
})
const mutations = {
SET_TEST: (state, newName) => {
state.test = newName
},
}
const actions = {
actionSetTest({ commit }, newName) {
commit('SET_TEST', newName)
},
}
export const myCustomModule = {
namespaced: true,
state,
mutations,
actions,
}
/store/index.js
import { myCustomModule } from './modules/custom_module'
export default {
modules: {
'custom': myCustomModule,
},
}
/pages/test.vue
<template>
<div>
<button #click="actionSetTest('updated test')">Test the vuex action</button>
</div>
</template>
<script>
import { mapActions } from 'vuex'
export default {
methods: {
...mapActions('custom', ['actionSetTest']),
}
</script>

Why dynamic component is not working in vue3?

Here is a working Vue2 example:
<template>
<div>
<h1>O_o</h1>
<component :is="name"/>
<button #click="onClick">Click me !</button>
</div>
</template>
<script>
export default {
data: () => ({
isShow: false
}),
computed: {
name() {
return this.isShow ? () => import('./DynamicComponent') : '';
}
},
methods: {
onClick() {
this.isShow = true;
}
},
}
</script>
Redone under Vue3 option does not work. No errors occur, but the component does not appear.
<template>
<div>
<h1>O_o</h1>
<component :is="state.name"/>
<button #click="onClick">Click me !</button>
</div>
</template>
<script>
import {ref, reactive, computed} from 'vue'
export default {
setup() {
const state = reactive({
name: computed(() => isShow ? import('./DynamicComponent.vue') : '')
});
const isShow = ref(false);
const onClick = () => {
isShow.value = true;
}
return {
state,
onClick
}
}
}
</script>
Has anyone studied the vue2 beta version? Help me please. Sorry for the clumsy language, I use Google translator.
Leave everything in the template as in Vue2
<template>
<div>
<h1>O_o</h1>
<component :is="name"/>
<button #click="onClick">Click me !</button>
</div>
</template>
Change only in "setup" using defineAsyncComponent
You can learn more about defineAsyncComponent here
https://labs.thisdot.co/blog/async-components-in-vue-3
const isShow = ref(false);
const name = computed (() => isShow.value ? defineAsyncComponent(() => import("./DynamicComponent.vue")) : '')
const onClick = () => {
isShow.value = true;
}
Try this
import DynamicComponent from './DynamicComponent.vue'
export default {
setup() {
const state = reactive({
name: computed(() => isShow ? DynamicComponent : '')
});
...
return {
state,
...
}
}
}
The issue with this seems to be to do with the way we register components when we use the setup script - see the official docs for more info. I've found that you need to register the component globally in order to reference it by string in the template.
For example, for the below Vue component:
<template>
<component :is="item.type" :item="item"></component>
</template>
<script setup lang="ts">
// Where item.type contains the string 'MyComponent'
const props = defineProps<{
item: object
}>()
</script>
We need to register the component in the main.ts, as such:
import { createApp } from 'vue'
import App from './App.vue'
import MyComponent from './MyComponent.vue'
var app = createApp(App);
app.component('MyComponent', MyComponent)
app.mount('#app')
Using 'watch' everything works.
<template>
<component :is="componentPath"/>
</template>
<script lang="ts">
import {defineComponent, ref, watch, SetupContext} from "vue";
export default defineComponent({
props: {
path: {type: String, required: true}
},
setup(props: { path: string }, context: SetupContext) {
const componentPath = ref("");
watch(
() => props.path,
newPath => {
if (newPath !== "")
import("#/" + newPath + ".vue").then(val => {
componentPath.value = val.default;
context.emit("loaded", true);
});
else {
componentPath.value = "";
context.emit("loaded", false);
}
}
);
return {componentPath};
}
});
</script>

failed to configure axios with django rest auth to login and get auth token

I tried these codes:
src/api/auth.js
import session from "./session";
export default {
login(Username, Password) {
return session.post("/auth/login/", { Username, Password });
},
logout() {
return session.post("/auth/logout/", {});
},
createAccount(username, password1, password2, email) {
return session.post("/registration/", {
username,
password1,
password2,
email
});
},
changeAccountPassword(password1, password2) {
return session.post("/auth/password/change/", { password1, password2 });
},
sendAccountPasswordResetEmail(email) {
return session.post("/auth/password/reset/", { email });
},
resetAccountPassword(uid, token, new_password1, new_password2) {
// eslint-disable-line camelcase
return session.post("/auth/password/reset/confirm/", {
uid,
token,
new_password1,
new_password2
});
},
getAccountDetails() {
return session.get("/auth/user/");
},
updateAccountDetails(data) {
return session.patch("/auth/user/", data);
},
verifyAccountEmail(key) {
return session.post("/registration/verify-email/", { key });
}
};
src/session.js
import axios from "axios";
const CSRF_COOKIE_NAME = "csrftoken";
const CSRF_HEADER_NAME = "X-CSRFToken";
const session = axios.create({
xsrfCookieName: CSRF_COOKIE_NAME,
xsrfHeaderName: CSRF_HEADER_NAME
});
export default session;
src/store/auth.js
import auth from "../api/auth";
import session from "../api/session";
import {
LOGIN_BEGIN,
LOGIN_FAILURE,
LOGIN_SUCCESS,
LOGOUT,
REMOVE_TOKEN,
SET_TOKEN
} from "./types";
const TOKEN_STORAGE_KEY = "TOKEN_STORAGE_KEY";
const initialState = {
authenticating: false,
error: false,
token: null
};
const getters = {
isAuthenticated: state => !!state.token
};
const actions = {
login({ commit }, { username, password }) {
commit(LOGIN_BEGIN);
return auth
.login(username, password)
.then(({ data }) => commit(SET_TOKEN, data.key))
.then(() => commit(LOGIN_SUCCESS))
.catch(() => commit(LOGIN_FAILURE));
},
logout({ commit }) {
return auth
.logout()
.then(() => commit(LOGOUT))
.finally(() => commit(REMOVE_TOKEN));
},
initialize({ commit }) {
const token = localStorage.getItem(TOKEN_STORAGE_KEY);
if (token) {
commit(SET_TOKEN, token);
} else {
commit(REMOVE_TOKEN);
}
}
};
const mutations = {
[LOGIN_BEGIN](state) {
state.authenticating = true;
state.error = false;
},
[LOGIN_FAILURE](state) {
state.authenticating = false;
state.error = true;
},
[LOGIN_SUCCESS](state) {
state.authenticating = false;
state.error = false;
},
[LOGOUT](state) {
state.authenticating = false;
state.error = false;
},
[SET_TOKEN](state, token) {
localStorage.setItem(TOKEN_STORAGE_KEY, token);
session.defaults.headers.Authorization = `Token ${token}`;
state.token = token;
},
[REMOVE_TOKEN](state) {
localStorage.removeItem(TOKEN_STORAGE_KEY);
delete session.defaults.headers.Authorization;
state.token = null;
}
};
export default {
namespaced: true,
state: initialState,
getters,
actions,
mutations
};
src/views/Login.vue
<template>
<div>
<form class="login" #submit.prevent="login">
<h1>Sign in</h1>
<label>Username</label>
<input required v-model="Username" type="text" placeholder="Name" />
<label>Password</label>
<input
required
v-model="Password"
type="password"
placeholder="Password"
/>
<hr />
<button type="submit">Login</button>
</form>
</div>
</template>
<script>
import axios from "axios";
export default {
data() {
return {
Username: "",
Password: ""
};
},
methods: {
/*login() {
let Username = this.Username;
let Password = this.Password;
this.$store
.dispatch("auth/login", { Username, Password })
.then(() => this.$router.push("/"))
.catch(err => console.log(err));*/
login({ Username, Password }) {
const API_URL = "http://127.0.0.1:8000";
const url = `${API_URL}/auth/login/`;
return axios
.post(url, { Username, Password })
.then(() => this.$router.push("/"))
.catch(err => console.log(err));
}
},
mounted() {
this.login();
}
};
</script>
first, I tried using the auth service but the failure was OPTIONS not POST.
then i used axios directly to post user and get token, but then the failure was method not allowed, I do not know what is the hidden process, can you explain please?
app.vue
<template>
<div id="app">
<navbar v-if="isAuthenticated"></navbar>
<router-view></router-view>
</div>
</template>
<script>
import { mapGetters } from "vuex";
import Navbar from "./components/Navbar";
export default {
name: "app",
components: {
Navbar
},
computed: mapGetters("auth", ["isAuthenticated"])
};
</script>
router.js
import Vue from "vue";
import Router from "vue-router";
import About from "./views/About";
import Home from "./views/Home";
import Login from "./views/Login";
import Lost from "./views/Lost";
import PasswordReset from "./views/PasswordReset";
import PasswordResetConfirm from "./views/PasswordResetConfirm";
import Register from "./views/Register";
import VerifyEmail from "./views/VerifyEmail";
import store from "./store/index";
const requireAuthenticated = (to, from, next) => {
store.dispatch("auth/initialize").then(() => {
if (!store.getters["auth/isAuthenticated"]) {
next("/login");
} else {
next();
}
});
};
const requireUnauthenticated = (to, from, next) => {
store.dispatch("auth/initialize").then(() => {
if (store.getters["auth/isAuthenticated"]) {
next("/home");
} else {
next();
}
});
};
const redirectLogout = (to, from, next) => {
store.dispatch("auth/logout").then(() => next("/login"));
};
Vue.use(Router);
export default new Router({
saveScrollPosition: true,
routes: [
{
path: "/",
redirect: "/home"
},
{
path: "/about",
component: About,
beforeEnter: requireAuthenticated
},
{
path: "/home",
component: Home,
beforeEnter: requireAuthenticated
},
{
path: "/password_reset",
component: PasswordReset
},
{
path: "/password_reset/:uid/:token",
component: PasswordResetConfirm
},
{
path: "/register",
component: Register
},
{
path: "/register/:key",
component: VerifyEmail
},
{
path: "/login",
component: Login,
beforeEnter: requireUnauthenticated
},
{
path: "/logout",
beforeEnter: redirectLogout
},
{
path: "*",
component: Lost
}
]
});
main.js
import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import store from "./store/index";
import axios from "axios";
import Axios from "axios";
import VueAxios from "vue-axios";
import Vuex from "vuex";
Vue.use(Vuex);
Vue.use(VueAxios, axios);
//Vue.config.productionTip = false;
Vue.prototype.$http = Axios;
const token = localStorage.getItem("token");
if (token) {
Vue.prototype.$http.defaults.headers.common["Authorization"] = token;
}
new Vue({
router,
store,
render: h => h(App)
}).$mount("#app");
references:
https://www.techiediaries.com/vue-axios-tutorial/
https://scotch.io/tutorials/handling-authentication-in-vue-using-vuex
https://github.com/jakemcdermott/vue-django-rest-auth
Most likely CORS issues.
If you're serving the vue server on different port then the django server, then you need to set the proper CORS settings.
Please refer to https://github.com/ottoyiu/django-cors-headers/
while it seems my code is little ugly because I mixed bunch of repositories, but at least I made it make POST successfully. I used
npm install qs
then import it, then:
var username = payload.credential.username;
var password = payload.credential.password;
then editing
axios.post(url, qs.stringify({ username, password })
and it worked.