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

网站备案号 有效期济南网站建设选聚搜网络认可

网站备案号 有效期,济南网站建设选聚搜网络认可,网站开发知识产权,杭州网站做的好公司名称接上篇。上篇中给出了代码框架#xff0c;没有具体实现#xff0c;这一篇会对上篇定义的几个组件进行分别介绍和完善#xff1a; 1、TodoContainer组件 TodoContainer组件#xff0c;用来组织其它组件#xff0c;这是react中推荐的方式#xff0c;也是redux中高阶组件一般…接上篇。上篇中给出了代码框架没有具体实现这一篇会对上篇定义的几个组件进行分别介绍和完善 1、TodoContainer组件   TodoContainer组件用来组织其它组件这是react中推荐的方式也是redux中高阶组件一般就是用来包装成容器组件用的比如redux中的connect函数返回的包装组件就是一个容器组件它用来处理这样一种场景加入有A、B两个组件A组件中需要通过Ajax请求和后端进行交互B组件也需要通过Ajax请求和后端交互针对这种场景有如下代码 //组件A定义 var CompA{template:divA 渲染 list/div,data:function(){return {list:[]}},methods:{getListA:function(){$.ajax({url:xxx,dataType:json,success:rthis.listr.data})}} }; //组件B定义 var CompB{template:divB 渲染list/div,data:function(){return {list:[]}},methods:{getListB:function(){$.ajax({url:xxx,dataType:json,success:rthis.listr.data})}} } 可以看出A组件和B组件中都会存在Ajax访问重复代码有重复代码就要提取出来第一种方式提取公共方法使用mixin混入到两个组件中所谓混入就是动态把方法注入到两个对象中 第二种方法使用外部传入这是react中推荐的方式使用props传入其实我们仔细分析我们的两个组件都是为了渲染列表数据至于是在组件外请求还是在组件内请求它是不关注的这样我们可以进一步考虑把AB组件重构成只用来渲染数据的pure组件数据由外部传入而vue正好提供了这种props父传子的机制把Ajax操作定义到父组件中就是我们这里提到的容器组件也起到了重复代码提取的作用基于此请看我们的第二版代码 //A组件 var CompA{template:divA/div,props:[list] }; //B组件 var CompB{template:divB/div,props:[list] } //容器组件 var Container{template:comp-a :listlistA /comp-acomp-b :listlistB /comp-b,components:{comp-a:CompA,comp-b:CompB},methods:{getListA:function(){//TODO:A 逻辑},getListB:function(){//TODO:B 逻辑}} } 这样A、B组件变成了傻白甜组件只是负责数据渲染所有业务逻辑由容器组件处理容器组件把A、B组件需要的数据通过props的方式传递给它们。 已经明白了容器组件的作用那么我们来实现一下前几篇中todolist的容器组件吧上篇已有基本结果这里先出代码后解释 /*** 容器组件* 说明容器组件包括三个字组件*/var TodoContainer {template: div classcontainersearch-bar οnsearchsearch($event)/search-bardiv classrowtodo-list :itemsitems onremoveremove($event) oneditedit($event)/todo-list todo-form :init-iteminitItem onsavesave($event) /todo-form/div/div,data: function () {return {/*** Todolist数据列表* 说明通过props传入到Todolist组件中让组件进行渲染*/items: [],/*** TodoForm初始化数据* 说明由于TodoForm包括两种操作新增和编辑新增操作无需处理编辑操作需要进行数据绑定这里通过传入initItem属性进行编辑时数据的初始化* 如果传入的值为空说明为新增操作由initItem参数的Id是否为空来确认是更新保存还是新增保存*/initItem: {title: ,desc: ,id: }}},components: {search-bar: SearchBar,/**SearchBar组件注册 */todo-form: TodoForm,/**TodoForm组件注册 */todo-list: todoList/**TodoList组件注册 */},methods: {/*** 模拟保存数据方法* 辅助方法*/_mock_save: function (lst) {list lst;},/*** 根据id查询对象* 辅助方法*/findById: function (id) {return this.items.filter(v v.id id)[0] || {};},/*** 查询方法* 由SearchBar组件触发*/search: function ($e) {this.items list.filter(v v.title.indexOf($e) ! -1);},/*** 保存方法* 响应新增和更新操作由TodoForm组件触发*/save: function ($e) {//id存在则为编辑保存if (this.initItem.id) {var o this.findById($e.id);o.title $e.title;o.desc $e.desc;} else {this.items.push(new Todo($e.title, $e.desc));}this.initItem { id: , title: , desc: };this._mock_save(this.items);},/*** 删除方法* 响应删除按钮操作* 由TodoItem组件触发*/remove: function ($e) {this.items this.items.filter(v v.id ! $e);this._mock_save(this.items);},/*** 编辑按钮点击时进行表单数据绑定*/edit: function ($e) {this.initItem this.findById($e);}}}   我们把所有业务逻辑也放在容器组件中处理其它组件都是傻白甜这样的好处是其它组件容易重用因为只是数据渲染并不涉及业务操作这种组件没有业务相关性比如一个list组件我可以用它显示用户信息当然也可以用它显示角色信息根据传入的数据而变化。   对上述代码需要简单解释一下的是Vue中父子event传递是通过$emit和$on来实现的但是写法和angular中有一些差异在angular中我们一般这样写 //事件发射 $scope.$emit(onxxx,data); //事件监听 $scope.$on(onxxx,function(e,data){//TODO: }) 但是在vue中$on是直接使用v-on:onxxx或onxxx来写的所以一般存在的是这样的代码 todo-list :itemsitems onremoveremove($event) oneditedit($event)/todo-list todo-form :init-iteminitItem onsavesave($event) /todo-form 其它代码中加入了很多注释也比较简单就不做过多解释了有疑问可提交。 2、SearchBar组件   SearchBar组件比较简单只是简单触发查询按钮发射触发onsearch事件然后TodoContainer组件中使用 οnsearchsearch($event) 进行监听。 /*** 搜索组件*/var SearchBar {template: div classrow toolbardiv classcol-md-8keywordinput typetext v-modelkeyword /input typebutton clicksearch() valuesearch classbtn btn-primary //div/div,data: function () {return {keyword: }},methods: {search: function () {this.$emit(onsearch, this.keyword);}}} 3、TodoForm组件   TodoForm组件是我们Todolist中的表单组件编辑和新增公用我们需要考虑的是我们的初始化数据由外部传入首先看第一版代码考虑有什么坑 /*** 表单组件*/var TodoForm {template: div classcol-md-6div classform-inlinelabel fortitle classcontrol-label col-md-4title:/labelinput typehidden v-bind:valuetodo.id /input typetext v-modeltodo.title classform-control col-md-8/divdiv classform-inlinelabel fordesc classcontrol-label col-md-4desc/labelinput typetext v-modeltodo.desc classform-control col-md-8/divdiv classform-inlineinput typebutton valueOK v-on:clickok() classbtn btn-primary offset-md-10 //div/div,props: [initItem],     data: function {return {todo: this.initItem}},methods: {ok: function () {this.$emit(onsave, this.todo);}}} 这段代码有什么问题呢我们把传入的初始化参数给了我们的todo对象这样导致的直接问题是新增的时候没问题但是编辑的时候无法绑定数据原因是编辑操作实际上就是修改外部传入的initItem对象但是todo只在组件初始化的时候被赋值其它时候是不响应initItem变化的如何才能响应initItem变化很明显是我们的computed属性computed属性会响应其封装对象的变化代码第二版修改如下 /*** 表单组件*/var TodoForm {template: div classcol-md-6div classform-inlinelabel fortitle classcontrol-label col-md-4title:/labelinput typehidden v-bind:valuetodo.id /input typetext v-modeltodo.title classform-control col-md-8/divdiv classform-inlinelabel fordesc classcontrol-label col-md-4desc/labelinput typetext v-modeltodo.desc classform-control col-md-8/divdiv classform-inlineinput typebutton valueOK v-on:clickok() classbtn btn-primary offset-md-10 //div/div,props: [initItem],computed: {todo: function () {          //这里不直接返回this.initItem 是因为会导致双向绑定因为传递的是引用return { id: this.initItem.id, title: this.initItem.title, desc: this.initItem.desc };}},methods: {ok: function () {this.$emit(onsave, this.todo);}}}    4、TodoList TodoItem组件   TodoList组件是数据列表组件它的每一个列表项我们进行了一次封装每一个list中的列表项就是一个TodoItem组件所以在TodoItem组件中只需要引入todoitem数据即可唯一需要关注的就是todoItem组件中会触发onremove和onedit事件。 /*** 列表项组件*/var TodoItem {template: trth{{todo.id}}/thtd{{todo.title}}/tdtd{{todo.desc}}/tdtdinput typebutton valueremove clickremove() classbtn btn-danger /input typebutton valueedit clickedit() classbtn btn-info //td/tr,props: [todo],methods: {edit: function () {console.log(this.todo);this.$emit(onedit, this.todo.id);},remove: function () {this.$emit(onremove, this.todo.id);}}}/*** 列表组件*/var TodoList {template: div classcol-md-6table classtable table-borderedtrth/ththtitle/ththdesc/thth/th/trtodo-item v-foritem in items :todoitem :keyitem.id oneditedit($event) onremoveremove($event)/todo-item/table/div,props: [items],components: {todo-item: TodoItem},methods: {edit: function ($e) {this.$emit(onedit, $e);},remove: function ($e) {this.$emit(onremove, $e);}}} 这两个数据渲染组件就没什么好说名的了但是大家发现一个很不爽的问题由于我们在容器中统一管理了业务逻辑更逼格高一些叫状态所以在todoitem组件中触发的事件没办法直接到TodoContainer组件中只能通过一级一级的往上传递所以在todolist中也有和todoitem中类似的触发事件的代码this.$emit(onremove, $e);这里组件层级才2级如果多了状态管理就是灾难了幸好vuex的出现就是专门处理这种问题的后期用到vuex的时候会详细介绍。 5、小结   todolist这个demo就暂时告一段落了下一片会以一个稍微复杂的demo信息管理来介绍vue-router当然在一步一步学习的过程中我还是没能做到把所有基本概念过一遍我个人觉得还是用到再解释吧否则还不如直接看文档来的方便。。。 完整代码 index.html !DOCTYPE html html langenheadmeta charsetUTF-8meta nameviewport contentwidthdevice-width, initial-scale1.0meta http-equivX-UA-Compatible contentieedgetitledemo1/titlescript srchttps://cdn.bootcss.com/vue/2.4.1/vue.js/scriptlink hrefhttps://cdn.bootcss.com/bootstrap/4.0.0-alpha.6/css/bootstrap.css relstylesheet/headbody classcontainerdiv idapptodo-container/todo-container/divscript src./todolist.js/script /body/html View Code todolist.js ; (function () {var list [];var Todo (function () {var id 1;return function (title, desc) {this.title title;this.desc desc;this.id id;}})();/*** 搜索组件*/var SearchBar {template: div classrow toolbardiv classcol-md-8keywordinput typetext v-modelkeyword /input typebutton clicksearch() valuesearch classbtn btn-primary //div/div,data: function () {return {keyword: }},methods: {search: function () {this.$emit(onsearch, this.keyword);}}}/*** 表单组件*/var TodoForm {template: div classcol-md-6div classform-inlinelabel fortitle classcontrol-label col-md-4title:/labelinput typehidden v-bind:valuetodo.id /input typetext v-modeltodo.title classform-control col-md-8/divdiv classform-inlinelabel fordesc classcontrol-label col-md-4desc/labelinput typetext v-modeltodo.desc classform-control col-md-8/divdiv classform-inlineinput typebutton valueOK v-on:clickok() classbtn btn-primary offset-md-10 //div/div,props: [initItem],computed: {todo: function () {return { id: this.initItem.id, title: this.initItem.title, desc: this.initItem.desc };}},methods: {ok: function () {this.$emit(onsave, this.todo);}}}/*** 列表项组件*/var TodoItem {template: trth{{todo.id}}/thtd{{todo.title}}/tdtd{{todo.desc}}/tdtdinput typebutton valueremove clickremove() classbtn btn-danger /input typebutton valueedit clickedit() classbtn btn-info //td/tr,props: [todo],methods: {edit: function () {console.log(this.todo);this.$emit(onedit, this.todo.id);},remove: function () {this.$emit(onremove, this.todo.id);}}}/*** 列表组件*/var TodoList {template: div classcol-md-6table classtable table-borderedtrth/ththtitle/ththdesc/thth/th/trtodo-item v-foritem in items :todoitem :keyitem.id oneditedit($event) onremoveremove($event)/todo-item/table/div,props: [items],components: {todo-item: TodoItem},methods: {edit: function ($e) {this.$emit(onedit, $e);},remove: function ($e) {this.$emit(onremove, $e);}}}/*** 容器组件* 说明容器组件包括三个字组件*/var TodoContainer {template: div classcontainersearch-bar οnsearchsearch($event)/search-bardiv classrowtodo-list :itemsitems onremoveremove($event) oneditedit($event)/todo-list todo-form :init-iteminitItem onsavesave($event) /todo-form/div/div,data: function () {return {/*** Todolist数据列表* 说明通过props传入到Todolist组件中让组件进行渲染*/items: [],/*** TodoForm初始化数据* 说明由于TodoForm包括两种操作新增和编辑新增操作无需处理编辑操作需要进行数据绑定这里通过传入initItem属性进行编辑时数据的初始化* 如果传入的值为空说明为新增操作由initItem参数的Id是否为空来确认是更新保存还是新增保存*/initItem: {title: ,desc: ,id: }}},components: {search-bar: SearchBar,/**SearchBar组件注册 */todo-form: TodoForm,/**TodoForm组件注册 */todo-list: TodoList/**TodoList组件注册 */},methods: {/*** 模拟保存数据方法* 辅助方法*/_mock_save: function (lst) {list lst;},/*** 根据id查询对象* 辅助方法*/findById: function (id) {return this.items.filter(v v.id id)[0] || {};},/*** 查询方法* 由SearchBar组件触发*/search: function ($e) {this.items list.filter(v v.title.indexOf($e) ! -1);},/*** 保存方法* 响应新增和更新操作由TodoForm组件触发*/save: function ($e) {//id存在则为编辑保存if (this.initItem.id) {var o this.findById($e.id);o.title $e.title;o.desc $e.desc;} else {this.items.push(new Todo($e.title, $e.desc));}this.initItem { id: , title: , desc: };this._mock_save(this.items);},/*** 删除方法* 响应删除按钮操作* 由TodoItem组件触发*/remove: function ($e) {this.items this.items.filter(v v.id ! $e);this._mock_save(this.items);},/*** 编辑按钮点击时进行表单数据绑定*/edit: function ($e) {this.initItem this.findById($e);}}}var app new Vue({el: #app,components: {todo-container: TodoContainer}});})();/*** * * div idapp* todo-container/todo-container* /app*/ View Code  转载于:https://www.cnblogs.com/Johnzhang/p/7223064.html
http://www.zqtcl.cn/news/405322/

相关文章:

  • 企业网站优化的方式萍乡市建设局网站王丽
  • 做网站的收费标准社保网上服务大厅
  • php网站开发安全网站建设管理教程视频教程
  • 网站建设的空间是什么意思海络网站
  • 深圳华强北今晚网站优化推广公司
  • 网站建设行业好做吗太原网站改版
  • 寿光企业建站流程个人网站用什么软件
  • 网站建设与管理自考本全国卷wordpress 关闭文章修订
  • 兴义市建设局网站首页网站开发项目实训总结
  • 个人网站空间收费网络软文营销案例
  • 网站开发文件结构组成微网站移交
  • 西安全网优化 西安网站推广网页浏览器缩略词
  • 网站开发及企业推广营销型网站建设怎么收费
  • 网站建设与管理ppt课件百度云盘关键词推广营销
  • c asp.net网站开发书宁波建设业协会网站
  • 政务网站建设发言材料知名互联网公司有哪些
  • 网站搭建制作建e室内设计网画图
  • 重庆市建设工程施工安全管理信息网北京seo公司网站
  • 国外做调查问卷的网站建设邮费自己的网站 要不要购买服务器的
  • 网站建设和优化排名四川建设网官网证书查询入口
  • 如何搜名字搜到自己做的网站电子商务平台icp备案证明
  • 网站建设与管理工作内容北京网站建设价
  • 做网站选哪个语言软文营销的方法
  • 青岛正规公司网站建设公司中国建设银行注册网站
  • 免费个人网站平台关键词检索
  • 定制型网站建设推广宁河网站建设
  • 主流网站开发语言有哪些电子邮件营销
  • 扫描二维码进入公司网站怎样做在万网上域名了怎么做网站
  • 销售型网站设计怎么做网站广告位
  • 网站推广的方法ppt购物网站logo