Nuxt / Vuex / Vue反应性问题增量

布莱克鬼

大家好,我在与Nuxt和Vuex合作时遇到了一些困难。

我正在尝试通过示例Vuex / Nuxt经典模式运行。https://nuxtjs.org/guide/vuex-store/

单击我的增量按钮后,我看不到数字上升。我的页面仅停留在0,我可以在控制台中看到状态知道数字不再是0,而是在屏幕上不再显示,就好像它不知道是被动的一样。

我的假设是我错过了某个地方的配置,而我的0不是实际状态,但是我以某种方式创建了它的一些副本。

这是我模板中的按钮。

<button @click="inc">{{ counter }}</button>

这是我方法中的inc函数。

inc () {
  this.$store.commit('increment')
},

这是我计算的

computed: {
  counter () {
    return this.$store.getters.counter
  }
}

这是store文件夹中包含的我的Vuex / index.js文件。

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)

const createStore = () => {
  return new Vuex.Store({
    state: () => ({
      counter: 0
    }),
    getters: {
       counter: state => state.counter
    },
    mutations: {
      increment (state) {
        state.counter++
      }
    }
  })
}

export default createStore

商业摄影

更新:包括更多代码段,并回复了现有注释。

@Boussadjra Brahim @xaviert,谢谢你们的参与,感谢您的帮助。

@Boussadjra Brahim-是的,我曾尝试使用一种称为变异的动作,但似乎也无法使我到达那里。我还尝试仅通过动作来调整状态,并且无法进行任何更改,但是这似乎是正确的,因为我的印象是动作需要通过突变来进行状态更改,而不是自己进行更改,请纠正我了解更多。我对未正确尝试的想法持100%的态度。以下是没有做任何事情的动作,以及称为突变的动作

actions: {
  increment (state) {
    state.counter++
  }
},   

这是带有称为突变的动作的版本。

actions: {
  incrementCounterUp () {
    this.commit('increment')
  }
},

@xaviert-我尝试过重新启动服务器,并且还尝试查看是否在nuxt构建之后加上firebase服务,以查看是否有帮助。它没有。我正常的服务器启动是“ npm run dev”。希望您/其他任何人都能在下面找到我的错误是我完整的_id.vue组件以及我的nuxt.config.js文件,也许就是这样。它仍然很原始,可以使用很多重构,因此希望您可以对它进行足够的整理。

_.id.vue

<template>
  <div class="product">
    <div class="product-image">
      <div class="product-image-img">
        <img v-bind:src="product.image_file" width="450px;"/>
      </div>
    </div>
    <div class="product-details-wrapper">
      <div class="product-details">
        <h1>
          <div v-if="this.$route.query.editPage">
            <textarea @input="updateTextArea" ref="textarea2" v-model="product.item_name" type="text" />
          </div>
          <div v-else>{{product.item_name}}</div>
        </h1>
        <div class="product-description">
          <div class="product-description-text" v-if="this.$route.query.editPage">
            <textarea @input="updateTextArea" ref="textarea" v-model="product.description" type="text" />
          </div>
          <div class="product-description-text" v-else v-html="product.description"></div>
        </div>
        <p class="product-brand"><strong>Brand - </strong> {{product.brand_name}}</p>
        <hr />
        <div class="product-price">
          <div v-if="this.$route.query.editPage">
            <strong>Original Price - </strong>
            <input v-model="product.msrp" type="text" />
          </div>
          <div v-else class="product-msrp">
            <strong>Original Price - </strong>
            <span class="strike">${{product.msrp}}</span>
          </div>
          <div v-if="this.$route.query.editPage">
            <strong>Sale Price - </strong>
            <input v-model="product.price" type="text" />
          </div>
          <div v-else class="product-sale-price">
            <strong>Sale Price - </strong>
            <span class="">${{product.price}}</span>
          </div>
          <div class="product-price">
            Quantity x
            <input @input="updateQuantity" v-model="quantity" min="1" class="" type="number" value="1" />
          </div>
          <button @click="inc">{{ counter }}</button>
        </div>
      </div>
    </div>
    <div v-if="this.$route.query.editPage" class="update-product">       <button @click="updateProduct(product)">Update</button></div>
    <div class="footer">
      <router-link to="/privacy-policy" target="_blank">Privacy</router-link> |
      <router-link to="/terms" target="_blank">Terms</router-link>
    </div>

  </div>
</template>

<script>
// @ is an alias to /src

import firebase from '@/services/fireinit'
import foo from '@/components/foo'
const db = firebase.firestore()
export default {
  name: 'ProductPage',
  head () {
    return {
      title: this.product.item_name
    }
  },
  components: {
    foo
  },
  data: function () {
    return {
      product: {},
      image: '',
      name: 'Checkout',
      description: '',
      currency: 'USD',
      amount: '',
      msrp: '',
      quantity: 1
    }
  },
  methods: {
    inc () {
      this.$store.dispatch('incrementCounterUp', true)
    },
    updateProduct: function (product) {
      db.collection('products').doc(product.item_id).set(product)
        .then(function () {
          console.log('Document successfully written!')
        })
        .catch(function (error) {
          console.error('Error writing document: ', error)
        })
    },
    updateQuantity () {
      this.product.msrp = (this.quantity * this.product.orgMsrp)
      this.product.msrp = Math.round(100 * this.product.msrp) / 100
      this.product.price = this.quantity * this.product.orgPrice
      this.product.price = Math.round(100 * this.product.price) / 100
    },
    updateTextArea () {
      this.$refs.textarea.style.minHeight = this.$refs.textarea.scrollHeight + 'px'
      this.$refs.textarea2.style.minHeight = this.$refs.textarea2.scrollHeight + 'px'
    }
  },
  async asyncData({app, params, error}) {
    const ref = db.collection("products").doc(params.id)
    let snap
    let thisProduct = {}
    try {
      snap = await ref.get()
      thisProduct = snap.data()
      thisProduct.orgMsrp =  thisProduct.msrp
      thisProduct.orgPrice =  thisProduct.price
    } catch (e) {
      // TODO: error handling
      console.error(e)
    }
    return {
      product: thisProduct
    }
  },
  mounted () {
    if(this.$refs.textarea) {
      this.$refs.textarea.style.minHeight = this.$refs.textarea.scrollHeight + 'px'
      this.$refs.textarea2.style.minHeight = this.$refs.textarea2.scrollHeight + 'px'
    }
  },
  computed: {
    counter () {
      return this.$store.getters.counter
    }
  }
}
</script>


<style lang="less">
body {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  color: #2c3e50;
  margin: 0
}
p{
  margin-top: 1em;
  margin-bottom: 1em;
}
html, body, #__nuxt, #__layout, .default,  .product{
  height: 100%;
}
.product {
  justify-content: center;
  display: flex;
  max-width: 1150px;
  margin: 0 auto;
  flex-wrap: wrap;
  align-items: center;
  padding: 0 24px;
  &-price{
    input {
      border: 1px solid;
      padding: 0 .3em;
      text-align: center;
      width: 50px;
    }
  }
}
  .product-details{
    width: 100%;
    textarea {
      width: 100%;
      font-size: inherit;
      color: inherit;
      font-family: inherit;
      font-weight: inherit;
      height: initial;
      resize: none;
      background-color: transparent;
      border: none;
    }
    h1{
      font-size: 1.9rem;
      margin: 15px 0 20px;
    }
    hr{
      width: 50%;
      margin: .5rem 0px;
    }
    p{

    }
  }
  .product-description-text{
    margin: 10px 0;
  }
  .product-image, .product-details-wrapper{
    align-items: center;
    display: flex;
    justify-content: center;
  }
  .product-details-wrapper{
    flex: 0 1 535px;
  }
  .product-image{
    flex: 0 1 535px;
    img{
      width: 100%;
    }
  }
  .product-price{
    .strike{
      text-decoration: line-through;
    }
    button{
      display: flex;
      width: 150px;
      height: 50px;
      border-radius: 5px;
      justify-content: center;
      font-size: 24px;
      margin-top: 20px;
      &:hover{
        cursor: pointer;
        background-color: #f1f1f1;
        box-shadow: 3px 3px 11px -1px rgba(0, 0, 0, 0.48);
      }
    }
  }
  .product-sale-price{
    color: #f30000;
  }
  .footer {
    flex: 1 1 100%;
    text-align: center;
    color: #ccc;
    margin-top: 25px;
    padding: 15px;
    a {
      color: #ccc;
      text-decoration: none;
      &:hover{
        text-decoration: underline;
      }
    }
  }
  .update-product{
    position: absolute;
    top: 0;
    text-align: center;
  }

</style>

nuxt.confgs.js

const pkg = require('./package')
const { STRIPE_TOKEN } = process.env;

module.exports = {
  vue: {
    config: {
      productionTip: false,
      devtools: true
    }
  },
  buildDir: './functions/nuxt',
  mode: 'universal',

  /*
  ** Headers of the page
  */
  head: {
    title: pkg.name,
    meta: [
      { charset: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1' },
      { hid: 'description', name: 'description', content: pkg.description }
    ],
    link: [
      { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
    ]
  },

  /*
  ** Customize the progress-bar color
  */
  loading: { color: '#fff' },

  /*
  ** Global CSS
  */
  css: [
  ],

  /*
  ** Plugins to load before mounting the App
  */

  /*
  ** Nuxt.js modules
  */
  modules: [
    // Doc: https://github.com/nuxt-community/axios-module#usage
    '@nuxtjs/axios',
    'nuxt-stripe-module'
  ],
  stripe: {
    version: 'v3',
    publishableKey: 'pk_test_XXX',
  },
  /*
  ** Axios module configuration
  */
  axios: {
    // See https://github.com/nuxt-community/axios-module#options
  },

  /*
  ** Build configuration
  */
  build: {
    /*
    ** You can extend webpack config here
    */
    publicPath: '/public/',
    vendor: [],
    extractCSS: true,
    bable: {
      presets: [
        'es2015',
        'stage-8'
      ],
      plugins: [
        ['transform-runtime', {
          'polyfill': true,
          'regenerator': true
        }]
      ]
    },
    extend (config, { isDev }) {
      if (isDev && process.client) {
        config.module.rules.push({
          enforce: 'pre',
          test: /\.(js|vue)$/,
          loader: 'eslint-loader',
          exclude: /(node_modules)/
        })
      }
    },
    router: {
      middleware: 'router-auth'
    }
  },
  plugins: [
    { src: '~/plugins/fireauth', ssr: true }
  ]
}

商店/index.js

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)

const createStore = () => {
  return new Vuex.Store({
    state: () => ({
      counter: 0
    }),
    actions: {
      incrementCounterUp () {
        this.commit('increment')
      }
    },
    getters: {
      counter: state => state.counter
    },
    mutations: {
      increment (state) {
        state.counter++
      }
    }
  })
}

export default createStore
布莱克鬼

最终,我无法准确确定应用程序中的错误。

我假设我在初始化,配置或开发过程中碰到了不应该碰到的东西,安装了不应该安装的东西,弄乱了我不应该拥有的软件包,或者在nuxt.config.js更改中加粗了。

按照相同的安装说明,我创建了一个新的nuxt应用程序。https://nuxtjs.org/guide/installation/

完全按原样移动上面的_id.vue组件,一旦更新了依赖项,它就可以正常工作,如下图所示。

非常感谢@Boussadjra Brahim,@ xaviert和@ Andrew1325为您提供的帮助。

在此处输入图片说明

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

Vuex getter 反应性问题(结合 Vue 路由器)

nuxt Auth模块和vuex-persist是否存在任何可比性问题?

在Nuxt JS vuex中使用Vue Router进行重定向

从Vuex商店使用NUXT中的vue-apollo访问this。$ apollo?

Nuxt:在Vue.js组件之外的Vuex提交或调度消息

Vuex,Nuxt:未知操作类型

何时使用 vuex(在 Nuxt 中)?

使用Nuxt / Vuex / Vue检测用户是否通过浏览器的后退按钮导航到路线

Nuxt / Vue - 不要在变异处理程序之外改变 vuex 存储状态

如何在状态Vuex / Vue / Nuxt中添加新的属性对象

将Vuex与Nuxt和Vue-Native-Websocket一起使用

在nuxt vuex中提交未定义

用Jest测试Nuxt + Vuex + Vuetify的设置

在Nuxt中找不到Vuex模块动作

使用Nuxt从组件访问Vuex存储状态

Vuex商店在Nuxt中驻留的位置

Nuxt获取中的Vuex动作“不是功能”

在Vuex / Nuxt中绑定选择表单

Nuxt Vuex 商店中的未知操作类型

用Jest测试NUXT.js和Vue.js应用程序。获取“在mapState()中找不到[vuex]模块名称空间”和“ [vuex]未知操作类型”

错误:[vuex]不在变异处理程序vuex(nuxt.js)外部变异vuex存储状态

在命名空间存储中分派操作(Vuex / Nuxt)

使用Nuxt.js在Vuex中预提取api数据

Nuxt 使用 vuex 和多语言站点生成

检测vuex状态更改以在nuxt布局内执行方法

为什么 nuxt 返回 mutate vuex 存储错误

NUXT Vuex更改状态值返回存储状态错误

在 Nuxt 商店 (vuex) 中使用 window.open

如何在vuex nuxt中获取嵌套的吸气剂