Vuex原来可以这样上手

     在Mvc模式大行其道的今天,后端通过各种Mvc框架实现视图与数据模型的隔离,而前端这方面也发展迅速。vue实现了Dom与viewModel双向绑定,使其视图的更新影响模型,模型的更新影响视图,你会不会觉得这就是Mvc库呢,实则不然,因为他还差一个重要的C(也就是控制器)。以下是鄙人对Mvc的个人理解,如有失误还请各位道友指正。

  • M:模型用于表示各种事物及事物特性的数据
  • v:view + viewModel,此处鄙人认为v不能单纯的理解为视图,而应该是视图+视图模型。
  • c:控制器,用于协调M与v之间的关系。

第一部分:我对vuex的理解

     这个重要的C是谁呢,鄙人认为就是此文章要介绍的Vuex(如果你想初识vue,可以移步vue原来可以这样上手这篇博文)。如此理解也是可以的:vue + vuex = 前端mvc框架

  • flux(单向数据流)
    • actions:一个动作,可以是view创建的,也可以是程序其他逻辑创建的
    • dispatcher:将业务逻辑与用户界面分离,负责响应action动作事件,并意向传遍整个系统
    • store:业务逻辑处理
    • view:视图
  • vuex是借鉴了flux、redux、The Elm Architecture等相关思想。

第二部分:揭开vuex面纱

本示例实现为一个输入框动态向下拉列表增加选择项的功能源码下载地址,先看效果图:

为了展示vuex的作用,此示例你可以看到如下内容:

  • 两个局部组件:输入和下拉列表组件
  • 一个全局组件:App,也是整个Vue实例的顶级组件
  • 一个jquery.js和bootstrap.js,用于实例下拉组件,jquery只辅助用于bootstrap。
  • 还有一个bootstrap.css,用于美化样式。

一、实现vuex的store实例

//Vue.use(Vuex);//如果是window引入方式,vuex会自动附加到Vue上。
var state = {
    list: [{"id":1, "name": "001"}]
};
var mutations = {
    ADDITEM: function(argState, item){
        argState.list.push(item);
    }
};
var getters = {
    getList:function(argState){
        return argState.list;
    }
}
var actions = {
    addItem:function(dis,item){
        dis.commit('ADDITEM',item);
    }
}
var _storeObj = new Vuex.Store({
    "state": state,
    "mutations": mutations,
    "getters": getters,
    "actions": actions
});

vuex更新数据流程:

  • dispatch可以是view视图中触发,也可以是程序业务逻辑来触发
  • actions通过commit方法发出一个改变事件
  • mutations中具体操作state的改变
  • state的改变通过getter暴露给view,state改变后会立即通知用getter关联起来的view。
  • 创建一个Vuex.Store的实例,用于Vue实例。

二、实现vue的组件

var inputComp = {
    render:function(createElement){
        var self = this; 
        return createElement('div',{
            attrs:{
                "data-id": "001"
            },
            class:{
                "form-inline":true
            },
            style:{
                "display": "inline-block"
            }
        },[createElement('input',{
           attrs:{
               type: 'text'
           },
           class:{
                "form-control": true
           },
           domProps:{
               value: self.value
           },
           on:{
               input:function(event){
                   self.value = event.target.value;
               }
           } 
        }),createElement('button',{
            on:{
                "click": function(event){
                   self.$store.dispatch('addItem',{"id":2,"name": self.value});
                }
            },
            class:{
                "btn":true,
                "btn-primary": true
            },
            domProps:{
                type: 'button'
            }
        },"添加")]);
    }
};
//下拉列表组件
var ComboComp = {
    render:function(createElement){ 
        var self = this;
        return createElement("div",{
            attrs:{
                "data-id": "ComboComp"
            },
            class:{
                "dropdown":true
            },
            style:{
                "display": "inline-block"
            }
        },[
            createElement("button",{
                class:{
                    "btn": true,
                    "btn-default": true,
                    "dropdown-toggle": true
                },
                attrs:{
                    "type": "button",
                    "id": "dr02",
                    "data-toggle": "dropdown"
                }
            },[ createElement("span", "选择"), createElement("span",{
                class:{
                    "caret":true
                }
            })])
            ,
            createElement("ul",
            {
                class:{
                    "dropdown-menu":true
                },
                attrs:{
                    "aria-labelledby":"dr02"
                }
            }, self.$store.getters["getList"].map(function(item){
                return createElement("li",item.name);
            }))
        ])
    }
};
Vue.component('App',{
    template:'<div class="wrap" ><ComboComp></ComboComp> <InputComp></InputComp></div>',
    components:{
        "InputComp": inputComp,
        "ComboComp": ComboComp
    }
});
  • inputComp(局部组件):提供输入
  • ComboComp(局部组件):实现列表内容的展示
  • App(全局组件):顶级组件,组合inputComp和ComboComp组件。
  • 组件参数说明:
    • render:返回一个组件,其中包含视图,data等。this为vue实例,参数是createElement方法,用于创建VNode。
  • 重点关注inputComp组件中button子元素的on中的click方法,内部用dispatch触发了store中对应Id的actions。
createElement('button',{
on:{
    "click": function(event){
       self.$store.dispatch('addItem',{"id":2,"name": self.value});
    }
}

三、输出

html部分代码:

<div class="wrap" id="app">
    <App></App>
</div>

js部分代码:

var _vue = new Vue({
    el: '#app',
    store: _storeObj
});
  • 视图中引入了App这个全局组件
  • 生成Vue实例的时候将vuex中创建的store实例传递进去。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏QQ音乐前端团队专栏

Web Components 初探

任何 UI 框架或库最期望目标之一是帮助我们建立通用的模式或约定。

7574
来自专栏Ryan Miao

idea快捷键总结

使用好快捷键会快很多,这里我慢慢添加我用习惯的快捷键。参考 1.alt+enter 这个几乎万能,有错误提示的时候将光标移动到错误处,然后alt+enter,会...

28612
来自专栏静晴轩

Android Studio快捷键

最常用快捷键 Alt+回车 导入包,自动修正 Ctrl+N 查找类 Ctrl+Shift+N 查找文件 Ctrl+Alt+L 格式化代码 Ctrl+Alt+O ...

3387
来自专栏技术墨客

React Flow代码静态检查

Flow是Facebook开源的静态代码检查工具,他的作用是在运行代码之前对React组件以及Jsx语法进行静态代码的检查以发现一些可能存在的问题。Flow可以...

1074
来自专栏用户2442861的专栏

我的VS2010+VAssistX

最近越来越觉得VAssistX好用,可能是以前没有去仔细研究过吧,也可能是因为我是个快捷键控吧,不管怎样,用或不用,方便或不方便,它就是那里,一动也不动,进入...

1231
来自专栏技术墨客

React学习(11)—— 高阶应用:Web组件

从概念上说,React 和 Web组件 分别用于解决不同的问题。Web组件提供了强大的封装特性来支持其可重复使用性,而React提供了一系列声明性(declar...

802
来自专栏hrscy

iOS 9 Storyboard 教程(二上)介绍Segue静态单元格(static cell)

Add Player 最终的设计看上去像下面这样:#接第一部分: 原帖地址 简书地址

2111
来自专栏点滴积累

PhiloGL学习(3)——程序员的法宝—键盘、鼠标

前言 上一篇文章中介绍了如何让对象动起来,本文介绍如何让场景响应我们的鼠标和键盘以控制场景的缩放及对象的转动和移动等。 一、 原理分析 有了上一篇文章的基础,我...

3527
来自专栏技术墨客

React Web组件

从概念上说,React 和 Web组件 分别用于解决不同的问题。Web组件提供了强大的封装特性来支持其可重复使用性,而React提供了一系列声明性(declar...

792
来自专栏五毛程序员

五毛的cocos2d-x学习笔记06-处理用户交互

1452

扫码关注云+社区