前提・実現したいこと
現在vueを使ってnewsを取得するアプリを作っています。
newsapiを使い、サイドバーに用意したカテゴリー(スポーツや政治など)の中から選択したものをページに表示したいと考えています。
詰まっているのはvuexを使ったmutationの部分です。module内でstate(サイドバーに格納するカテゴリーと、選択されているカテゴリーが入っています。)を作るまではできたのですが、mutationで選択されているカテゴリー(activeCategoryとしています)が更新できず詰まっています。
詳しい方いらっしゃいましたら教えていただきたいです。
該当のソースコード
ソースツリーは以下の通りです。
store
--index.js
--module
----news.js
components
--Header.vue
--atoms
----item.vue
それぞれのコードは以下の通りです。
store/index.vue
import Vue from 'vue' import Vuex from 'vuex' import news from './modules/news' Vue.use(Vuex) const debug = process.env.NODE_ENV !== 'production' export default new Vuex.Store({ modules: { news, }, strict: debug, })
store/module/news.js
// initial state const state = () => ({ newsData: { "home": "Home", "sport": "Sports", "business": "Business", "tech": "Technology", "finance": "Finance", "entertainment": "Entertainment", }, activeCategory: "sport", bookmarkData:[] }) // getters const getters = {} // actions const actions = { } // mutations const mutations = { changeCategory(state, newCategory) { // 状態を変更する state.activeCategory = newCategory.categoryName } } export default { namespaced: true, state, getters, actions, mutations }
components/Header.vue
<template> <v-app> <!-- ここにヘッダーをコーディング --> <header> <v-app-bar app dark > <v-app-bar-nav-icon @click="drawer = true"></v-app-bar-nav-icon> <v-toolbar-title>Vue-News</v-toolbar-title> <div class="textField"> <v-text-field hide-details append-icon="mdi-magnify" single-line ></v-text-field> </div> </v-app-bar> <v-navigation-drawer v-model="drawer" fixed temporary > <v-list nav dense > <v-list-item-group> <v-list-item v-for="(menuItem, index) in menuItems" :key="index" > <v-list-item-title @click="changeCategory(menuItem)">{{ menuItem }}</v-list-item-title> </v-list-item> </v-list-item-group> </v-list> </v-navigation-drawer> </header> </v-app> </template> <script> //import { mapMutations } from 'vuex' export default { data () { return { drawer: false, menuItems: this.$store.state.news.newsData } }, methods: { changeCategory(category) { this.$store.commit({ type: 'changeCategory', categoryName: category }) } } } </script> <style lang="sass"> .textField margin-left: 40px width: 300px </style>
components/atoms/item.vue
<template> <div class="itemField"> <div v-for="(result, index ) in results" :key="index"> <ul> <li> <a :href="`${result.url}`"> <v-card class="mx-auto card" max-width="400" height="400" :src="result.url" color="rgb(255, 0, 0, 0)" > <v-img class="white--text align-end" height="200px" :src="result.urlToImage" > </v-img> <v-card-title>{{ result.title }}</v-card-title> <v-card-actions> <v-btn color="orange" text > Share </v-btn> <v-btn color="orange" text > Explore </v-btn> </v-card-actions> </v-card> </a> </li> </ul> </div> </div> </template> <script> import axios from 'axios' //import constants from '@/common/constants' /* import store from '../../store/modules/news.js' */ const key = '540c0a2d08264331b2101b7c7169ed92' export default { data () { return { results:[] } }, mounted(){ /* const obj = constants.menuItems; let activeCategory = obj.find(o=> o.active === true); let category = activeCategory.value; */ let activeCategory = this.$store.state.news.activeCategory axios.get('https://newsapi.org/v2/top-headlines?country=jp&category=' + activeCategory + '&apiKey='+ key) .then(response => { this.results = response.data.articles; }) console.log(this.results); } } </script> <style lang="sass"> .card margin: 80px 30px 30px 30px .itemField display: flex max-width: 100vw ul list-style: none a text-decoration: none color: #000000 &:link, &:visited, &:hover, &:active color: #000000 .transparent background-color: blue!important .v-card width: 100% max-width: 600px background-color: none background: radial-gradient(100% 100% at 0% 0%, rgba(255, 255, 255, 0.4) 0%, rgba(255, 255, 255, 0) 100%) border: 1px solid rgba(255, 255, 255, 0.4) /* ボーダー */ border-right-color: rgba(255, 255, 255, 0.2) border-bottom-color: rgba(255, 255, 255, 0.2) border-radius: 15px -webkit-backdrop-filter: blur(20px) /* ぼかしエフェクト */ backdrop-filter: blur(20px) box-shadow: 0 5px 20px rgba(255, 152, 79, 0.5) /* 薄い影 */ </style>
試したこと
vuexを触るのが初めてなので、サイトなどを見て、mapmutationなども試したのですが、どうもうまくいきません。
apiの取得をmountedでしているのが悪いのかとも思ったのですが、エラーも出ないため解決できませんでした。
補足情報(FW/ツールのバージョンなど)
vue2
vuex
vuetify
M1
あなたの回答
tips
プレビュー