Vue.js 在VueJs中创建配方并存储在localstorage中

Vue.js 在VueJs中创建配方并存储在localstorage中,vue.js,vuetify.js,Vue.js,Vuetify.js,这是一个食品配方项目,通过它可以执行许多操作,例如删除、创建配方和添加,但添加配方时,会重复两个配方,如图所示。 如何解决这个问题 CreateRecipe.vue: <template> <v-app> <v-container> <v-layout row> <v-flex xs12 sm6 offset-sm3> <h2 class="btn-style&

这是一个食品配方项目,通过它可以执行许多操作,例如删除、创建配方和添加,但添加配方时,会重复两个配方,如图所示。 如何解决这个问题

CreateRecipe.vue:

<template>
  <v-app>
    <v-container>
      <v-layout row>
        <v-flex xs12 sm6 offset-sm3>
          <h2 class="btn-style">Create Recipe</h2>
        </v-flex>
      </v-layout>
      <v-layout row>
        <v-flex xs12>
          <form @submit.prevent="onCreateRecipe">    
             <v-layout>
              <v-flex xs12 sm6 offset-sm3>
                <v-text-field
                  name="title"
                  label="Title"
                  id="title"
                  v-model="title"
                  color="#43A047"
                  required
                >
                </v-text-field>
              </v-flex>
            </v-layout>
            <v-layout>
              <v-flex xs12 sm6 offset-sm3>
                <v-text-field
                  name="imageUrl"
                  label="ImageUrl"
                  id="imageUrl"
                  v-model="imageUrl"
                  color="#43A047"
                  required
                >
                </v-text-field>
              </v-flex>
            </v-layout>
            <v-layout>
              <v-flex xs12 sm6 offset-sm3>
                <img :src="imageUrl" height="300px" />
              </v-flex>
            </v-layout>
            <v-layout>
              <v-flex xs12 sm6 offset-sm3>
                <v-text-field
                  name="description"
                  label="Description"
                  id="description"
                  v-model="description"
                  color="#43A047"
                  multi-line
                  required
                >
                </v-text-field>
              </v-flex>
            </v-layout>
            <v-layout>
              <v-flex xs12 sm6 offset-sm3>
                <v-text-field
                  name="ingredients"
                  label="Ingredients"
                  id="ingredients"
                  v-model="ingredients"
                  color="#43A047"
                  multi-line
                  required
                >
                </v-text-field>
              </v-flex>
            </v-layout>
            <v-layout row>
              <v-flex xs12 sm6 offset-sm3>
                <v-btn
                  class="green darken-1 color"
                  :disabled="!formIsValid"
                  type="submit"
                >
                  Create Redcipe
                </v-btn>
              </v-flex>
            </v-layout>
          </form>
        </v-flex>
      </v-layout>
    </v-container>
  </v-app>
</template>
<script>
export default {
  data() {
    return {
      // id:"",
      title: "",
      imageUrl: "",
      description: "",
      ingredients: "",
    };
  },
  computed: {
    formIsValid() {
      return (
         // this.id !== ""&&
        this.title !== "" &&
        this.description !== "" &&
        this.imageUrl !== "" &&
        this.ingredients != ""
      );
    }
  },     
  methods: {     
    onCreateRecipe() {
      if (!this.formIsValid) {
        return;
      }
      const recipeData = {
      //   id:this.id,
        title: this.title,
        description: this.description,
        imageUrl: this.imageUrl,
        ingredients: this.ingredients,
      };
       this.$store.commit('createRecipe', recipeData)
      const stringifiedData = JSON.stringify(recipeData);
      // console.log("S: ", stringifiedData);
      localStorage.setItem("recipe", stringifiedData);
      console.log("We got : ", JSON.parse(localStorage.getItem("recipe")));         
    },
  }
};
</script>
<style scoped>
.btn-style {
  color: #43a047;
}
.color {
  color: #fafafa;
}
</style>

您应该在
CreateRecipe()
中只保留1条语句,因为它们是等效的,会导致重复的配方:

createRecipe(状态、负载)
{
state.loadedRecipes.push(有效负载)
}
import Vue from 'vue'
import Vuex from 'vuex'
const LOGIN = "LOGIN";
const LOGIN_SUCCESS = "LOGIN_SUCCESS";
const LOGOUT = "LOGOUT";
import image1 from '../assets/img/image4.jpg'
import image2 from '../assets/img/image2.jpg'
import image3 from '../assets/img/image3.jpg'
import image4 from '../assets/img/insta2.jpg'
Vue.use(Vuex)
export const store = new Vuex.Store({
    state:{
        loadedRecipes:[
            {imageUrl:image3,
                id:'3' , title:'Homemade Burger',
                description:'Small plates, salads & sandwiches - an intimate setting with 12 indoor 
                 seats plus patio seating..',
                ingredients: '25 Eges 30kg Water'
            },
            {imageUrl:image1,
                id:'1' , title:'Cake',
                description:'Small plates, salads & sandwiches - an intimate setting with 12 indoor 
                seats plus patio seating..',
                ingredients: '25 Eges 30kg Water'
            },
            {imageUrl:image4,
                id:'4' , title:'Salad',
                description:'Small plates, salads & sandwiches - an intimate setting with 12 indoor 
                  seats plus patio seating..',
                ingredients: '25 Eges 30kg Water'
            },
            {imageUrl:image2,id:'2' ,
             title:'Kabseh',description:'Small plates, salads & sandwiches - an intimate setting with 
               12 indoor seats plus patio seating.',
             ingredients: '25 Eges 30kg Water'
            }        
          ],
          isLoggedIn: !!localStorage.getItem('token'),
          user:{
              id:'nvdcjavdah',
              registeredRecipes:['jhvjhvmnbvhj']
          }
    },
   mutations:{
        createRecipe(state,payload){
            Vue.set(state, 'loadedRecipes', [...state.loadedRecipes, payload])
            state.loadedRecipes.push(payload)
        },
        delete_recipe(state, id){
            let index = state.loadedRecipes.findIndex(recipe => recipe.id == id)
            state.loadedRecipes.splice(index, 1)
           }
        ,
        [LOGIN] (state) {
            state.pending = true;
          },
          [LOGIN_SUCCESS] (state) {
            state.isLoggedIn = true;
            state.pending = false;
          },
          [LOGOUT](state) {
            state.isLoggedIn = false;
          }
    },
    actions: {
        login({ commit }) {
          commit(LOGIN); // show spinner
          return new Promise(resolve => {
            setTimeout(() => {
              localStorage.setItem("token", "JWT");
              console.log(  localStorage.setItem("token", "JWT"))
              commit(LOGIN_SUCCESS);
              resolve();
            }, 1000);
          });
        },
        logout({ commit }) {
          localStorage.removeItem("token");
          commit(LOGOUT);
        },
          deleteRecipe({commit}, id) {            
            commit('delete_recipe', id)
        }
      },
    getters:{
        loadedRecipes(state){
            return state.loadedRecipes.sort((RecipeA,RecipeB)=>{
                return RecipeA.id >RecipeB.id
            })
        },
        featuredRecipes(state,getters){
            return getters.loadedRecipes.slice(0,5)
        },
        loadedRecipe(state){
            return (recipeId)=>{
                return state.loadedRecipes.find((recipe)=>{
                    return recipe.id === recipeId
                })
            }
        },
        isLoggedIn: state => {
            return state.isLoggedIn
           },
           loading (state) {
            return state.loading
          }
    }
})