とりあえず一番初めに書くだろうカウンタアプリを少しだけVuetifyっぽく書いてみました。
結論から言うと、store(Vuex)からVuetifyは普通には見えません。
今回は最上位のVueで、特定のstoreインスタンスに$vuetifyを無理矢理埋め込みました。
html
1 <! DOCTYPE html >
2 < html lang = " ja " >
3
4 < head >
5 < link href = " https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900 " rel = " stylesheet " >
6 < link href = " https://cdn.jsdelivr.net/npm/@mdi/font@5.x/css/materialdesignicons.min.css " rel = " stylesheet " >
7 < link href = " https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.min.css " rel = " stylesheet " >
8 < meta name = " viewport " content = " width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, minimal-ui " >
9 </ head >
10
11 < body >
12 < div id = " app " > </ div >
13 </ body >
14 < script src = " https://cdn.jsdelivr.net/npm/vue/dist/vue.js " > </ script >
15 < script src = " https://unpkg.com/vuex " > </ script >
16 < script src = " https://unpkg.com/vuex " > </ script >
17 < script src = " https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.js " > </ script >
18 < script >
19 Vue . use ( Vuex ) ;
20 Vue . use ( Vuetify ) ;
21 const store = new Vuex . Store ( {
22 state : {
23 count : 0 ,
24 } ,
25 mutations : {
26 increment ( state ) {
27 console . log ( 'from store' ) ;
28 console . log ( this . $vuetify ) ;
29 state . count ++ ;
30 }
31 }
32 } ) ;
33 const Counter = {
34 name : 'Counter' ,
35 template : ` <v-card>
36 <v-card-title>{{count}}</v-card-title>
37 <v-card-actions @click="increment()">
38 <v-btn text>increment</v-btn>
39 </v-card-actions>
40 </v-card> ` ,
41 computed : {
42 count : function ( ) {
43 return this . $store . state . count ;
44 } ,
45 } ,
46 methods : {
47 increment : function ( ) {
48 console . log ( 'from counter' ) ;
49 console . log ( this . $vuetify ) ;
50 this . $store . commit ( 'increment' ) ;
51 } ,
52 }
53 } ;
54 new Vue ( {
55 template : ` <v-app class="app">
56 <v-main>
57 <v-container>
58 <counter/>
59 </v-container>
60 </v-main>
61 </v-app> ` ,
62 el : "#app" ,
63 store : store ,
64 vuetify : new Vuetify ( ) ,
65 components : {
66 "counter" : Counter ,
67 } ,
68 created : function ( ) {
69 // 無理矢理入れる
70 this . $store . $vuetify = this . $vuetify ;
71 }
72 } ) ;
73 </ script >
74
75 </ html >
追記
長々と書くのもアレだったので短く書きすぎました。解決後ですが追記しておきます。
まず、nuxt.jsを使ったもので説明します。
npx create-nuxt-app sample-nuxt
を↓な感じで作ります。
text
1 create-nuxt-app v3.2.0
2 ✨ Generating Nuxt.js project in sample-nuxt
3 ? Project name: sample-nuxt
4 ? Programming language: JavaScript
5 ? Package manager: Npm
6 ? UI framework: Vuetify.js
7 ? Nuxt.js modules: (Press <space> to select, <a> to toggle all, <i> to invert selection)
8 ? Linting tools: (Press <space> to select, <a> to toggle all, <i> to invert selection)
9 ? Testing framework: None
10 ? Rendering mode: Single Page App
11 ? Deployment target: Server (Node.js hosting)
12 ? Development tools: (Press <space> to select, <a> to toggle all, <i> to invert selection)
次に以下のファイルを作ったり、置き換えたりします。
pages/index.vue
vue
1 <template>
2 <v-container>
3 <counter />
4 </v-container>
5 </template>
6
7 <script>
8 import Counter from "~/components/Counter.vue";
9
10 export default {
11 components: {
12 Counter,
13 },
14 };
15 </script>
components/Counter.vue
vue
1 <template>
2 <v-card>
3 <v-card-title>{{ count }}</v-card-title>
4 <v-card-actions>
5 <v-btn text @click="increment()">increment</v-btn>
6 <v-btn text @click="push()">push</v-btn>
7 </v-card-actions>
8 </v-card>
9 </template>
10
11 <script>
12 import { mapMutations, mapGetters } from 'vuex'
13
14 export default {
15 name: "Counter",
16 computed: {
17 count: function () {
18 return this.$store.getters['counterstore/count'];
19 },
20 },
21 methods: {
22 increment: function () {
23 console.log("vue_component: this.$vuetify=" + this.$vuetify);
24 this.$store.commit("counterstore/increment");
25 },
26 push: function () {
27 this.$store.commit("counterstore/push", this.$vuetify);
28 },
29 },
30 };
31 </script>
store/counterstore.js
javascript
1 export const state = ( ) => ( {
2 counter : 0
3 } )
4
5 export const mutations = {
6 increment ( state ) {
7 state . counter ++ ;
8 console . log ( "store_increment: this.$vuetify =" + this . $vuetify ) ;
9 } ,
10 push ( state , args ) {
11 // 無理矢理受け渡す
12 this . $vuetify = args ;
13 console . log ( "store_push: this.$vuetify is set!" ) ;
14 }
15 }
16
17 export const getters = {
18 count ( state ) {
19 if ( this != null ) {
20 console . log ( 'store_getters: this.$vuetify =' + this . $vuetify ) ;
21 } else {
22 console . log ( 'store_getters: this =' + this ) ;
23 }
24 return state . counter ;
25 } ,
26 }
動かすと、初期画面がこんな感じになります。
consoleの表示は、
text
1 store_getters: this =undefined
な感じです。gettersでは呼出元が関数呼出してるので、thisが入っていません。
まずgettersを使うとthis.$vuetifyは無理なのですよ。
次にINCREMENTボタンを押します。するとconsoleは
text
1 vue_component: this.$vuetify=[object Object]
2 store_increment: this.$vuetify =undefined
3 store_getters: this =undefined
と出ています。vueコンポーネントからはthis.$vuetifyが入っていますが、生成時にプラグインからそういうのを入れるカラクリがないstoreにはthis.$vuetifyが入っていないのが分かります。
仕方がないので実装したPUSHボタンを押すと...
text
1 store_push: this.$vuetify is set!
引数で無理矢理コンポーネントから参照してたvuetifyのインスタンスを渡されるので、storeにvuetifyが設定されます。
再度INCREMENTを押すと...
text
1 vue_component: this.$vuetify=[object Object]
2 store_increment: this.$vuetify =[object Object]
3 store_getters: this =undefined
store側のincrementでthis.$vuetifyが入ってることが分かります。getterでは相変わらず見えませんが...
つまり、Vueコンポーネントでは見えるthis.$vuetifyも、Vuexからはインスタンス生成しただけでは見えない ということです。またgettersからはどうやっても見えません(Vue.prototype.$vuetifyも駄目でした。今はそういう渡し方じゃないのかも)。で、それを伝えようとしたのが最初のコードだったわけです。なお、この辺TypeScriptだとまた事情が変わるかもです。そのクラス表記はさらに不明です。
長文失礼しました。詳しい部分じゃないので、間違ってたら指摘お願いします。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/08/17 12:57