当前位置: 首页 > news >正文

vue select清空_Vue+Webpack开发可复用的单页面富应用教程(技巧篇)

山寨的Vuex

说到山寨,我们先看看正版的Vuex是个什么鬼。

当你的Vue项目比较大,或者说组件使用的比较深度(层级、复用性)的时候,状态、数据越来越共享化,如果把数据都存在组件中,会变的不太好维护,那么Vuex就是在这种情况下出现的。它借鉴于Flux和Redux的设计思想,用过React的话应该不会陌生,不过要比那些简单,而且转为Vue量身打造。

为什么需要山寨的Vuex

既然已经有正版的Vuex了,而且也不复杂,为什么需要山寨的vuex呢?我们先介绍一下什么是山寨的Vuex,其实这里有点概念化了,山寨的vuex并没有什么特殊,只是一个普通的js文件,为了达到类似的目的,我们将其命名为了vuex.js。它的结构大概是这样的:

exports.POILIST = {
    data : {
        list: []
    },
    clear : function() {
        this.data = {
            list: []
        };
    }
};
exports.MENU = {
    data: {
        list: [],
        select: {}
    },
    clear: function() {
        this.data = {
            list: [],
            select: {}
        };
    }
};

可以看到它对外导出了一些模块,模块的结构都有一个data,这个data里存储的就是我们需要共享的数据了,组件在通信时,不直接向上或向下传递数据,而是保存在vuex.js里,出于对象的引用关系,vue可以天然的实现共享数据的双向绑定,在使用时是这样的:

<template>
    <div>
        <li v-for="item in menu.list">{{ item }}</li>
        <p v-for="item in poi.list">{{ item.lng }},{{ item.lat }}</p>
    </div>
</template>
<script>
    import { POILIST, MENU } from '../config/vuex.js';
    export default {
        data() {
            return {
                menu: MENU.data,
                poi: POILIST.data
            }
        },
        methods: {
            set() {
                MENU.list.push('首页');
                POILIST.list.push({
                    lng: 124.1,
                    lat: 42.3
                });
            }
        }
    }
</script>

这种存储,可以理解为相当于存在全局,并且可以加一些事件来操作数据,比如我们demo的clear()用来清空数据,只不过这里是用函数来调用,也可以将其改为观察者模式,用事件派发的形式来修改数据,其实vuex正是这么玩的。

有了vuex.js,组件之间就可以直接保存到它里面,这对数据持久化、数据共享来说是一个简单粗暴的解决方案。它适用了不大的项目(当然在大型项目中它也没什么问题),或者不太想在当下接入vuex的架构,或者想简单而又优雅地维护一些全局状态和数据。

我们知道,JavaScript的对象是引用关系,也正是这个原因我们可以设计vuex.js,但也正是这个原因,如果你的数据不是对象,只是简单数组、数字、字符串等,是不能直接共享的,JS会复制来使用,所以我们在组件的data里,return的都是像MENU.data而不是MENU.data.list,在遍历时,才循环menu.list。

到底用prop还是事件

上一篇文章介绍过,组件之间数据交互,主要有prop和事件两种,在使用过程中发现,这两种方案有时候都可以达到同样的效果,比如下面的这个场景,父组件向子组件传递的一个数据id,子组件来判断这个id如果发生变化,就做一些事情。用prop是这么实现的:

<!-- 父组件 -->
<template>
    <child :id="id"></child>
</template>
<script>
    export default {
        data() {
            return {
                id: 1
            }
        },
        ready() {
            setTimeout(() => {
                this.id = 2;
            }, 1000);
        }
    }
</script>

<!-- child组件 -->
<template>
    
</template>
<script>
    export default {
        props: {
            id: {
                type: Number,
                default: 0
            }
        },
        data() {
            return {}
        },
        methods: {
            handler() { }
        },
        watch: {
            id() {
                this.handler();
            }
        }
    }
</script>

child组件通过watch来监听id的改变,如果用事件可以这样实现:

<!-- 父组件 -->
<template>
    <child :id="id"></child>
</template>
<script>
    export default {
        data() {
            return {
                id: 1
            }
        },
        ready() {
            setTimeout(() => {
                this.$broadcast('child-set-data', {
                    id: 2
                });
            }, 1000);
        }
    }
</script>

<!-- child组件 -->
<template>
    
</template>
<script>
    export default {
        props: {
            id: {
                type: Number,
                default: 0
            }
        },
        data() {
            return {}
        },
        methods: {
            handler() { }
        },
        events: {
            id() {
                this.handler();
            }
        }
    }
</script>

这次是通过events来接收事件,效果是一样的。既然两者都可以,那如何优雅的选择呢,笔者觉得可以在数据功能上进行区分。比如上面的场景,是由子组件child在知道id改变后,在它自己的作用域里去执行handler()方法,handler可能是一个需要ajax获取数据并渲染到child组件上的函数,这时候就推荐用watch来监听id的改变了。如果handler所对应的ajax任务是在父组件完成的,父组件需要将拿到的一堆json数据传给child时,这时可以通过事件来传递。不过说到底,还是看使用者的习惯了,这两者都是可以的,只不过事件更多的是来触发外部环境的action。

管好组件的一亩三分地

用好prop的sync

上篇文章介绍过,组件间可以通过prop传递数据,而且使用sync还可以双向绑定:

<child :id.sync="id"></child>

这样id就是一个双向的了,子组件修改后,父组件也会修改,但这样做有时候会分不清到底是谁改的,也很可能会不小心就修改了父组件的值,所以在使用时要特别注意。

验证prop

有时为了省事,在写组件时就将props直接写一个数组了,但如果你写的组件是给别人用的,那还是建议对每个prop都进行严格的验证,确保他人正确使用。具体验证方法可查看文档。

子组件不该干涉父组件的状态

子组件可以通过$parent访问到父组件,也就是说它有权利去修改父组件的状态,但不建议这样做,虽然有时候是省事了,但是这让父子组件之间紧耦合,很难知道到底是谁来维护数据,而且你开发给别人用的组件,随意修改了父级的状态,这会让使用者不知所措。所以子组件应该只关心自己的数据,要修改父级状态时,通过$dispatch()方法派发事件来通知父级,由父级自己修改。

总结

一口气写完这4篇文章,还真是有点辛苦啊。半年前还只是用Vue的一些简单功能,到现在TalkingData的多条产品线已逐步使用这整套架构,这个推动的过程还是很快的,也是真正意识到Vue是一个很出色的框架,对它充满了信心。TalkingData接下来陆续上线的几个重磅产品(Data Cloud、Marketing Cloud),也是证明了这一点。很快Vue2.0也要来了,对它更是充满了期待。前端就是这么神奇,总有玩不尽的框架,但一定要选对一个适合自己的技术栈。

相关文章:

  • 两个同级div等高布局
  • cant connect to local mysql_Can't connect to local MySQL server through socket
  • jQuery的切换函数(hover,toggle)
  • mysql锁怎么控制并发_Mysql并发控制-锁
  • yii的ActionForm组件
  • java调用python爬虫_Java调用Python爬虫
  • 移动端如何用swiper实现导航栏效果
  • mysql undo_mysql 的undo 表空间
  • linux 后台开发类常见问题及知识点
  • mysql无法存 x_mySQL如果X Y不保存信息
  • mysql查询语句能用吗_基于mysql查询语句的使用详解
  • C语言程序设计第四次作业——选择结构(2)
  • 数组不能以什么形式参与运算_EXCEL知识:数组运算是什么?
  • python内置函数it_Python标准库:内置函数iter(object[, sentinel])
  • CentOS yum 源的配置与使用
  • 【刷算法】从上往下打印二叉树
  • co.js - 让异步代码同步化
  • JS函数式编程 数组部分风格 ES6版
  • Just for fun——迅速写完快速排序
  • React系列之 Redux 架构模式
  • unity如何实现一个固定宽度的orthagraphic相机
  • 编写高质量JavaScript代码之并发
  • 搭建gitbook 和 访问权限认证
  • 大型网站性能监测、分析与优化常见问题QA
  • 动手做个聊天室,前端工程师百无聊赖的人生
  • 基于Dubbo+ZooKeeper的分布式服务的实现
  • 记一次和乔布斯合作最难忘的经历
  • 坑!为什么View.startAnimation不起作用?
  • 老板让我十分钟上手nx-admin
  • 理解在java “”i=i++;”所发生的事情
  • 漫谈开发设计中的一些“原则”及“设计哲学”
  • 前端存储 - localStorage
  • 前端每日实战:70# 视频演示如何用纯 CSS 创作一只徘徊的果冻怪兽
  • 区块链技术特点之去中心化特性
  • 使用 @font-face
  • 新版博客前端前瞻
  • 怎样选择前端框架
  • ​HTTP与HTTPS:网络通信的安全卫士
  • ​软考-高级-系统架构设计师教程(清华第2版)【第20章 系统架构设计师论文写作要点(P717~728)-思维导图】​
  • !!Dom4j 学习笔记
  • # .NET Framework中使用命名管道进行进程间通信
  • #pragma预处理命令
  • #QT(TCP网络编程-服务端)
  • $(function(){})与(function($){....})(jQuery)的区别
  • $.proxy和$.extend
  • (52)只出现一次的数字III
  • (AngularJS)Angular 控制器之间通信初探
  • (Arcgis)Python编程批量将HDF5文件转换为TIFF格式并应用地理转换和投影信息
  • (初研) Sentence-embedding fine-tune notebook
  • (附源码)springboot工单管理系统 毕业设计 964158
  • (附源码)springboot码头作业管理系统 毕业设计 341654
  • (万字长文)Spring的核心知识尽揽其中
  • (转) 深度模型优化性能 调参
  • (转)为C# Windows服务添加安装程序
  • *1 计算机基础和操作系统基础及几大协议