浏览代码

Merge branch 'v2' of https://github.com/jdf2e/nutui into v2

jin cao 7 年之前
父节点
当前提交
428eeab69c

+ 5 - 1
.gitignore

@@ -9,4 +9,8 @@ coverage/
 sites/doc/view
 sites/doc/page
 package-lock.json
-yarn.lock
+yarn.lock
+docshashCache.text
+srchashCache.text
+localsrc.cache
+localdocs.cache

+ 4 - 4
docs/intro.md

@@ -2,16 +2,16 @@
 
 NutUI是一套京东风格的移动端Vue组件库,开发和服务于移动Web界面的企业级前中后台产品。
 
+<div style="margin:30px 0;">
+    <img src="http://img14.360buyimg.com/uba/jfs/t1/8543/6/11560/22014/5c2c6136E8023ac0a/6abbd9de10999c48.png" width="150" alt="NutUI">
+</div>
+
 <iframe src="https://ghbtns.com/github-btn.html?user=jdf2e&repo=nutui&type=star&count=true" frameborder="0" scrolling="0" width="60px" height="20px"></iframe>
 
 <iframe src="https://ghbtns.com/github-btn.html?user=jdf2e&repo=nutui&type=watch&count=true&v=2" frameborder="0" scrolling="0" width="70px" height="20px"></iframe>
 
 <iframe src="https://ghbtns.com/github-btn.html?user=jdf2e&repo=nutui&type=fork&count=true" frameborder="0" scrolling="0" width="60px" height="20px"></iframe>
 
-<div style="margin:30px 0;">
-    <img src="http://img14.360buyimg.com/uba/jfs/t1/8543/6/11560/22014/5c2c6136E8023ac0a/6abbd9de10999c48.png" width="150" alt="NutUI">
-</div>
-
 ## 特性
 
 * 跨平台,自动转微信小程序组件(稍后上线,敬请期待)

+ 2 - 0
package.json

@@ -72,6 +72,7 @@
     "babel-preset-env": "1.7.0",
     "babel-preset-stage-2": "6.24.1",
     "chalk": "2.4.1",
+    "chokidar": "^2.0.4",
     "clipboard": "2.0.1",
     "copy": "0.3.2",
     "copy-webpack-plugin": "4.5.4",
@@ -83,6 +84,7 @@
     "eslint-plugin-vue": "4.7.1",
     "expect": "23.6.0",
     "file-loader": "1.1.11",
+    "folder-hash": "^2.1.2",
     "friendly-errors-webpack-plugin": "1.7.0",
     "google-code-prettify": "1.0.5",
     "has": "1.0.3",

+ 158 - 48
scripts/mdToVue.js

@@ -1,10 +1,14 @@
 const fs = require('fs');
 var path = require('path');
+//hash获取工具
+let { hashElement } = require('folder-hash');
 //marked转换工具
 let marked = require('marked');
 if (!marked) {
     console.log('you need npm i marked -D!');
 }
+//文件监听
+let Chokidar = require('chokidar');
 // 基本配置文件信息
 let {version} = require("../package.json");
 //vue js脚本
@@ -32,12 +36,12 @@ rendererMd.code = function (code, infostring, escaped) {
         code = code.replace(/@latest/g, '@' + version)
     }
 
-    return '<pre class="prettyprint"><span class="lang">' + lang + '</span><code class="'
+    return '<pre class="prettyprint"><span class="lang">' + lang + '</span><div class="code-wrapper"><code class="'
         + this.options.langPrefix
         + escape(lang, true)
         + '">'
         + (escaped ? code : escape(code, true))
-        + '</code><i class="copy" copy="copy" data-clipboard-action="copy" data-clipboard-target="code" title="复制代码"></i><i toast="toast" title="全屏"></i></pre>\n';
+        + '</code></div><i class="copy" copy="copy" data-clipboard-action="copy" data-clipboard-target="code" title="复制代码"></i><i toast="toast" title="全屏"></i></pre>\n';
 };
 marked.setOptions({
     renderer: rendererMd,
@@ -118,48 +122,149 @@ function readDirRecur(fileSrc, callback) {
       files.length === 0 && callback()
     })
 }
+function fileReadStar(filedir,callback){
+    fs.readFile(filedir, 'utf-8', (err, data) => {
+        let html = marked(data); 
+        let mdName = "";
+        let opensName = filedir.replace(/(^.*\/|.md)/g,"");                    
+        //如果是doc文件以前缀 为
+        if (opensName === 'doc') {
+            mdName = filedir.replace(/(^.*packages\/|\/doc\.md)/g,'');
+        } else {
+            //如果不是doc命名的文件
+            mdName = opensName;
+        } 
+        callback({
+            mdName:mdName,
+            html:html
+        })   
+    });
+}
 /**
  * 判断是否位md文件 并进行操作
+ * 判断文件是否有改动
  * @src {string} 打开的文件目录
+ * @hasobj {obj} hash对象
+ * @callback {fn} 回调函数
  */
-function ismd(src,callback){
+function ismd(src,hasobj,callback){
     //判断文件类型是否是md文件    
     let filedir = src;  
     //return new Promise((resolve,reject)=>{
     if (/.md$/.test(filedir)) {
-    //文件读取
-        fs.readFile(filedir, 'utf-8', (err, data) => {
-            let html = marked(data); 
-            let mdName = "";
-            let opensName = filedir.replace(/(^.*\/|.md)/g,"");                    
-            //如果是doc文件以前缀 为
-            if (opensName === 'doc') {
-                mdName = filedir.replace(/(^.*packages\/|\/doc\.md)/g,'');
-            } else {
-                //如果不是doc命名的文件
-                mdName = opensName;
-            } 
-            callback({
-                mdName:mdName,
-                html:html
-            })   
-        });
+        if(hasobj.fileText){
+            let hasHObjs = hasobj;
+            hashElement(filedir).then(res=>{                
+                if(hasHObjs.fileText.indexOf(res.hash)==-1){
+                    //执行写入
+                    //同时更新缓存
+                    fs.writeFileSync(hasHObjs.cachePath,
+                        hasHObjs.fileText+'|'+res.hash
+                        ,'utf-8');
+
+                    fileReadStar(filedir,(obj)=>{
+                        callback(obj)
+                    })
+                }
+            })
+        }else{
+            //如果没有hash 直接做下一部
+            fileReadStar(filedir,(obj)=>{
+                callback(obj)
+            })
+        }
+        //对md文件存储 hash       
+        //文件读取
+        
     }
 }
+/**
+ * 检查文件是否存折
+ * @param {*} path 
+ * @param {*} callback 
+ */
+function checkIsexists (path,callback){  
+    let pathFileName = path.replace(/[^a-zA-Z]/g,'');
+    let cacheName = './local'+pathFileName+'.cache';
+    fs.exists(cacheName, res=>{
+        console.log(res)
+        if(!res){
+            fs.writeFile(cacheName,'','utf8',()=>{
+                callback(cacheName)
+            })
+        }else{
+            callback(cacheName)
+        }
+    }) 
+}
+/**
+ * 执行文件缓存
+ */
+let outhash = [];
+function pushHash(obj){ 
+    //紧紧插入md文件hash                       
+    if(/\.md$/.test(obj.name)&&obj['hash']){
+        outhash.push(obj.hash);
+    }
+    if(obj['children']&&obj['children'].length>0){
+        obj['children'].map(res=>{
+            pushHash(res)
+        })
+    }              
+}
+//hash 对比
+/**
+ * 初始化检查是否有md文件 hash
+ * 如果没有 hash 创建一个 json文件并把 md文件 hash进去 用来做缓存
+ * 初始化获取所有md文件的 hash
+ * @param {*} path 
+ */
+function comparehash(path,callback){
+    checkIsexists(path,(cachePath)=>{       
+        //获取文件内容
+        let fileText = fs.readFileSync(cachePath,'utf-8');        
+         //获取文件 hash    
+        hashElement(path, {
+            folders: { exclude: ['.*', 'node_modules', 'test_coverage'] },
+            files: { include: ['*.md'],exclude:['*.js','*.vue','*.scss','__test__'] }
+        }).then(hash => {           
+            if(fileText){
+                //如果有内容
+                callback({
+                    fileText:fileText,
+                    cachePath:cachePath
+                })
+            }else{
+                pushHash(hash)               
+                fs.writeFileSync(cachePath,outhash.join('|'),'utf-8');
+                //如果没有内容
+                callback({
+                    fileText:fileText,
+                    cachePath:cachePath
+                })
+            }
+        })
+        .catch(error => {
+            return console.error('hashing failed:', error);
+        }); 
+    })
+     
+}
 //文件监听
-function filelisten(){    
-    let fsWatcher = fs.watchFile(filedir, {
+function filelisten(param){  
+    let watcher = Chokidar.watch(param.entry,{
         persistent: true,
-        persistent: 1000
-    }, (err, data) => {
-        //  console.log(err,data,filedir);
-        fs.readFile(filedir, 'utf-8', (err, data) => {
-            let html = marked(data);
-            let filedirarry = filedir.split('/');
-            let fileNames = filedirarry[filedirarry.length - 2];
-            createdFile(outPath + fileNames + '.vue', html, nohead)
-        });
-    });
+        usePolling: true,
+    })
+    let log = console.dir.bind(console);
+    let watchAction = function({event, eventPath}){      
+        // 这里进行文件更改后的操作
+        fileReadStar(eventPath,(res)=>{           
+            createdFile(param.output + res.mdName + '.vue', res.html, param.needCode)
+        })
+    }
+    watcher.on('change', path => watchAction({event: 'change', eventPath: path}))
+    .on('unlink', path => watchAction({event: 'remove', eventPath: path}));
 }
 /**
  * 文件转md
@@ -169,33 +274,36 @@ function filelisten(){
  * @needCode {boolen} 是否需要二维码 默认 true
  */
 function fileDisplay(param) {
-    // 获取文件
-    readDirRecur(param.entry, function(filePath) {    
-        //文件列表
+    //检查文件是否第一次初始化并获取hash
+    comparehash(param.entry,(hashMsgObj)=>{
         
-        fileList.map(item=>{  
-            ismd(item,res=>{
-                //res md文件处理结果           
-                createdFile(param.output + res.mdName + '.vue', res.html, param.needCode)
-            })
-        })    
+        // 获取目录下所有文件
+        readDirRecur(param.entry, function(filePath) {    
+            //文件列表        
+            fileList.map(item=>{              
+                ismd(item,hashMsgObj,res=>{
+                    //res md文件处理结果           
+                    createdFile(param.output + res.mdName + '.vue', res.html, param.needCode)
+                })
+            })    
+        });
     });
+    
 }
-//md转 其他格式类型
+
 /**
- * 
+ * 输出的文件目录 是否存在
  * @outPath {String} 输出的文件目录 
  */
 function ishasOutFile(outPath,callback){
     fs.stat(outPath,(err,res)=>{       
         if(err){
-            fs.mkdir(outPath,erro=>{
-                if(erro){
-                    
+            fs.mkdir(outPath,err=>{
+                if(err){
+                    console.log(err)
                 }else{                  
                     callback()
-                }
-               
+                }               
             })
         }else{
             callback()
@@ -220,6 +328,8 @@ function MdToHtml(commomOption) {
     ishasOutFile(params.output,()=>{
          //获取所有的md 转html的结果
         fileDisplay(params);
+        //文件监听 
+        filelisten(params);
     });
    
 }

+ 12 - 12
sites/doc/info.vue

@@ -65,22 +65,22 @@ export default {
   },
   watch: {
     packages() {
-      const compare = (obj1, obj2) => {
-        const val1 = obj1.name;
-        const val2 = obj2.name;
-        if (val1 < val2) {
-          return -1;
-        } else if (val1 > val2) {
-          return 1;
-        } else {
-          return 0;
-        }
-      };
+      // const compare = (obj1, obj2) => {
+      //   const val1 = obj1.name;
+      //   const val2 = obj2.name;
+      //   if (val1 < val2) {
+      //     return -1;
+      //   } else if (val1 > val2) {
+      //     return 1;
+      //   } else {
+      //     return 0;
+      //   }
+      // };
       let that = this;
       let tempAry = [];
       let temp = {};
       let sorts = this.sorts;
-      let sortArys = [...this.packages].sort(compare);
+      let sortArys = [...this.packages];
       sortArys.map(item => {
         let name = sorts[item.sort];
         if (!temp[name]) {

文件差异内容过多而无法显示
+ 7 - 10
src/packages/backtop/backtop.scss


+ 114 - 111
src/packages/backtop/backtop.vue

@@ -1,118 +1,121 @@
 <template>
-    <div :class="['nut-backtop', {'show': backTop}]" :style="styles" @click="goto">
-        <slot>
-            <div class="nut-backtop-main">
-            </div>
-        </slot>
-    </div>
+  <div :class="['nut-backtop', {'show': backTop}]" :style="styles" @click="goto">
+    <slot>
+      <div class="nut-backtop-main"></div>
+    </slot>
+  </div>
 </template>
 <script>
+export default {
+  name: "nut-backtop",
+  props: {
+    distance: {
+      type: Number,
+      default: 200
+    },
+    bottom: {
+      type: Number,
+      default: 20
+    },
+    right: {
+      type: Number,
+      default: 10
+    },
+    duration: {
+      type: Number,
+      default: 1000
+    },
+    zIndex: {
+      type: Number,
+      default: 1111
+    }
+  },
+  data() {
+    return {
+      backTop: false
+    };
+  },
+  mounted() {
+    window.addEventListener("scroll", this.handleScroll, false);
+    window.addEventListener("resize", this.handleScroll, false);
+  },
+  beforeDestroy() {
+    window.removeEventListener("scroll", this.handleScroll, false);
+    window.removeEventListener("resize", this.handleScroll, false);
+  },
+  computed: {
+    styles() {
+      return {
+        bottom: `${this.bottom}px`,
+        right: `${this.right}px`,
+        "z-index": this.zIndex
+      };
+    }
+  },
+  methods: {
+    handleScroll() {
+      this.backTop = window.pageYOffset >= this.distance;
+    },
+    goto() {
+      const sTop =
+        document.documentElement.scrollTop || document.body.scrollTop;
+      this.scrollTop(window, sTop, 0, this.duration);
+      this.$emit("click");
+    },
+    scrollTop(el, from = 0, to, duration = 500, endCallback) {
+      this.el = el;
+      let lastTime = 0;
+      let vendors = ["webkit", "moz"];
+      for (
+        let x = 0;
+        x < vendors.length && !window.requestAnimationFrame;
+        ++x
+      ) {
+        window.requestAnimationFrame =
+          window[vendors[x] + "RequestAnimationFrame"];
+        window.cancelAnimationFrame =
+          window[vendors[x] + "CancelAnimationFrame"] ||
+          window[vendors[x] + "CancelRequestAnimationFrame"];
+      }
 
-    export default {
-        name:'nut-backtop',
-        props: {
-            distance: {
-                type: Number,
-                default: 200
-            },
-            bottom: {
-                type: Number,
-                default: 20
-            },
-            right: {
-                type: Number,
-                default: 10
-            },
-            duration: {
-                type: Number,
-                default: 1000
-            },
-            zIndex: {
-                type: Number,
-                default: 1111
-            }
-        },
-        data () {
-            return {
-                backTop: false
-            };
-        },
-        mounted () {
-            window.addEventListener('scroll', this.handleScroll, false);
-            window.addEventListener('resize', this.handleScroll, false);
-        },
-        beforeDestroy () {
-            window.removeEventListener('scroll', this.handleScroll, false);
-            window.removeEventListener('resize', this.handleScroll, false);
-        },
-        computed: {
-            styles () {
-                return {
-                    'bottom': `${this.bottom}px`,
-                    'right': `${this.right}px`,
-                    'z-index': this.zIndex
-                };
-            }
-        },
-        methods: {
-            handleScroll () {
-                this.backTop = window.pageYOffset >= this.distance;
-            },
-            goto () {
-                const sTop = document.documentElement.scrollTop || document.body.scrollTop;
-                this.scrollTop(window, sTop, 0, this.duration);
-                this.$emit('click');
-            },
-            scrollTop(el, from = 0, to, duration = 500, endCallback) {
-                this.el = el;
-                let lastTime = 0;
-                let vendors = ['webkit', 'moz'];
-                for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
-                    window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame'];
-                    window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] ||    // name has changed in Webkit
-                                                window[vendors[x] + 'CancelRequestAnimationFrame'];
-                }
-
-                if (!window.requestAnimationFrame) {
-                    window.requestAnimationFrame = function(callback, element) {
-                        var currTime = new Date().getTime();
-                        var timeToCall = Math.max(0, 16.7 - (currTime - lastTime));
-                        var id = window.setTimeout(function() {
-                            callback(currTime + timeToCall);
-                        }, timeToCall);
-                        lastTime = currTime + timeToCall;
-                        return id;
-                    };
-                }
-                if (!window.cancelAnimationFrame) {
-                    window.cancelAnimationFrame = function(id) {
-                        clearTimeout(id);
-                    };
-                }
-                const difference = Math.abs(from - to);
-                const step = Math.ceil(difference / duration * 50);
-
-                
-                this.scroll(from, to, step, endCallback);
-            },
-            scroll(start, end, step, endCallback) {
-                if (start === end) {
-                    endCallback && endCallback();
-                    return;
-                }
+      if (!window.requestAnimationFrame) {
+        window.requestAnimationFrame = function(callback, element) {
+          let currTime = new Date().getTime();
+          let timeToCall = Math.max(0, 16.7 - (currTime - lastTime));
+          let id = window.setTimeout(function() {
+            callback(currTime + timeToCall);
+          }, timeToCall);
+          lastTime = currTime + timeToCall;
+          return id;
+        };
+      }
+      if (!window.cancelAnimationFrame) {
+        window.cancelAnimationFrame = function(id) {
+          clearTimeout(id);
+        };
+      }
+      const difference = Math.abs(from - to);
+      const step = Math.ceil((difference / duration) * 50);
 
-                let d = (start + step > end) ? end : start + step;
-                if (start > end) {
-                    d = (start - step < end) ? end : start - step;
-                }
-                if (this.el === window) {
-                    window.scrollTo(d, d);
-                } else {
-                    this.el.scrollTop = d;
-                }
-                window.requestAnimationFrame(() => this.scroll(d, end, step));
-            }
+      this.scroll(from, to, step, endCallback);
+    },
+    scroll(start, end, step, endCallback) {
+      if (start === end) {
+        endCallback && endCallback();
+        return;
+      }
 
-        }
-    };
+      let d = start + step > end ? end : start + step;
+      if (start > end) {
+        d = start - step < end ? end : start - step;
+      }
+      if (this.el === window) {
+        window.scrollTo(d, d);
+      } else {
+        this.el.scrollTop = d;
+      }
+      window.requestAnimationFrame(() => this.scroll(d, end, step));
+    }
+  }
+};
 </script>

+ 66 - 20
src/packages/backtop/demo.vue

@@ -1,36 +1,82 @@
 <template>
-    <div class="back-top-demo"> 
-      这个页面很长...<br>       
-      这个页面很长...<br>       
-      这个页面很长...<br>       
-      这个页面很长...<br>       
-      这个页面很长...<br>       
-      这个页面很长...<br>       
-      这个页面很长...<br>             
-      <nut-backtop @click="handleClick"></nut-backtop>
-    </div>
+  <div class="back-top-demo">
+    <h3>《再别康桥》</h3>
+    <p>徐志摩</p>
+    <p>轻轻的我走了,正如我轻轻的来;</p>
+    <p>我轻轻的招手,作别西天的云彩。</p>
+    <p>那河畔的金柳,是夕阳中的新娘;</p>
+    <p>波光里的艳影,在我的心头荡漾。</p>
+    <p>软泥上的青荇,油油的在水底招摇;</p>
+    <p>在康桥的柔波里,</p>
+    <p>我甘心做一条水草!</p>
+    <p>那榆荫下的一潭,</p>
+    <p>不是清泉,是天上虹</p>
+    <p>揉碎在浮藻间,沉淀着彩虹似的梦。</p>
+    <p>寻梦?撑一支长蒿,</p>
+    <p>向青草更青处漫溯,</p>
+    <p>满载一船星辉,在星辉斑斓里放歌。</p>
+    <p>但我不能放歌,悄悄是别离的笙箫;</p>
+    <p>夏虫也为我沉默,沉默是今晚的康桥!</p>
+    <p>悄悄的我走了,正如我悄悄的来;</p>
+    <p>我挥一挥衣袖,不带走一片云彩。</p>
+
+    <h3>《乡愁》</h3>
+    <p>余光中</p>
+    <p>小时侯</p>
+    <p>乡愁是一枚小小的邮票</p>
+    <p>我在这头</p>
+    <p>母亲在那头</p>
+    <p>长大后</p>
+    <p>乡愁是一张窄窄的船票</p>
+    <p>我在这头</p>
+    <p>新娘在那头</p>
+    <p>之后呵</p>
+    <p>乡愁是一方矮矮的坟墓</p>
+    <p>我在外头</p>
+    <p>母亲呵在里头</p>
+    <p>而此刻</p>
+    <p>乡愁是一湾浅浅的海峡</p>
+    <p>我在这头</p>
+    <p>大陆在那头</p>
+    
+    <h3>《盼望》</h3>
+    <p>席慕容</p>
+    <p>其实我盼望的</p>
+    <p>也但是就只是那一瞬</p>
+    <p>我从没要求过你给我</p>
+    <p>你的一生</p>
+    <p>如果能在开满了栀子花的山坡上</p>
+    <p>与你相遇如果能</p>
+    <p>深深地爱过一次再别离</p>
+    <p>那麽再长久的一生</p>
+    <p>不也就只是就只是</p>
+    <p>回首时</p>
+    <p>那短短的一瞬</p>
+    <nut-backtop @click="handleClick"></nut-backtop>
+  </div>
 </template>
 
 <script>
 export default {
-  components: {
-
-  },
+  components: {},
   data() {
     return {};
   },
   methods: {
-      handleClick(){
-        console.log('触发回到顶部')
-      }
+    handleClick() {
+      console.log("触发回到顶部");
+    }
   }
 };
 </script>
 
 <style lang="scss" scoped>
-  .back-top-demo {
-    height: 1600px;
-    line-height: 400px;
-    text-align: center;
+.back-top-demo {
+  height: 1600px;
+  line-height: 2;
+  text-align: center;
+  p {
+    font-size: 14px;
   }
+}
 </style>

+ 1 - 1
src/packages/buttongroup/doc.md

@@ -4,7 +4,7 @@
 
 常规按钮组
 
-```html
+```html3123123213123123123423423423431231233123123123123123123
 <nut-button-group>
   <nut-button 
     type="light"

+ 1 - 1
src/packages/cell/doc.md

@@ -16,7 +16,7 @@
 ```html
 <nut-cell 
   :isLink = "true"
-  title = "左侧主标题" 
+  title = "左侧主标题" 312312312423423423423
   subTitle = "左侧副标题"
   desc="右侧描述文字">
 </nut-cell>