项目总结cms

需求:会议室预定,实现如下图的table表格,显示对应时间段的预定情况

  问题1: 当会议室名称较长时,如何实现表格中,div的高度自适应,占满整个td?

 

  实现思路,在完成了数据渲染之后,使用js重新设置高度

        

1       this.$nextTick( _=>{
2         var eles = this.$el.querySelectorAll('tbody .au-table-cell')
3 
4         eles.forEach( ele =>{
5           ele.style.height = ele.parentElement.clientHeight+'px'
6         })
7 
8       })

 

 

需求: 实现图片的拖拽排序,可能出现换行的情况


  实现思路:

    1: 拖拽过程中的动画:对于之前实现表格的拖拽排序,不需要考虑换行,所以可以判断拖拽的tr距离顶部的高度以及drag的tr元素距离顶部的高度之差,来设定拖拽过程中的动画,比如dragover的元素向上移动或者向下移动。可是图片会有换行,所以不能根据高度来判断。所以动画可以换一种思路实现。空白占位符

    2: 在页面初始化时,给ul绑定拖拽事件,(支持事件委托),在li标签上实现。

     拖拽img时,冒泡到li标签上。

1 // 工具函数  
2 // 参数: 指定的node元素
3 // 返回: 该node元素在列表中所占的位置角标(该indx值用于处理数据的删除插入)
4 
5         getNodeIndex(node){
6             return Array.apply(null, this.$refs.xinxiImgList.$el.children[0].querySelectorAll('li')).indexOf(node);
7         },

         

 1         dragstart(event) {
 2             if (event.target.parentNode.nodeName.toLowerCase() != 'ul') {
 3               return;
 4             }
 5             event.dataTransfer.effectAllowed = 'move';  
 6             this.startIndex = this.getNodeIndex(event.target) // 获取起始位置的索引
 7             window.requestAnimationFrame(() => {
 8               event.target.style.display = 'none';
 9               event.target.parentNode.insertBefore(this.placeholder, event.target);
10             });
11         },
12         dragend(event) {
13             if (event.target.parentNode.nodeName.toLowerCase() != 'ul') {
14                 return;
15             }
16             this.endIndex = this.getNodeIndex(this.placeholder) // 获取结束位置的索引
17             window.requestAnimationFrame(() => {
18                 event.target.style.display = '';
19                 this.placeholder.remove(); // 删除占位符
20                 // 修改数据
21                 this.pic.imgList.splice(this.endIndex, 0 , this.pic.imgList[this.startIndex])
22                 if (this.endIndex>this.startIndex) {
23                     this.pic.imgList.splice(this.startIndex,1)
24                 } else {
25                     this.pic.imgList.splice(this.startIndex+1,1)
26                 }
27             })
28         },
29         dragover(event) {
30             event.preventDefault();
31             let $ele = event.target  
32             let targetRect = $ele.getBoundingClientRect();
33             let clientX = event.clientX;
34             let middle = targetRect.width / 2 + targetRect.left;
35             if($ele.nodeName.toLowerCase() == 'img'){
36               $ele = $ele.parentNode
37             } else if ($ele.nodeName.toLowerCase() != 'li' || $ele.classList.contains('placeholder')){
38               return
39             }
40             if (clientX < middle) {
41               $ele.parentNode.insertBefore(this.placeholder, $ele);
42             } else {
43               $ele.parentNode.insertBefore(this.placeholder, $ele.nextElementSibling);
44             }
45             return false;
46         }        

 

// 在页面初始化的时候绑定事件

 1             this.$nextTick(() => {
 2                 let ul = this.$refs.xinxiImgList.$el.children[0]
 3                 // 创建placeholder
 4                 var newNode = document.createElement("li");
 5                 newNode.classList.add("placeholder")
 6                 this.placeholder = newNode
 7                 // 取消监听
 8                 ul.removeEventListener('dragstart', this.dragstart, false)
 9                 ul.removeEventListener("dragover", this.dragover, false)
10                 ul.removeEventListener("dragend", this.dragend, false);
11                 
12                 // 监听
13                 ul.addEventListener("dragstart", this.dragstart, false)
14                 ul.addEventListener("dragover", this.dragover, false)
15                 ul.addEventListener("dragend", this.dragend, false);           
16             })

 

 

tip: 关于window.requestAnimationFrame()

  The window.requestAnimationFrame() method tells the browser that you wish to perform an animation and requests that the browser call a specified function to update an animation before the next repaint. The method takes a callback as an argument to be invoked before the repaint.

window.requestAnimationFrame()方法告诉浏览器,你想要执行一个动画,并要求浏览器,在下一次重绘页面之前,执行一个特殊的函数去更新动画。这个方法有一个回调函数作为参数,他在下一次页面重绘之前执行。

 

3: 关于服务器时间和本地时间不同步的问题:

  服务器和前端改成所在的时区必须相同,否则时间解析会有差异

             

4: 高德地图

自定义一个组件

 1 export default {
 2     template: ` <div>
 3                     <div id='gaodeMap' style='height:400px'>{{ value }}</div>
 4                     <div class ='panel' style=' background-color: #ddf;color: #333;border: 1px solid silver;box-shadow: 3px 4px 3px 0px silver;position: absolute;top: 100px;right: 50%; border-radius: 5px;overflow: hidden;line-height: 20px;'>
 5                         <div id = 'message'></div>
 6                     </div>
 7                 </div>
 8     `,
 9     props: {
10         value: String,
11         lnglatXY: Array,
12     },
13     model: {
14     },
15     data: () => ({
16         map: '',
17     }),
18     watch: {
19         lnglatXY:function(val, oldval){
20             if(val[1] == oldval[1] && val[0] == oldval[0]) return 
21             this.map.setCenter(val)
22         }
23     },
24     mounted: function(){
25         this.init()
26     },
27     methods: {
28         init(){
29             var map = new AMap.Map('gaodeMap', {
30                 mapStyle: 'amap://styles/normal', //样式URL
31                 resizeEnable: true,
32                 zoom: 10,
33                 center: this.lnglatXY,
34                 scrollWheel: false
35             });
36             var message = document.getElementById('message');
37             //加载PositionPicker,loadUI的路径参数为模块名中 'ui/' 之后的部分
38             AMapUI.loadUI(['misc/PositionPicker'], (PositionPicker) => {
39                 var positionPicker = new PositionPicker({
40                     // mode:'dragMap',//'dragMap'、'dragMarker',默认为'dragMap'
41                     map:map
42                 });
43                 positionPicker.on('success', (positionResult) => {
44                     message.innerHTML = ''
45                     this.$emit('getPointZuobiao',positionResult.position)    
46                 });
47                 positionPicker.on('fail', function(positionResult) {
48                     message.innerHTML = '无法获取地址'
49                 });
50                 positionPicker.start();
51             });
52             
53             AMap.plugin(['AMap.ToolBar','AMap.Scale','AMap.OverView'],function(){
54                 map.addControl(new AMap.ToolBar());
55                 map.addControl(new AMap.Scale());
56                 map.addControl(new AMap.OverView({isOpen:true}));
57             });
58             this.map = map
59         }
60     }
61 }

参考: http://lbs.amap.com/fn/jsdemo_loader/?url=http%3A%2F%2Fwebapi.amap.com%2Fdemos%2Fgeocoder%2Fgeocoder-regeo.html

 

 

5:  遇到的问题: 在第一次初始化frame时,会获取到用户权限和用户信息,这些信息在 frame 部分显示。

  用户退出系统并再次登陆时,由于并没有重新初始化frame,所以frame的SSPA_componentReady方法没有调用,因此不会重新调用权限和用户信息的方法,权限和信息还保留上次登陆用户的信息。

解决方案: 设置一个全局变量,例如 window.__reload , 默认为false。 当用户进入系统后退出时,设置window.__reload = true, 若是直接打开登陆界面,那么不需要处理。

      在登陆界面判断,如果window.__reload为true,那么刷新,反之不刷新

 1       if(window.__reload === true){
 2           location.reload()
 3           return
 4       }
 5 //      if(localStorage.getItem('TOKEN')){
 6 //        dataHelper.userVerify(localStorage.getItem('TOKEN'),{forbidToast: true}).then(res=>{
 7 //          location.replace('#welcome')
 8 //        }).catch(res=>{
 9 //          localStorage.removeItem('TOKEN')
10 //        })
11 //      }

 

 6: 低版本的手机浏览器不支持es6的语法,所以字符串模版等写法不可用,

  另外,对于transform属性的设置,应该写作ele.style.transform = 'scale(0.5)'  , 而不应该用ele.style= 'transform: scale(0.5)'

 7: nginx 配置

 8: 金额和数字 输入框控件(vue指令)

 

 1 Vue.directive('numberOnly', { // au-input 只能输入数字
 2   bind: function (ele) {
 3     ele = ele.querySelector('input')
 4     this.handler = function () {
 5       ele.value = ele.value.replace(/\D+/, '')
 6       
 7     }
 8     ele.addEventListener('input', this.handler)
 9   }
10 })
11 Vue.directive('money', { // au-input 只能输入金额
12   bind: function (ele) {
13     ele = ele.querySelector('input')
14     var exp =/[^0-9.]$/;
15     
16     this.handler = function () {      
17       if(exp.test(ele.value)){ 
18         // 输入不正确
19         ele.style.borderColor = 'red'
20         return false; 
21       } else {
22         ele.style.borderColor = '#DDD'
23       }
24     }
25     this.format = function(){
26       if(!exp.test(ele.value)&&!!ele.value){ 
27         ele.value = parseFloat(ele.value).toFixed(2)        
28       }        
29     }
30     ele.addEventListener('input', this.handler)
31     ele.addEventListener('blur', this.format)
32   }
33 })

 

posted @ 2017-12-27 17:40  rrranmo  阅读(428)  评论(0编辑  收藏  举报