zoukankan      html  css  js  c++  java
  • vue+vuex初入门

    Vuex

    Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

    解决问题:

    • 传参的方法对于多层嵌套的组件将会非常繁琐,并且对于兄弟组件间的状态传递无能为力。

    • 采用父子组件直接引用或者通过事件来变更和同步状态的多份拷贝。以上的这些模式非常脆弱,通常会导致无法维护的代码。

    参考文档:

    • https://github.com/vuejs/vuex/tree/dev/examples/shopping-cart
    • https://vuex.vuejs.org/zh-cn/getting-started.html

    数据流动

    开始

    让我们做一个添加列表的功能

    目录结构

     
    ├── index.css
    ├── index.js
    ├── store
    │   ├── index.js
    │   ├── main.js
    │   └── modules
    │       └── card.js
    └── vue-mods
        ├── card.vue
        └── index.vue
     

    定义store.js

     
    import Vue from 'vue'
    import Vuex from 'vuex'
    ​
    import card from "./modules/card.js";
    ​
    //初始化store
    export default new Vuex.Store({
        //store的子模块
        modules : {
            card
        },
        //定义状态
        state : {
            msg : "hello, this msg is from vuex.store",
            name : "zhangjian",
            location : "zhengjiang"
        },
        //设置状态的获取,可以做一些特殊的定制
        getters : {
            detail : state => {
                return state.msg + state.name
            }
        },
        //mutation,用来修改state
        mutations : {
            CHANGE_LOCATION (state, location = "beijing"){
                state.location = location;
            }
        },
        //事件处理,主要是由外部触发store
        actions : {
            changeLocation ({ commit, state }){
                commit("CHANGE_LOCATION");//触发mutation
            },
            changeLocationAsync ({commit, state}, {location}){
                setTimeout(function (){
                    commit("CHANGE_LOCATION", location);
                }, 1000);
            }
        }
    });
     

    modules/card.js ,和store.js和一致,只是输出的是一个模块

    let state = {
        list : [],
        message : "this is card"
    }
    ​
    let getters = {
    ​
    }
    ​
    let mutations = {
        ADD_CARD (state, card){
            state.list.unshift(card)
        },
        UPDATE_MESSAGE (state, message){
            state.message = message;
        },
        DELETE_CARD_BY_INDEX (state, index){
            state.list.splice(index, 1);
        }
    }
    ​
    let actions = {
        addcard ({commit, state}, card){
            let message = state.message;
            let time = new Date().getTime();
    ​
            commit("ADD_CARD", {name : `${message} card - ${time}`})
        },
        updateMessage ({commit, state}, message){
            commit("UPDATE_MESSAGE", message);
        },
        deleteCard ({commit, state}, index){
            commit("DELETE_CARD_BY_INDEX", index);
        }
    }
    ​
    export default{
        state, getters, mutations, actions
    }

    入口文件 App.vue

    <style lang="less">
    </style>
    <template>
        <div>
            <p>{{msg}}</p>
            <p>{{name}}</p>
            <p>{{location}}</p>
            <p>detail : {{detail}}</p>
            <button @click="change">change location</button>
            <button @click="asyncChange">async change location</button>
            <card></card>
        </div>
    </template>
    <script>
        import store from "../store/";
        import Card from "./card.vue";
    ​
        export default {
            components : {
                Card
            },
            store,
            created () {},
            computed : {
                msg (){
                    return "msg : " + this.$store.state.msg
                },
                name (){
                    return "name :" + this.$store.state.name
                },
                location (){
                    return "location :" + this.$store.state.location
                },
                detail (){
                    return this.$store.getters.detail
                }
            },
            ready() {
    ​
            },
            methods : {
                change (){
                    this.$store.dispatch("changeLocation")
                },
                asyncChange (){
                    this.$store.dispatch("changeLocationAsync", {
                        location : "china"
                    });
                }
            },
            watch : {
            },
            filters: {
            }
          }
    </script>
    

    子模块 card.vue

     
    <style lang="less">
    </style>
    <template>
        <div>
            <button @click="add">add card</button>
            <input type="text" name="" @input="updateMessage" :value="message">
            <span>{{cardCount}}</span>
            <div v-for="(index, card) in list">{{card.name}}<span @click="del(index)">x</span></div>
        </div>
    </template>
    <script>
        export default {
            components : {
            },
            computed : {
                list (){
                    return this.$store.state.card.list
                },
                cardCount (){
                    return this.$store.state.card.list.length;
                },
                message (){
                    return this.$store.state.card.message
                }
            },
            created () {
                
            },
            ready() {
    ​
            },
            methods : {
                add (){
                    this.$store.dispatch("addcard");
                },
                updateMessage (e){
                    this.$store.dispatch("updateMessage", e.target.value)
                },
                del (index){
                    this.$store.dispatch("deleteCard", index);
                }
            },
            watch : {
    ​
            },
            filters: {
            }
          }
    </script>
    

    附上webpack.config.js

    var webpack = require('webpack');
    var vue = require('vue-loader')
    var commonsPlugin = new webpack.optimize.CommonsChunkPlugin('common.js');
    var ExtractTextPlugin = require("extract-text-webpack-plugin");
     
    module.exports = {
        //插件项
        plugins: [
            new ExtractTextPlugin("[name].css")
        ],
        //页面入口文件配置
        entry: {
            index : './src/index.js'
        },
        //入口文件输出配置
        output: {
            path: './dist/',
            filename: '[name].js'
        },
        module: {
            //加载器配置
            loaders: [
                { test: /.css$/, loader: ExtractTextPlugin.extract("css") },
                { test: /.less$/, loader: ExtractTextPlugin.extract("css!less") },
                { test: /.js$/, loader: "babel",query: {presets: ['es2015']},exclude: /node_modules/ },
                { test: /.vue$/, loader: 'vue'}
            ]
        },
        vue : {
          loaders: {
            css: ExtractTextPlugin.extract("css"),
            less: ExtractTextPlugin.extract("css!less")
          },
          autoprefixer: { browsers: ["ios_saf >= 7", "android >= 4"] }
        },
        externals: {
            vue: "window.Vue",
            vuex : "window.Vuex"
        }
    };
    

    注意:这里,我针对vue和vuex2个仓库,做了一个全局引用,这样打包出来的boundle不会太大。

     
  • 相关阅读:
    [转]经典SQL语句大全
    listview分页
    verticalalign属性和用法
    在后台.cs页面往前台插入html代码的方法
    前台js改变Session的值(用ajax)
    2012.10笔记
    添加收藏夹(兼容部分)
    使textbox无法手动修改,但可以代码修改
    题目审批表
    任务书
  • 原文地址:https://www.cnblogs.com/xiaoniuzai/p/6144828.html
Copyright © 2011-2022 走看看