Nuxt / Vuex / Vue 반응성 문제 증가
여러분 안녕하세요 저는 Nuxt와 Vuex와 함께 작업할 때 어려움을 겪고 있습니다.
Vuex / Nuxt Classic Mode 예제를 실행하려고 합니다.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
}
}
스토어 폴더에 포함된 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 빌드에 이어 파이어베이스가 기능하는지 확인했습니다.그것이 도움이 될 수 있는지 어떤지를 조사했습니다.그렇지 않았다.보통 서버 시작은 'npm run dev'입니다.아래 저의 실수를 찾으실 수 있도록 저의 풀 아이디입니다.vue 컴포넌트 및 nuxt.config.config.config.config 파일을 사용할 수 있습니다.아직 꽤 생으로 리팩터링이 많이 필요하기 때문에 잘 정리할 수 있기를 바랍니다.
_.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.displaces
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 }
]
}
store/index.displaces
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 컴포넌트는 그대로이며, 의존관계를 업데이트 받은 후 아래 이미지와 같이 완벽하게 동작합니다.
도와주신 @Bousadjra Brahim, @xaviert, @Andrew1325님 감사합니다.
언급URL : https://stackoverflow.com/questions/53670125/nuxt-vuex-vue-reactivity-issue-increment
'programing' 카테고리의 다른 글
Google Guava vs.아파치 커먼즈 (0) | 2022.08.01 |
---|---|
함수 정의에 대한 질문(파라미터의 점 세 개) (0) | 2022.08.01 |
여러 Vue 인스턴스에 여러 Vue 모듈 인스턴스 필요 (0) | 2022.08.01 |
off_t 타입의 완전한 정의는 어디서 찾을 수 있습니까? (0) | 2022.08.01 |
while(true) 루프가 그렇게 나쁜가요? (0) | 2022.08.01 |