vue-递归树形菜单 发表于 2017-12-18 | 分类于 Vue | | 阅读次数 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230<!DOCTYPE html><html lang="zh-cn"><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title></title> <style> ul { padding: 0; margin: 0; list-style: none; } .tree-menu { width: 360px; height: 100%; padding: 0px 12px; border-right: 1px solid #e6e9f0; } .tree-menu-comm span { display: block; font-size: 12px; position: relative; } .tree-contro .ico { background-position: 3px -92px; } .tree-title .ico { position: absolute; left: -13px; top: 0; width: 15px; height: 26px; background: url(./folder-tree.png) no-repeat 4px -43px; opacity: 0.8; } .tree-menu-comm span strong { display: block; width: 82%; position: relative; line-height: 22px; padding: 2px 0; padding-left: 5px; color: #161719; font-weight: normal; } .tree-nav { background: #e7f2fe; border: 1px solid #bfdaf4; padding-left: 14px; margin-left: 0px; } .tree-title { border: 1px solid #fff; margin-top: 1px; } /*无箭头*/ .tree-contro-none .ico { background-position: -999px -99px; } /*箭头朝下*/ .tree-contro .ico { background-position: 3px -92px; } </style> <script src="../vue.js"></script> <script> </script></head><body> <div id="app"> <!-- <div class="tree-menu-comm tree-menu"> <ul> <li> <div class="tree-title" style="padding-left: 16px;"><span><strong>目录</strong> <i class="ico"></i></span></div> <ul> <li> <div class="tree-title" style="padding-left: 32px;"><span><strong>我的音乐</strong> <i class="ico"></i></span></div> <ul> <li> <div class="tree-title" style="padding-left: 48px;"><span><strong>周杰伦</strong> <i class="ico"></i></span></div> <ul> <li> <div class="tree-title tree-contro-none" style="padding-left: 64px;"><span><strong>发如雪</strong> <i class="ico"></i></span></div> </li> </ul> </li> <li> <div class="tree-title" style="padding-left: 48px;"><span><strong>王杰</strong> <i class="ico"></i></span></div> <ul> <li> <div class="tree-title tree-contro-none" style="padding-left: 64px;"><span><strong>一场游戏一场梦</strong> <i class="ico"></i></span></div> </li> </ul> </li> </ul> </li> <li> <div class="tree-title tree-contro-none" style="padding-left: 32px;"><span><strong>我的照片</strong> <i class="ico"></i></span></div> </li> </ul> </li> </ul> </div> --> <m-tree :data="treeList"></m-tree> </div> <script> /* 传入的数据结构: [ { title:XXX, children:[ { title:XXXX, chidren:[] } ] }] 设置的props: data 数据结构 默认为 [] 定制模板: 不可定制 监控状态变化: 事件名on-select-change 点击树节点触发 */ Vue.component('m-tree-list',{ computed:{ count(){ var c = this.increment; return ++c; }, stylePadding(){ return { 'padding-left':this.count * 16 + 'px' } } }, props:{ data:{ type:Array, default:[] }, increment:{ type:Number, default:0 } }, template:` <ul> <li v-for="item of data"> <div class="tree-title" :style="[stylePadding]"> <span><strong>{{item.title}}</strong> <i class="ico"></i></span> </div> <!--如果循环的item有children属性,那么生成下一级--> <m-tree-list :increment="count" v-if='item.chidren' :data="item.chidren" ></m-tree-list> </li> </ul> ` }) Vue.component('m-tree',{ props:{ data:{ type:Array, default:[] } }, template:` <div class="tree-menu-comm tree-menu"> <m-tree-list :data="data"></m-tree-list> </div> ` }) var data = [{ title: "目录", chidren: [{ title: "我的音乐", chidren: [{ title: "周杰伦", chidren: [{ title: "发如雪" }] }, { title: "王杰", chidren: [{ title: "一场游戏一场梦" }] }] }, { title: "我的照片" }] }]; new Vue({ el:"#app", data:{ treeList:data } }) </script></body></html>
vue-封装弹出框组件 发表于 2017-12-18 | 分类于 Vue | | 阅读次数 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213<!DOCTYPE html><html lang="zh-cn"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title></title> <link rel="stylesheet" type="text/css" href="fontFace.css"> <style> [class*=" m-icon-"], [class^=m-icon-] { font-family: element-icons!important; speak: none; font-style: normal; font-weight: 400; font-variant: normal; text-transform: none; line-height: 1; vertical-align: baseline; display: inline-block; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } /*基本样式*/ .m-alert { width: 100%; padding: 8px 16px; margin: 0; box-sizing: border-box; border-radius: 4px; position: relative; background-color: #fff; overflow: hidden; color: #fff; display: table; transition: opacity .2s; margin-top:10px; border: 1px solid #ccc; } .m-content { display: table-cell; padding: 0 8px; } .m-message { font-size: 13px; line-height: 18px; } /*不同状态样式*/ .m-alert-success{ background-color:#13ce66; } .m-alert-info{ background-color:#50bfff; } .m-alert-warning{ background-color:#f7ba2a; } .m-alert-error{ background-color:#ff4949; } /*关闭按钮样式*/ .m-closebtn { font-size: 12px; color: #fff; opacity: 1; top: 12px; right: 15px; position: absolute; cursor: pointer; } .m-icon-close:before { content: "\E60C"; } /*小图标样式*/ .m-icon { font-size: 16px; width: 16px; display: table-cell; color: #fff; vertical-align: middle; } .m-icon-success:before { content: "\E609"; } .m-icon-warning:before { content: "\E615"; } .m-icon-info:before { content: "\E615"; } .m-icon-error:before { content: "\E60B"; } /*自定义图标*/ .m-icon-message:before { content: "\E618"; } .m-icon-menu:before { content: "\E617"; } .m-icon-setting:before { content: "\E61E"; } #app { width: 500px; } </style> <script src="vue.js"></script> <script> </script> </head> <body> <div id="app"> <alert type="info" title="这里有一个消息要提示"></alert> <alert type="success" title="成功的消息"></alert> <alert type="error" title="错误的消息"></alert> <alert type="warning" title="警告的消息" :closeable="false" :showicon="true" style="color:#333"></alert> <alert @close-click="closed"> <template slot="messageTemp"> <p>你好张幸</p> <p>你好张幸</p> <p>你好张幸</p> <p>你好张幸</p> <p>你好张幸</p> <p>你好张幸</p> <i slot="iconTemp" class="m-icon m-icon-menu"></i> </template> </alert> </div> <script> /* alert提醒框有四种状态: info success error warning 设置的props: type 提醒框类型 默认为info title 提示信息 '这里有一个消息要提示' closeable 是否禁用关闭 默认为true showicon 是否显示图标 默认为fasle style 设置提醒框样式 默认为{} 定制模板: slot为iconTmp 定制icon模板 slot为titleTmp 定制提示信息结构 监控状态变化: 事件名close-click 点击关闭X触发 */ Vue.component("alert",{ props:{ type:{ type:String, default:"success" }, title:{ type:String, default:"这是一个提醒的消息" }, closeable:{ type:Boolean, default:true }, showicon:{ type:Boolean, default:false }, style:String }, computed:{ classes:function(){ return `m-alert-${this.type}` }, icon:function(){ return `m-icon-${this.type}` } }, template:` <div class="m-alert" :class="[classes]" :style="style" > <slot name="iconTemp"> <i class="m-icon" :class="[icon]" v-if="showicon"></i> </slot> <div class="m-content"> <slot name="messageTemp"> <span class="m-message">{{title}}</span> </slot> <i class="m-closebtn m-icon-close" v-if="closeable" @click="closeHander"></i> </div> </div> `, methods:{ closeHander(){ this.$emit("close-click") } } }) new Vue({ el:"#app", methods:{ closed(){ alert("关闭后执行的行为") } } }) </script> </body></html>
vue-封装模态框组件 发表于 2017-12-18 | 分类于 Vue | | 阅读次数 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Title</title> <style> p,h4{ margin:0; } .modal{ width: 500px; background-color: #fff; border: 1px solid rgba(0,0,0,.2); border-radius: 6px; box-shadow: 0 3px 9px rgba(0,0,0,.5); } .modal-header { padding: 15px; border-bottom: 1px solid #e5e5e5; } .modal-content div { padding: 20px; } .modal-footer { padding: 15px; text-align: right; border-top: 1px solid #e5e5e5; } .btn { padding: 5px 15px; border: none; outline: none; } .blue { color: #fff; background-color: #39f; border-color: #39f; } </style> <script src="vue.js"></script></head><body> <div id="app"> <m-alert @on-ok="onRect"></m-alert> <m-alert modal-title="提醒" @on-cancel="onfale"> <ul slot="model"> <li v-for="item of list">{{item}}</li> </ul> </m-alert> <m-alert> <div slot="modal-footer"> <span>确定</span> <span>重置</span> <span>返回</span> </div> </m-alert> </div> <script> /* 设置的props: modalTitle 提醒信息 默认为 '这是一个模态框' 定制模板: slot为modal-content 定制提醒信息模板 slot为modal-footer 定制底部模板 监控子组件状态变化: 事件名on-ok 点击确定触发 事件名on-cancel 点击取消触发 */ Vue.component('m-alert',{ props:{ modalTitle:{ type:String, default:"这是一个模态框" } }, template:` <div class="modal"> <div class="modal-header"> <h4>{{modalTitle}}</h4> </div> <div class="modal-content"> <slot name="model"> <div> 在这里添加内容 </div> </slot> </div> <div class="modal-footer"> <slot name="modal-footer"> <input class="btn blue" type="button" value="确定" @click="onHander" /> <input class="btn" type="button" value="取消" @click="onCanle" /> </slot> </div> </div> `, methods:{ onHander(){ // alert("a") this.$emit("on-ok") }, onCanle(){ this.$emit("on-cancel") } } }) list=[...'大家好吗'] new Vue({ el:"#app", data:{ list:list }, methods:{ onRect(){ alert("成功确定") }, onfale(){ alert("chen") } } }) </script></body></html>
vue-props验证 发表于 2017-12-17 | 分类于 Vue | | 阅读次数 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879<!DOCTYPE html><html lang="zh-cn"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title></title> <style> </style> <script src="./vue.js"></script> </head> <body> <div id="app"> <h3>父组件中使用了count</h3> <p>{{count}}</p> <custom-component :count="count" @increment-click="countHandle"></custom-component> </div> <script> //自定义事件 //全局组件 //count传入的类型为Number Vue.component('custom-component',{ props:{ count:{ //type:Number, //type:[Number,String], //default:10 //required:true validator:function (value){ console.log(value); return value > 10 } } }, data(){ return { incrementCount:this.count //作为局部这个组件的data的初始值 } }, computed:{ incrementCount2(){ return this.incrementCount } }, template:` <div> <h2>我是一个自定义的组件</h2> <input type="button" value="改变count的值" @click="changeCount" /> {{incrementCount2}} </div> `, methods:{ changeCount(){ this.incrementCount++; //通知父组件 发生了改变 this.$emit("increment-click") } } }) new Vue({ el:"#app", data:{ count:20 }, methods:{ countHandle(){ //alert("子组件点击了"); this.count++; } } }) </script> </body></html>