浏览代码

feat: 优化mdloader

zhenyulei 5 年之前
父节点
当前提交
3c4fdbab63

+ 3 - 2
loader/md-vue/config.js

@@ -1,6 +1,7 @@
 /* eslint-disable @typescript-eslint/no-var-requires */
-const Config = require('markdown-it-chain');
-const anchorPlugin = require('markdown-it-anchor');
+/*markdown-it的配置文件*/
+const Config = require('markdown-it-chain'); //链式配置
+const anchorPlugin = require('markdown-it-anchor'); //给页眉添加锚点
 const slugify = require('transliteration').slugify;
 const hljs = require('highlight.js');
 const containers = require('./containers');

+ 4 - 1
loader/md-vue/containers.js

@@ -10,10 +10,13 @@ module.exports = md => {
       const m = tokens[idx].info.trim().match(/^demo\s*(.*)$/);
       if (tokens[idx].nesting === 1) {
         const description = m && m.length > 1 ? m[1] : '';
+        /*
+        tokens是一个数组,里面是块级容器里面所有md代码的code,按照一定规则分割,例如
+        tokens[idx].type === 'fence'意味着被```包裹的东西
+        */
         const content = tokens[idx + 1].type === 'fence' ? tokens[idx + 1].content : '';
         return `<demo-block>
         ${description ? `<div>${md.render(description)}</div>` : ''}
-        <!--nutui-demo: ${content}:nutui-demo-->
         `;
       }
       return '</demo-block>';

+ 3 - 3
loader/md-vue/fence.js

@@ -6,9 +6,9 @@ module.exports = md => {
     // 判断该 fence 是否在 :::demo 内
     const prevToken = tokens[idx - 1];
     const isInDemoContainer = prevToken && prevToken.nesting === 1 && prevToken.info.trim().match(/^demo\s*(.*)$/);
-    if (token.info === 'html' && isInDemoContainer) {
-      return `<template #highlight><pre v-pre><code class="html">${md.utils.escapeHtml(token.content)}</code></pre></template>`;
-    }
+    // if (token.info === 'html' && isInDemoContainer) {
+    //   return `<template #highlight><pre v-pre><code class="html">${md.utils.escapeHtml(token.content)}</code></pre></template>`;
+    // }
     return defaultRender(tokens, idx, options, env, self);
   };
 };

+ 11 - 8
loader/md-vue/index.js

@@ -3,8 +3,7 @@ const { stripScript, stripTemplate, genInlineComponentText } = require('./util')
 const md = require('./config');
 
 module.exports = function(source) {
-  const content = md.render(source);
-
+  const content = md.render(source); //得到来自.md的解析出来的数据
   const startTag = '<!--nutui-demo:';
   const startTagLen = startTag.length;
   const endTag = ':nutui-demo-->';
@@ -21,18 +20,21 @@ module.exports = function(source) {
     output.push(content.slice(start, commentStart));
 
     const commentContent = content.slice(commentStart + startTagLen, commentEnd);
-    const html = stripTemplate(commentContent);
-    const script = stripScript(commentContent);
+
+    const html = stripTemplate(commentContent); //传入的是demo的代码部分,获取demo中的的html
+    const script = stripScript(commentContent); //传入的是demo的代码部分,获取demo中的的script
     let demoComponentContent = genInlineComponentText(html, script);
     const demoComponentName = `nutui-demo${id}`;
+    //output是一个数组,最终会拼接放入输出vue文件的template里面,也就是这一页的HTML
     output.push(`<template #source><${demoComponentName} /></template>`);
     componenetsString += `${JSON.stringify(demoComponentName)}: ${demoComponentContent},`;
 
     // 重新计算下一次的位置
-    id++;
-    start = commentEnd + endTagLen;
-    commentStart = content.indexOf(startTag, start);
-    commentEnd = content.indexOf(endTag, commentStart + startTagLen);
+    // demoComponentName 与id,命名每个demo组件名字用的,id会在while每一次循环+1,这样子组件从第一个到最后一个都不会重名。
+    // id++;
+    // start = commentEnd + endTagLen;
+    // commentStart = content.indexOf(startTag, start);
+    // commentEnd = content.indexOf(endTag, commentStart + startTagLen);
   }
 
   // 仅允许在 demo 不存在时,才可以在 Markdown 中写 script 标签
@@ -56,6 +58,7 @@ module.exports = function(source) {
   }
 
   output.push(content.slice(start));
+  console.log(output.length);
   const result = `
   <template>
     <section class="content nutui-doc">

+ 4 - 0
loader/md-vue/util.js

@@ -1,17 +1,20 @@
 /* eslint-disable @typescript-eslint/no-var-requires */
 const { compileTemplate, TemplateCompiler } = require('@vue/compiler-sfc');
 
+//获取script标签中的内容
 function stripScript(content) {
   const result = content.match(/<(script)>([\s\S]+)<\/\1>/);
   return result && result[2] ? result[2].trim() : '';
 }
 
+//获取style标签中的代码
 function stripStyle(content) {
   const result = content.match(/<(style)\s*>([\s\S]+)<\/\1>/);
   return result && result[2] ? result[2].trim() : '';
 }
 
 // 编写例子时不一定有 template。所以采取的方案是剔除其他的内容
+//获取template标签中的内容
 function stripTemplate(content) {
   content = content.trim();
   if (!content) {
@@ -57,6 +60,7 @@ function genInlineComponentText(template, script) {
     ${compiled.code.replace('return function render', 'function render')}
   `;
   // todo: 这里采用了硬编码有待改进
+  // 这部分是把字符串里面的export default 替换为const democomponentExport =便于后面的解构赋值
   script = script.trim();
   if (script) {
     script = script.replace(/export\s+default/, 'const democomponentExport =').replace(/import ({.*}) from 'vue'/g, (s, s1) => `const ${s1} = Vue`);

+ 41 - 7
src/packages/button/doc.md

@@ -14,12 +14,25 @@
 ### 基础用法
 
 :::demo
-``` javascript
-import { createApp } from 'vue';
-import { Button } from '@nutui/nutui';
-
-const app = createApp();
-app.use(Button);
+```html
+<template>
+  <div @click="clickMe">点击我</div>
+</template>
+<script>
+  export default{
+    setup(){
+      onMounted(){
+        console.log(aa);
+      }
+      function clickMe(){
+        console.log('nihao');
+      }
+      return {
+        clickMe
+      }
+    }
+  }
+</script>
 ```
 :::
 
@@ -51,4 +64,25 @@ app.use(Button);
 |序号|名称|备注|
 |--|--|--|
 |1|小花|等哈阿贾克斯|
-|2|小浪|阿师大丹江口市|
+|2|小浪|阿师大丹江口市|
+
+```html
+<template>
+  <div @click="clickMe">点击我</div>
+</template>
+<script>
+  export default{
+    setup(){
+      onMounted(){
+        console.log(aa);
+      }
+      function clickMe(){
+        console.log('nihao');
+      }
+      return {
+        clickMe
+      }
+    }
+  }
+</script>
+```

+ 25 - 0
src/packages/temp/demo.vue

@@ -0,0 +1,25 @@
+<template>
+  <div class="demo">
+    <h2>基础用法</h2>
+    <nut-cell>
+      <nut-temp name="wifi"></nut-temp>
+      <nut-temp name="mail" txt="test txt"></nut-temp>
+    </nut-cell>
+  </div>
+</template>
+
+<script lang="ts">
+import { createComponent } from '@/utils/create';
+const { createDemo } = createComponent('temp');
+export default createDemo({
+  props: {},
+  setup() {
+    return {};
+  }
+});
+</script>
+
+<style lang="scss" scoped>
+.nut-temp {
+}
+</style>

+ 65 - 0
src/packages/temp/doc.md

@@ -0,0 +1,65 @@
+# Temp xx组件
+
+### 介绍
+
+基于 xxxxxxx
+
+### 安装
+
+``` javascript
+import { createApp } from 'vue';
+import { Temp } from '@nutui/nutui';
+
+const app = createApp();
+app.use(Temp);
+
+```
+
+## 代码演示
+
+### 基础用法1
+
+`Icon` 的 `name` 属性支持传入图标名称或图片链接。
+
+```html
+<nut-temp name="wifi"></nut-temp>
+<nut-temp name="mail"></nut-temp>
+```
+
+### 基础用法2
+
+`Icon` 的 `name` 属性支持传入图标名称或图片链接。
+
+```html
+<nut-temp name="wifi"></nut-temp>
+<nut-temp name="mail"></nut-temp>
+```
+
+### 基础用法3
+
+`Icon` 的 `name` 属性支持传入图标名称或图片链接。
+
+```html
+<nut-temp name="wifi"></nut-temp>
+<nut-temp name="mail"></nut-temp>
+```
+
+
+## API
+
+### Props
+
+| 参数 | 说明 | 类型 | 默认值 |
+| --- | --- | --- | --- |
+| name | 图标名称或图片链接 | _string_ | - |
+| color | 图标颜色 | _string_ | - |
+| size | 图标大小,如 `20px` `2em`,默认单位为`px` | _number \| string_ | - |
+| class-prefix | 类名前缀,用于使用自定义图标 | _string_ | `nutui-icon` |
+| tag | HTML 标签 | _string_ | `i` |
+
+### Events
+
+| 事件名 | 说明           | 回调参数       |
+| ------ | -------------- | -------------- |
+| click  | 点击图标时触发 | _event: Event_ |
+

+ 2 - 0
src/packages/temp/index.scss

@@ -0,0 +1,2 @@
+.nut-temp {
+}

+ 40 - 0
src/packages/temp/index.vue

@@ -0,0 +1,40 @@
+<template>
+  <view :class="classes" @click="handleClick">
+    <view>{{ name }}</view>
+    <view>{{ txt }}</view>
+  </view>
+</template>
+<script lang="ts">
+import { toRefs, PropType } from 'vue';
+import { createComponent } from '@/utils/create';
+const { componentName, create } = createComponent('temp');
+
+export default create({
+  props: {
+    name: {
+      type: String,
+      default: ''
+    },
+    txt: {
+      type: String,
+      default: ''
+    }
+  },
+  components: {},
+  emits: ['click'],
+
+  setup(props, { emit, slots }) {
+    const { name, txt } = toRefs(props);
+
+    const handleClick = (event: Event) => {
+      emit('click', event);
+    };
+
+    return { name, txt, handleClick };
+  }
+});
+</script>
+
+<style lang="scss">
+@import 'index.scss';
+</style>

+ 1 - 0
src/sites/doc/components/demo-block/demoBlock.vue

@@ -1,5 +1,6 @@
 <template>
   <div>
+    <slot name="highlight"></slot>
     <slot></slot>
     <p class="online-part">
       <a href="//gitpod.io/#https://github.com/jdf2e/nutui.git" target="_blank" class="online-btn">在线运行</a>