HBuilderX

HBuilderX

极客开发工具
uni-app

uni-app

开发一次,多端覆盖
uniCloud

uniCloud

云开发平台
HTML5+

HTML5+

增强HTML5的功能体验
MUI

MUI

上万Star的前端框架

云函数上传不了

昨天一键登录还可以,今天就报错,云函数phone-login上传失败。失败原因:InvalidSpaceId.NotFound: The specified SpaceId does not exist. RequestId: 6E2A734C-218E-55BB-AA57-9AC1433CCB9F POST

继续阅读 »

昨天一键登录还可以,今天就报错,云函数phone-login上传失败。失败原因:InvalidSpaceId.NotFound: The specified SpaceId does not exist. RequestId: 6E2A734C-218E-55BB-AA57-9AC1433CCB9F POST

收起阅读 »

hbuilderx 增加elementui 提示

参考:https://github.com/snowffer/Element-UI-Snippets-VSCode
工具-代码设置-vue代码块

{  
    // 注意:本文档仅支持单行注释,并且'//'前不能有任何非空字符!!!  
    //  
    // HBuilderX使用json扩展代码块,兼容vscode的代码块格式  
    // 本文档修改完毕,保存即可生效,无需重启。  
    // 本文档用于用户自定义{1}代码块。  
    // 每个配置项的说明如下:  
    // 'key'    :代码块显示名称,显示在代码助手列表中的名字,以下例子中'console.log'就是一个key。  
    // 'prefix' :代码块的触发字符,就是敲什么字母匹配这个代码块。  
    // 'body'   :代码块的内容。内容中有如下特殊格式  
    //          $1 表示代码块输入后光标的所在位置。如需要多光标,就在多个地方配置$1,如该位置有预置数据,则写法是${1:foo1}。多选项即下拉候选列表使用${1:foo1/foo2/foo3}  
    //          $2 表示代码块输入后再次按tab后光标的切换位置tabstops(代码块展开后按tab可以跳到下一个tabstop)  
    //          $0代表代码块输入后最终光标的所在位置(也可以按回车直接跳过去)。  
    //          双引号使用\\'转义  
    //          换行使用多个数组表示,每个行一个数组,用双引号包围,并用逗号分隔  
    //          缩进需要用\\t表示,不能直接输入缩进!  
    // 'triggerAssist' :为true表示该代码块输入到文档后立即在第一个tabstop上触发代码提示,拉出代码助手,默认为false。  
    // 每个代码块以key为主键,多个代码块需要逗号分隔。  
    // 如果json语法不合法,底部会弹出错误信息,请注意修正。  
    // 例子:  
    // "console.log": {  
    //  "prefix": "logtwo",  
    //  "body": [  
    //      "console.log('$1');",  
    //      "\tconsole.log('$2');"  
    //  ],  
    //  "triggerAssist": false,  
    //  "description": "Log output to console twice"  
    // }  

     //elementui提示  
     //https://github.com/snowffer/Element-UI-Snippets-VSCode/tree/master/snippets  
     "Basic: Layout el-row": {  
             "prefix": "elrow",  
             "body": [  
                 "<el-row :gutter=\"${1:20}\">",  
                     "\t<el-col :span=\"${2:12}\" :offset=\"${3:0}\">${4}</el-col>",  
                     "\t<el-col :span=\"${5:12}\" :offset=\"${6:0}\">${7}</el-col>",  
                 "</el-row>",  
                 "${8}"  
             ],  
             "description": "Element UI <el-row> with <el-col>"  
         },  

         "Basic: Layout el-col": {  
             "prefix": "elcol",  
             "body": [  
                 "<el-col :span=\"${1}\" :offset=\"${2:0}\">",  
                 "\t${3}",  
                 "</el-col>",  
                 "${4}"  
             ],  
             "description": "Element UI <el-col>"  
         },  

         "Basic: Layout hidden class": {  
             "prefix": "elhc",  
             "body": [  
                 "${1|hidden-xs-only,hidden-sm-only,hidden-sm-and-down,hidden-sm-and-up,hidden-md-only,hidden-md-and-down,hidden-md-and-up,hidden-lg-only,hidden-lg-and-down,hidden-lg-and-up,hidden-xl-only|}"  
             ],  
             "description": "Element UI hidden class"  
         },  

         "Basic: Container el-container": {  
             "prefix": "elcon",  
             "body": [  
                 "<el-container :direction=\"${1:vertical}\">",  
                     "\t<el-header height=\"$2\">",  
                         "\t\t${3:<!-- Header content -->}",  
                     "\t</el-header>",  
                     "\t<el-container :direction=\"${4:horizontal}\">",  
                         "\t\t<el-aside width=\"${5:200px}\">",  
                             "\t\t\t${6:<!-- Aside content -->}",  
                         "\t\t</el-aside>",  
                         "\t\t<el-container :direction=\"${7:vertical}\">",  
                             "\t\t\t<el-main height=\"$8\">",  
                                 "\t\t\t\t${9:<!-- Main content -->}",  
                             "\t\t\t</el-main>",  
                             "\t\t\t<el-footer height=\"$10\">",  
                                 "\t\t\t\t${11:<!-- Footer content -->}",  
                             "\t\t\t</el-footer>",  
                         "\t\t</el-container>",  
                     "\t</el-container>",  
                 "</el-container>",  
                 "${12}"  
             ],  
             "description": "Element UI <el-container>"  
         },  

         "Basic: Container el-header": {  
             "prefix": "elhe",  
             "body": [  
                 "<el-header height=\"$1\">",  
                     "\t${2:<!-- Header content -->}",  
                 "</el-header>",  
                 "${3}"  
             ],  
             "description": "Element UI <el-header>"  
         },  

         "Basic: Container el-aside": {  
             "prefix": "elas",  
             "body": [  
                 "<el-aside width=\"${1:200px}\">",  
                     "\t${2:<!-- Aside content -->}",  
                 "</el-aside>",  
                 "${3}"  
             ],  
             "description": "Element UI <el-aside>"  
         },  

         "Basic: Container el-main": {  
             "prefix": "elma",  
             "body": [  
                 "<el-main height=\"${1}\">",  
                     "\t${2:<!-- Main content -->}",  
                 "</el-main>",  
                 "${3}"  
             ],  
             "description": "Element UI <el-main>"  
         },  

         "Basic: Container el-footer": {  
             "prefix": "elfo",  
             "body": [  
                 "<el-footer height=\"${1}\">",  
                     "\t${2:<!-- Footer content -->}",  
                 "</el-footer>",  
                 "${3}"  
             ],  
             "description": "Element UI <el-footer>"  
         },  

         "Basic: Color blue": {  
             "prefix": "elcb",  
             "body": ["#409EFF"],  
             "description": "Element UI Color Blue"  
         },  

         "Basic: Color danger": {  
             "prefix": "elcd",  
             "body": ["#F56C6C"],  
             "description": "Element UI Color Danger"  
         },  

         "Basic: Color info": {  
             "prefix": "elci",  
             "body": ["#909399"],  
             "description": "Element UI Color Info"  
         },  

         "Basic: Color success": {  
             "prefix": "elcs",  
             "body": ["#67C23A"],  
             "description": "Element UI Color Success"  
         },  

         "Basic: Color waring": {  
             "prefix": "elcw",  
             "body": ["#E6A23C"],  
             "description": "Element UI Color Waring"  
         },  

         "Basic: Color primary text": {  
             "prefix": "elcpt",  
             "body": ["#303133"],  
             "description": "Element UI Color Primary Text"  
         },  

         "Basic: Color regular text": {  
             "prefix": "elcrt",  
             "body": ["#606266"],  
             "description": "Element UI Color Regular Text"  
         },  

         "Basic: Color secondary text": {  
             "prefix": "elcst",  
             "body": ["#909399"],  
             "description": "Element UI Color Secondary Text"  
         },  

         "Basic: Color placeholder text": {  
             "prefix": "elcht",  
             "body": ["#C0C4CC"],  
             "description": "Element UI Color Placeholder Text"  
         },  

         "Basic: Color Base Border": {  
             "prefix": "elcbb",  
             "body": ["#DCDFE6"],  
             "description": "Element UI Color Base Border"  
         },  

         "Basic: Color Light Border": {  
             "prefix": "elclb",  
             "body": ["#E4E7ED"],  
             "description": "Element UI Color Light Border"  
         },  

         "Basic: Color Lighter Border": {  
             "prefix": "elclrb",  
             "body": ["#EBEEF5"],  
             "description": "Element UI Color Lighter Border"  
         },  

         "Basic: Color Extra Light Border": {  
             "prefix": "elelb",  
             "body": ["#DCDFE6"],  
             "description": "Element UI Color Extra Light Border"  
         },  

         "Basic: Typography": {  
             "prefix": "eltypo",  
             "body": ["font-family: \"Helvetica Neue\",Helvetica,\"PingFang SC\",\"Hiragino Sans GB\",\"Microsoft YaHei\",\"微软雅黑\",Arial,sans-serif;"],  
             "description": "Element UI Font-family"  
         },  

         "Basic: Border Basic Shadow": {  
             "prefix": "elbbs",  
             "body": ["box-shadow: 0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .04);"],  
             "description": "Element UI Border Basic Shadow"  
         },  

         "Basic: Border Light Shadow": {  
             "prefix": "elbls",  
             "body": ["box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);"],  
             "description": "Element UI Border Light Shadow"  
         },  

         "Basic: Button": {  
             "prefix": "elb",  
             "body": [  
                 "<el-button type=\"${1|primary,text,info,success,warning,danger|}\" size=\"${2|default,medium,small,mini|}\" @click=\"$3\">${4}</el-button>",  
                 "${5}"  
             ],  
             "description": "Element UI <el-button>"  
         },  

         "Basic: Button Group": {  
             "prefix": "elbg",  
             "body": [  
                 "<el-button-group>",  
                     "\t<el-button type=\"${1|primary,text,info,success,warning,danger|}\" size=\"${2|default,medium,small,mini|}\" @click=\"$3\">${4}</el-button>",  
                     "\t<el-button type=\"${5|primary,text,info,success,warning,danger|}\" size=\"${2|default,medium,small,mini|}\" @click=\"$6\">${7}</el-button>",  
                 "</el-button-group>",  
                 "${8}"  
             ],  
             "description": "Element UI <el-button-group>"  
         },  

         "Basic: Link": {  
             "prefix": "ell",  
             "body": [  
                 "<el-link type=\"${1|primary,success,warning,danger,info|}\" :underline=\"${2:false}\" href=\"${3}\" target=\"${4:_blank}\">${5}</el-link>",  
                 "${6}"  
             ],  
             "description": "Element UI <el-button>"  
         },  

         "Form: Radio": {  
             "prefix": "elr",  
             "body": [  
                 "<el-radio v-model=\"${1}\" label=\"${2}\" @change=\"${3}\">${4}</el-radio>",  
                 "${5}"  
             ],  
             "description": "Element UI <el-radio>"  
         },  

         "Form: Radio Group": {  
             "prefix": "elrg",  
             "body": [  
                 "<el-radio-group v-model=\"$1\" @change=\"$2\">",  
                     "\t<el-radio v-for=\"${3:item} in ${4:items}\" :key=\"${3:item}.${5:key}\" :label=\"${3:item}.${6:label}\">",  
                         "\t\t{{${3:item}.${7:title}}}",  
                     "\t</el-radio>",  
                 "</el-radio-group>",  
                 "${8}"  
             ],  
             "description": "Element UI <el-radio-group> with <el-radio>"  
         },  

         "Form: Radio Button Group": {  
             "prefix": "elrbg",  
             "body": [  
                 "<el-radio-group v-model=\"$1\" size=\"${2|normal,medium,small,mini|}\" @change=\"$3\">",  
                     "\t<el-radio-button v-for=\"${4:item} in ${5:items}\" :key=\"${4:item}.${6:key}\" :label=\"${4:item}.${7:label}\">",  
                         "\t\t{{${4:item}.${8:title}}}",  
                     "\t</el-radio-button>",  
                 "</el-radio-group>",  
                 "${9}"  
             ],  
             "description": "Element UI <el-radio-group> with <el-radio-button>"  
         },  

         "Form: Radio Button": {  
             "prefix": "elrb",  
             "body": [  
                 "<el-radio-button v-model=\"${1}\" label=\"${2}\">${3}</el-radio-button>",  
                 "${4}"  
             ],  
             "description": "Element UI <el-radio>"  
         },  

         "Form: Checkbox": {  
             "prefix": "elc",  
             "body": [  
                 "<el-checkbox v-model=\"${1}\" label=\"${2}\" :indeterminate=\"${3:false}\" @change=\"${4}\">{{$5}}</el-checkbox>",  
                 "${6}"  
             ],  
             "description": "Element UI <el-checkbox>"  
         },  

         "Form: Checkbox Group": {  
             "prefix": "elcg",  
             "body": [  
                 "<el-checkbox-group v-model=\"$1\" @change=\"${2}\">",  
                     "\t<el-checkbox v-for=\"${3:item} in ${4:items}\" :key=\"${3:item}.${5:key}\" :label=\"${3:item}.${6:label}\">",  
                         "\t\t{{${3:item}.${7:label}}}",  
                     "\t</el-checkbox>",  
                 "</el-checkbox-group>",  
                 "${8}"  
             ],  
             "description": "Element UI <el-checkbox-group> with <el-checkbox>"  
         },  

         "Form: Checkbox Button Group": {  
             "prefix": "elcbg",  
             "body": [  
                 "<el-checkbox-group v-model=\"$1\" size=\"${2|normal,medium,small,mini|}\"  @change=\"${3}\">",  
                     "\t<el-checkbox-button v-for=\"${4:item} in ${5:items}\" :key=\"${4:item}.${6:key}\" :label=\"${4:item}.${7:label}\">",  
                         "\t\t{{${4:item}.${8:label}}}",  
                     "\t</el-checkbox-button>",  
                 "</el-checkbox-group>",  
                 "${9}"  
             ],  
             "description": "Element UI <el-checkbox-group> with <el-checkbox-button>"  
         },  

         "Form: Checkbox Button": {  
             "prefix": "elcbt",  
             "body": [  
                 "<el-checkbox-button v-model=\"${1}\" label=\"${2}\" :indeterminate=\"${3:false}\" @change=\"${4}\">{{$5}}</el-checkbox-button>",  
                 "${6}"  
             ],  
             "description": "Element UI <el-checkbox-button>"  
         },  

         "Form: Input": {  
             "prefix": "eli",  
             "body": [  
                 "<el-input v-model=\"$1\" placeholder=\"$2\" size=\"${3|normal,medium,small,mini|}\" clearable @change=\"$4\">$5</el-input>",  
                 "${6}"  
             ],  
             "description": "Element UI <el-input>"  
         },  

         "Form: Textarea": {  
             "prefix": "elit",  
             "body": [  
                 "<el-input type=\"${1|text,textarea|}\" :rows=\"${2:2}\" v-model=\"$3\" placeholder=\"$4\" ",  
                     "\t:maxlength=\"${5:-1}\" :show-word-limit=\"${6|false,true|}\" :autosize=\"{ minRows: ${7:2}, maxRows: ${8:4} }\">",  
                 "</el-input>",  
                 "${9}"  
             ],  
             "description": "Element UI <el-input type=\"text,textarea\">"  
         },  

         "Form: Autocomplete": {  
             "prefix": "ela",  
             "body": [  
                 "<el-autocomplete v-model=\"$1\" value-key=\"$2\" placeholder=\"${3}\" clearable",  
                     "\t:debounce=\"$4\" :fetch-suggestions=\"${5}\"  @select=\"$6\">$7</el-autocomplete>",  
                 "${8}"  
             ],  
             "description": "Element UI <el-autocomplete>"  
         },  

         "Form: Input Slot": {  
             "prefix": "elis",  
             "body": [  
                 "<template slot=\"${1|prefix,suffix,prepend,append|}\">$2</template>",  
                 "${3}"  
             ],  
             "description": "Element UI <template slot=''>"  
         },  

         "Form: InputNumber": {  
             "prefix": "elin",  
             "body": [  
                 "<el-input-number v-model=\"$1\" size=\"${2|normal,medium,small,mini|}\" label=\"$3\"",  
                     "\t:min=\"${4:1}\" :max=\"${5:10}\" :step=\"${6:1}\" :controls=\"${7|true,false|}\" controls-position=\"${8|both,right|}\" @change=\"$9\">",  
                 "</el-input-number>",  
                 "${10}"  
             ],  
             "description": "Element UI <el-input-number>"  
         },  

         "Form: Select": {  
             "prefix": "elsel",  
             "body": [  
                 "<el-select v-model=\"$1\" value-key=\"$2\" placeholder=\"$3\" clearable filterable @change=\"$4\">",  
                     "\t<el-option v-for=\"${5:item} in ${6:options}\"",  
                         "\t\t:key=\"${5:item}.${7:value}\"",  
                         "\t\t:label=\"${5:item}.${8:label}\"",  
                         "\t\t:value=\"${5:item}.${9:value}\">",  
                     "\t</el-option>",  
                 "</el-select>",  
                 "${10}"  
             ],  
             "description": "Element UI <el-select>"  
         },  

         "Form: Select Remote Search": {  
             "prefix": "elselr",  
             "body": [  
                 "<el-select v-model=\"$1\" value-key=\"$2\" placeholder=\"$3\" clearable filterable",  
                     "\tremote reserve-keyword :remote-method=\"$4\" :loading=\"$5\" @change=\"$6\">",  
                     "\t<el-option v-for=\"${7:item} in ${8:options}\"",  
                         "\t\t:key=\"${7:item}.${9:value}\"",  
                         "\t\t:label=\"${7:item}.${10:label}\"",  
                         "\t\t:value=\"${7:item}.${11:value}\">",  
                     "\t</el-option>",  
                 "</el-select>",  
                 "${12}"  
             ],  
             "description": "Element UI <el-select>"  
         },  

         "Form: Select Option": {  
             "prefix": "elop",  
             "body": [  
                 "<el-option :key=\"$1\" :label=\"$2\" :value=\"$3\"></el-option>",  
                 "${3}"  
             ],  
             "description": "Element UI <el-option>"  
         },  

         "Form: Select Option Group": {  
             "prefix": "elopg",  
             "body": [  
                 "<el-option-group v-for=\"${1:group} in ${2:options}\"",  
                     "\t:key=\"${1:group}.${3:value}\"",  
                     "\t:label=\"${1:group}.${4:label}\">",  
                     "\t<el-option v-for=\"${5:item} in ${1:group}.${6:options}\"",  
                         "\t\t:key=\"${5:item}.${7:value}\"",  
                         "\t\t:label=\"${5:item}.${8:label}\"",  
                         "\t\t:value=\"${5:item}.${9:value}\">",  
                     "\t</el-option>",  
                 "<el-option-group>",  
                 "${10}"  
             ],  
             "description": "Element UI <el-option-group>"  
         },  

         "Form: Cascader": {  
             "prefix": "elca",  
             "body": [  
                 "<el-cascader :options=\"${1:options}\" v-model=\"${2}\" clearable filterable :show-all-levels=\"${3|false,true|}\"",  
                     "\t:props=\"{ expandTrigger: ${4|'hover','click'|}, multiple: ${5|true,false|}, checkStrictly: ${6|true,false|} }\" @change=\"${7}\">",  
                 "</el-cascader>",  
                 "${8}"  
             ],  
             "description": "Element UI <el-cascader>"  
         },  

         "Form: Cascader Panel": {  
             "prefix": "elcap",  
             "body": [  
                 "<el-cascader :options=\"${1:options}\" v-model=\"${2}\" @change=\"${3}\"",  
                     "\t:props=\"{ expandTrigger: ${4|'hover','click'|}, multiple: ${5|true,false|}, checkStrictly: ${6|true,false|} }\">",  
                 "</el-cascader>",  
                 "${7}"  
             ],  
             "description": "Element UI <el-cascader-panel>"  
         },  

         "Form: Switch": {  
             "prefix": "elsw",  
             "body": [  
                 "<el-switch v-model=\"$1\" :active-value=\"${2:true}\" :inactive-value=\"${3:false}\" @change=\"$4\">",  
                 "</el-switch>",  
                 "${5}"  
             ],  
             "description": "Element UI <el-switch>"  
         },  

         "Form: Slider": {  
             "prefix": "elsl",  
             "body": [  
                 "<el-slider v-model=\"$1\" :min=\"$2\" :max=\"$3\" :step=\"$4\" vertical=\"${5:false}\" @change=\"$6\">",  
                 "</el-slider>",  
                 "${7}"  
             ],  
             "description": "Element UI <el-slider>"  
         },  

         "Form: Time Select": {  
             "prefix": "elts",  
             "body": [  
                 "<el-time-select v-model=\"$1\" size=\"${2|normal,medium,small,mini|}\" placeholder=\"$3\"",  
                     "\t:picker-options=\"{",  
                         "\t\tstart: '${4}',",  
                         "\t\tstep: '${5:00:30}',",  
                         "\t\tend: '${6}',",  
                     "\t}\"",  
                     "\tchange=\"${7}\">",  
                 "</el-time-select>",  
                 "${8}"  
             ],  
             "description": "Element UI <el-time-select>"  
         },  

         "Form: Time Select Range": {  
             "prefix": "eltsr",  
             "body": [  
                 "<el-time-select v-model=\"$1\" size=\"${2|normal,medium,small,mini|}\" placeholder=\"$3\"",  
                     "\t:picker-options=\"{",  
                         "\t\tstart: '${4}',",  
                         "\t\tstep: '${5:00:30}',",  
                         "\t\tend: '${6}',",  
                     "\t}\">",  
                 "</el-time-select>",  
                 "<el-time-select v-model=\"$7\" size=\"${2|normal,medium,small,mini|}\" placeholder=\"$8\"",  
                     "\t:picker-options=\"{",  
                         "\t\tstart: '${4}',",  
                         "\t\tstep: '${5:00:30}',",  
                         "\t\tend: '${6}',",  
                         "\t\tminTime: $1",  
                     "\t}\">",  
                 "</el-time-select>",  
                 "${9}"  
             ],  
             "description": "Element UI <el-time-select> range"  
         },  

         "Form: TimePicker": {  
             "prefix": "eltp",  
             "body": [  
                 "<el-time-picker v-model=\"$1\" size=\"${2|normal,medium,small,mini|}\" arrow-control",  
                     "\t:picker-options=\"{",  
                         "\t\tselectableRange: '${3:18:30:00} - ${4:20:30:00}'",  
                     "\t}\"",  
                     "\tplaceholder=\"${5:任意时间点}\">",  
                 "</el-time-picker>",  
                 "${6}"  
             ],  
             "description": "Element UI <el-time-picker>"  
         },  

         "Form: TimePicker Range": {  
             "prefix": "eltpr",  
             "body": [  
                 "<el-time-picker v-model=\"$1\" size=\"${2|normal,medium,small,mini|}\" arrow-control",  
                     "\tis-range range-separator=\"${3:-}\" start-placeholder=\"$4\" end-placeholder=\"$5\"",  
                     "\t:picker-options=\"{",  
                         "\t\tselectableRange: '${6:18:30:00} - ${7:20:30:00}'",  
                     "\t}\">",  
                 "</el-time-picker>",  
                 "${8}"  
             ],  
             "description": "Element UI <el-time-picker is-range>"  
         },  

         "Form: DatePicker": {  
             "prefix": "eldp",  
             "body": [  
                 "<el-date-picker v-model=\"$1\" type=\"${2|year,month,date,dates,week|}\" size=\"${3|normal,medium,small,mini|}\" placeholder=\"${4:选择日期时间}\">",  
                 "</el-date-picker>",  
                 "${5}"  
             ],  
             "description": "Element UI <el-date-picker>"  
         },  

         "Form: DatePicker Range": {  
             "prefix": "eldpr",  
             "body": [  
                 "<el-date-picker v-model=\"$1\" type=\"${2|daterange,monthrange|}\" size=\"${3|normal,medium,small,mini|}\"",  
                     "\trange-separator=\"${4:-}\" start-placeholder=\"$5\" end-placeholder=\"$6\">",  
                 "</el-date-picker>",  
                 "${7}"  
             ],  
             "description": "Element UI <el-date-picker>"  
         },  

         "Form: DateTimePicker": {  
             "prefix": "eldtp",  
             "body": [  
                 "<el-date-picker v-model=\"$1\" type=\"datetime\" size=\"${2|normal,medium,small,mini|}\" placeholder=\"${3:选择日期时间}\">",  
                 "</el-date-picker>",  
                 "${4}"  
             ],  
             "description": "Element UI <el-date-picker type=\"datetime\">"  
         },  

         "Form: DateTimePicker Range": {  
             "prefix": "eldtpr",  
             "body": [  
                 "<el-date-picker v-model=\"$1\" type=\"datetimerange\" size=\"${2|normal,medium,small,mini|}\"",  
                     "\trange-separator=\"${3:-}\" start-placeholder=\"$4\" end-placeholder=\"$5\">",  
                 "</el-date-picker>",  
                 "${6}"  
             ],  
             "description": "Element UI <el-date-picker type=\"datetime\">"  
         },  

         "Form: Upload": {  
             "prefix": "elu",  
             "body": [  
                 "<el-upload",  
                     "\taction=\"$1\"",  
                     "\tref=\"${2:upload}\"",  
                     "\t:on-remove=\"$3\"",  
                     "\t:auto-upload=\"false\"",  
                     "\tmultiple",  
                     "\t:limit=\"${4:5}\"",  
                     "\t:on-exceed=\"$5\"",  
                     "\t:file-list=\"$6\">",  
                     "\t<el-button slot=\"trigger\" size=\"small\" type=\"primary\">${7:select file}</el-button>",  
                     "\t<el-button style=\"margin-left: 10px;\" size=\"small\" type=\"success\" @click=\"$8\">${9:upload to server}</el-button>",  
                     "\t<div slot=\"tip\" class=\"el-upload__tip\">${10:jpg/png files with a size less than 500kb}</div>",  
                 "</el-upload>",  
                 "${11}"  
             ],  
             "description": "Element UI <el-upload>"  
         },  

         "Form: Rate": {  
             "prefix": "elra",  
             "body": [  
                 "<el-rate v-model=\"$1\" :allow-half=\"${2|false,true|}\" @change=\"$3\"></el-rate>",  
                 "${4}"  
             ],  
             "description": "Element UI <el-rate>"  
         },  

         "Form: ColorPicker": {  
             "prefix": "elcp",  
             "body": [  
                 "<el-color-picker v-model=\"$1\" size=\"${2|normal,medium,small,mini|}\" :show-alpha=\"${3|true,false|}\" ></el-color-picker>",  
                 "${4}"  
             ],  
             "description": "Element UI <el-color-picker>"  
         },  

         "Form: Transfer": {  
             "prefix": "eltr",  
             "body": [  
                 "<el-transfer v-model=\"$1\" :data=\"$2\" target-order=\"${3|original,push,unshift|}\" filterable @change=\"$4\"",  
                     "\t:format=\"{noChecked: '\\${total}',hasChecked: '\\${checked}/\\${total}'}\">",  
                 "</el-transfer>",  
                 "${5}"  
             ],  
             "description": "Element UI <el-transfer>"  
         },  

         "Form: Form": {  
             "prefix": "elf",  
             "body": [  
                 "<el-form :model=\"${1:form}\" ref=\"${2:form}\" :rules=\"${3:rules}\" label-width=\"80px\" :inline=\"${4|false,true|}\" size=\"${5|normal,medium,small,mini|}\">",  
                     "\t<el-form-item label=\"$6\">",  
                         "\t\t<el-input v-model=\"${1:form}.${7}\"></el-input>",  
                     "\t</el-form-item>",  
                     "\t<el-form-item>",  
                         "\t\t<el-button type=\"primary\" @click=\"onSubmit\">${8:立即创建}</el-button>",  
                         "\t\t<el-button>${9:取消}</el-button>",  
                     "\t</el-form-item>",  
                 "</el-form>",  
                 "${10}"  
             ],  
             "description": "Element UI <el-form>"  
         },  

         "Form: Form Item": {  
             "prefix": "elfi",  
             "body": [  
                 "<el-form-item label=\"$1\" size=\"${2|normal,medium,small,mini|}\">",  
                     "\t$3",  
                 "</el-form-item>",  
                 "${4}"  
             ],  
             "description": "Element UI <el-form-item>"  
         },  

         "Data: Table": {  
             "prefix": "elt",  
             "body": [  
                 "<el-table :data=\"$1\" border stripe>",  
                     "\t<el-table-column v-for=\"${2:col} in ${3:columns}\"",  
                         "\t\t:prop=\"${2:col}.${4:id}\"",  
                         "\t\t:key=\"${2:col}.${4:id}\"",  
                         "\t\t:label=\"${2:col}.${5:label}\"",  
                         "\t\t:width=\"${2:col}.${6:width}\">",  
                     "\t</el-table-column>",  
                 "</el-table>",  
                 "${7}"  
             ],  
             "description": "Element UI <el-table>"  
         },  

         "Data: Table Column": {  
             "prefix": "eltc",  
             "body": [  
                 "<el-table-column :label=\"${1}\" :min-width=\"${2}\" :prop=\"${3}\" </el-table-column>",  
                 "${0}"  
             ],  
             "description": "Element UI <el-table-column>"  
         },  

         "Data: Tag": {  
             "prefix": "elta",  
             "body": [  
                 "<el-tag type=\"${1|danger,info,success,warning|}\" size=\"${2|normal,medium,small,mini|}\"  effect=\"${3|dark,plain|}\" closable @close=\"${4}\">$5</el-tag>",  
                 "${6}"  
             ],  
             "description": "Element UI <el-tag>"  
         },  

         "Data: Progress": {  
             "prefix": "elpr",  
             "body": [  
                 "<el-progress type=\"${1|line,circle,dashboard|}\" :percentage=\"$2\" status=\"${3|success,exception,warning|}\" :stroke-width=\"${4:6}\"></el-progress>",  
                 "${5}"  
             ],  
             "description": "Element UI <el-progress>"  
         },  

         "Data: Tree": {  
             "prefix": "eltree",  
             "body": [  
                 "<el-tree ref=\"${1:tree}\" :data=\"$2\" node-key=\"$3\" :props=\"$4\" empty-text=\"$5\" show-checkbox=\"${6|false,true|}\" highlight-current=\"${7|true,false|}\" @node-click=\"$8\">$9</el-tree>",  
                 "${10}"  
             ],  
             "description": "Element UI <el-tree>"  
         },  

         "Data: Pagination": {  
             "prefix": "elp",  
             "body": [  
                 "<el-pagination",  
                     "\t@size-change=\"${1:sizeChange}\"",  
                     "\t@current-change=\"${2:currentChange}\"",  
                     "\t:current-page.sync=\"${3:currentPage}\"",  
                     "\t:page-sizes=\"${4:[20, 40, 80, 100]}\"",  
                     "\t:page-size=\"${5:pageSize}\"",  
                     "\tlayout=\"total, sizes, prev, pager, next, jumper\"",  
                     "\t:total=\"${6:totalNum}\" background>",  
                     "\t:pager-count=\"${7:7}\">",  
                 "</el-pagination>",  
                 "${8}"  
             ],  
             "description": "Element UI <el-pagination>"  
         },  

         "Data: Badge": {  
             "prefix": "elba",  
             "body": [  
                 "<el-badge :value=\"${1}\" :max=\"${2:99}\" :is-dot=\"${3|false,true|}\" :hidden=\"${4|false,true|}\" type=\"${5|primary,success,warning,danger,info|}\">",  
                     "\t<el-button size=\"small\">$6</el-button>",  
                 "</el-badge>",  
                 "${7}"  
             ],  
             "description": "Element UI <el-badge>"  
         },  

         "Data: Avatar": {  
             "prefix": "elav",  
             "body": [  
                 "<el-avatar icon=\"el-icon-user-solid\" size=\"${1|large,medium,small|}\" shape=\"${2|circle,square|}\" :src=\"${3}\" fit=\"${4|fill,contain,cover,none,scale-down|}\"></el-avatar>",  
                 "${5}"  
             ],  
             "description": "Element UI <el-avatar>"  
         },  

         "Notice: Alert": {  
             "prefix": "elal",  
             "body": [  
                 "<el-alert :title=\"$1\" type=\"${2|info,success,warning,error|}\" effect=\"${3|light,dark|}\" show-icon closable></el-alert>",  
                 "${4}"  
             ],  
             "description": "Element UI <el-alert>"  
         },  

         "Notice: Loading": {  
             "prefix": "elloads",  
             "body": [  
                 "element-loading-text=\"${1:拼命加载中}\"",  
                 "element-loading-spinner=\"${2:el-icon-loading}\"",  
                 "element-loading-background=\"${3:rgba(0, 0, 0, 0.8)}\"",  
                 "${4}"  
             ],  
             "description": "Element UI loading options"  
         },  

         "Notice: Message": {  
             "prefix": "elme",  
             "body": [  
                 "this.\\$message({",  
                     "\tmessage: '$1',",  
                     "\ttype: '${2|info,success,warning,error|}',",  
                     "\tshowClose: ${3:true},",  
                     "\tduration: ${4:3000},",  
                 "});",  
                 "${5}"  
             ],  
             "description": "Element UI $message"  
         },  

         "Notice: Messagebox": {  
             "prefix": "elmebox",  
             "body": [  
                 "this.\\$msgbox({",  
                     "\ttitle: '$1',",  
                     "\tmessage: '${2}',",  
                     "\tshowCancelButton: true,",  
                     "\tconfirmButtonText: '${3:OK}',",  
                     "\tcancelButtonText: '${4:Cancel}',",  
                     "\tcenter: ${5:false},",  
                     "\tbeforeClose: (action, instance, done) => {",  
                         "\t\t${6}",  
                     "\t}",  
                 "}).then(action => {",  
                     "\t${7}",  
                 "}).catch(() => {",  
                     "\t${8}",  
                 "});",  
                 "${9}"  
             ],  
             "description": "Element UI $msgbox"  
         },  

         "Notice: Messagebox Alert": {  
             "prefix": "elmeal",  
             "body": [  
                 "this.\\$alert('${1:content}', '${2:title}', {",  
                     "\tconfirmButtonText: '${3:OK}',",  
                     "\tcallback: action => {",  
                         "\t\t${4}",  
                     "\t}",  
                 "})",  
                 "${5}"  
             ],  
             "description": "Element UI $alert"  
         },  

         "Notice: Messagebox Confirm": {  
             "prefix": "elmecon",  
             "body": [  
                 "this.\\$confirm('${1:content}', '${2:title}', {",  
                     "\tconfirmButtonText: '${3:OK}',",  
                     "\tcancelButtonText: '${4:Cancel}',",  
                     "\ttype: '${5|success,info,warning,erro|}',",  
                 "}).then(action => {",  
                     "\t${6}",  
                 "}).catch(() => {",  
                     "\t${7}",  
                 "});",  
                 "${8}"  
             ],  
             "description": "Element UI $confirm"  
         },  

         "Notice: Messagebox Prompt": {  
             "prefix": "elmepro",  
             "body": [  
                 "this.\\$prompt('${1:content}', '${2:title}', {",  
                     "\tconfirmButtonText: '${3:OK}',",  
                     "\tcancelButtonText: '${4:Cancel}',",  
                     "\tinputPattern: / ${5} /,",  
                     "\tinputErrorMessage: '${6}',",  
                 "}).then(({ value }) => {",  
                     "\t${7}",  
                 "}).catch(() => {",  
                     "\t${8}",  
                 "});",  
                 "${9}"  
             ],  
             "description": "Element UI $prompt"  
         },  

         "Notice: Notification": {  
             "prefix": "elno",  
             "body": [  
                 "this.\\$notify({",  
                     "\ttitle: '${1:title}',",  
                     "\tmessage: '${2:message}',",  
                     "\ttype: '${3|info,success,warning,error|}',",  
                     "\tduration: '${4|4500, 0|}',",  
                     "\tposition: '${5|top-right,top-left,bottom-right,bottom-left|}',",  
                     "\tshowClose: '${6:true}',",  
                 "});",  
                 "${7}"  
             ],  
             "description": "Element UI $notify"  
         },  

         "Notice: Notification with type": {  
             "prefix": "elnot",  
             "body": [  
                 "this.\\$notify.${1|info,success,warning,error|}({",  
                     "\ttitle: '${2:title}',",  
                     "\tmessage: '${3:message}',",  
                     "\tduration: '${4|4500, 0|}',",  
                     "\tposition: '${5|top-right,top-left,bottom-right,bottom-left|}',",  
                     "\tshowClose: '${6:true}',",  
                 "});",  
                 "${7}"  
             ],  
             "description": "Element UI $notify.type"  
         },  

         "Navigation: NavMenu Menu": {  
             "prefix": "elmen",  
             "body": [  
                 "<el-menu mode=\"${1|horizontal,vertical|}\" default-active=\"$2\" @select=\"$3\">",  
                     "\t<el-submenu v-for=\"(${4:submenus}, ${5:index}) in ${6:menus}\"",  
                         "\t\t:index=\"${5:index} + 1\"",  
                         "\t\t:key=\"${4:submenus}.${7:key}\">",  
                         "\t\t<template slot=\"title\">{{${4:submenus}.${8:title}}}</template>",  
                         "\t\t<el-menu-item v-for=\"(${9:item}, ${10:subIndex}) in ${4:submenus}.${11:menus}\"",  
                             "\t\t\t:index=\"(${5:index} + 1) + '-' + (${10:subIndex} + 1)\"",  
                             "\t\t\t:key=\"${9:item}.${12:key}\">",  
                                 "\t\t\t\t{{${9:item}.${13:title}}}",  
                         "\t\t</el-menu-item>",  
                     "\t</el-submenu>",  
                 "</el-menu>",  
                 "${14}"  
             ],  
             "description": "Element UI <el-menu> with <el-submenu> and <el-menu-item>"  
         },  

         "Navigation: NavMenu subMenu": {  
             "prefix": "elsubmen",  
             "body": [  
                 "<el-submenu :index=\"$1\">",  
                     "\t<template slot=\"title\">$2</template>",  
                     "\t<el-menu-item v-for=\"(${3:item}, ${4:subIndex}) in $5\"",  
                         "\t\t:index=\"${4:subIndex} + 1\"",  
                         "\t\t:key=\"${3:item}.${6:key}\">",  
                             "\t\t\t{{${3:item}.${7:title}}}",  
                     "\t</el-menu-item>",  
                 "</el-submenu>",  
                 "${8}"  
             ],  
             "description": "Element UI <el-submenu> with <el-menu-item>"  
         },  

         "Navigation: NavMenu Menu Item": {  
             "prefix": "elmeni",  
             "body": [  
                 "<el-menu-item index=\"$1\" key=\"$2\">$3</el-menu-item>",  
                 "${4}"  
             ],  
             "description": "Element UI <el-menu-item>"  
         },  

         "Navigation: Tabs": {  
             "prefix": "eltabs",  
             "body": [  
                 "<el-tabs v-model=\"$1\" type=\"${2|card,border-card,normal|}\" tab-position=\"${3|top,left,right,bottom|}\" @tab-click=\"$4\">",  
                     "\t<el-tab-pane v-for=\"${5:item} in ${6:panes}\"",  
                         "\t\t:key=\"${5:item}.${7:key}\"",  
                         "\t\t:label=\"${5:item}.${8:label}\"",  
                         "\t\t:name=\"${5:item}.${7:key}\">",  
                         "\t\t$9",  
                     "\t</el-tab-pane>",  
                 "</el-tabs>",  
                 "${10}"  
             ],  
             "description": "Element UI <el-tabs> with <el-tab-pane>"  
         },  

         "Navigation: Tabs tab pane": {  
             "prefix": "eltabp",  
             "body": [  
                 "<el-tab-pane :label=\"$1\" :name=\"$2\">",  
                     "\t$3",  
                 "</el-tab-pane>",  
                 "${4}"  
             ],  
             "description": "Element UI <el-tab-pane>"  
         },  

         "Navigation: Breadcrumb": {  
             "prefix": "elbr",  
             "body": [  
                 "<el-breadcrumb separator-class=\"${1:el-icon-arrow-right}\">",  
                     "\t<el-breadcrumb-item :to=\"{ path: '$2', name: '$3' }\">$4</el-breadcrumb-item>",  
                     "\t<el-breadcrumb-item :to=\"{ path: '$5', name: '$6' }\">$7</el-breadcrumb-item>",  
                 "</el-breadcrumb>",  
                 "${8}"  
             ],  
             "description": "Element UI <el-breadcrumb>"  
         },  

         "Navigation: Breadcrumb Item": {  
             "prefix": "elbri",  
             "body": [  
                 "<el-breadcrumb-item :to=\"{ path: '$1', name: '$2' }\">$3</el-breadcrumb-item>",  
                 "${4}"  
             ],  
             "description": "Element UI <el-breadcrumb-item>"  
         },  

         "Navigation: PageHeader": {  
             "prefix": "elpa",  
             "body": [  
                 "<el-page-header @back=\"$1\" content=\"$2\"></el-page-header>",  
                 "${3}"  
             ],  
             "description": "Element UI <el-page-header>"  
         },  

         "Navigation: Dropdown": {  
             "prefix": "eldr",  
             "body": [  
                 "<el-dropdown trigger=\"${1:click}\" size=\"${2|default,medium,small,mini|}\" split-button type=\"${3|primary,success,warning,danger,info,text|}\" @command=\"$4\">",  
                     "\t${5:title}",  
                     "\t<el-dropdown-menu slot=\"dropdown\">",  
                         "\t\t<el-dropdown-item v-for=\"${6:item} in ${7:items}\"",  
                             "\t\t\t:key=\"${6:item}.${8:key}\" :command=\"${6:item}.${9:command}\">",  
                             "\t\t\t{{${6:item}.${10:title}}}",  
                         "\t\t</el-dropdown-item>",  
                     "\t</el-dropdown-menu>",  
                 "</el-dropdown>",  
                 "${11}"  
             ],  
             "description": "Element UI <el-dropdown> with <el-dropdown-item>"  
         },  

         "Navigation: Dropdown Item": {  
             "prefix": "eldri",  
             "body": [  
                 "<el-dropdown-item :command=\"$1\">$2</el-dropdown-item>",  
                 "${3}"  
             ],  
             "description": "Element UI <el-dropdown-item>"  
         },  

         "Navigation: Steps": {  
             "prefix": "elsts",  
             "body": [  
                 "<el-steps :active=\"$1\" direction=\"${2|horizontal,vertical|}\" process-status=\"${3|wait,process,finish,error,success|}\" finish-status=\"${4|wait,process,finish,error,success|}\">",  
                     "\t<el-step v-for=\"${5:item} in ${6:items}\"",  
                         "\t\t:key=\"${5:item}.${7:key}\"",  
                         "\t\t:title=\"${5:item}.${8:title}\"",  
                         "\t\t:description=\"${5:item}.${9:description}\"",  
                         "\t\t:icon=\"${5:item}.${10:icon}\">",  
                     "\t</el-step>",  
                 "</el-steps>",  
                 "${11}"  
             ],  
             "description": "Element UI <el-steps> with <el-step>"  
         },  

         "Navigation: Steps Step": {  
             "prefix": "elst",  
             "body": [  
                 "<el-step :title=\"$1\" :description=\"$2\" :icon=\"$3\"></el-step>",  
                 "${4}"  
             ],  
             "description": "Element UI <el-step>"  
         },  

         "Others: Dialog": {  
             "prefix": "eldi",  
             "body": [  
                 "<el-dialog title=\"$1\" :visible.sync=\"$2\" width=\"${3:30%}\" @close=\"$4\">",  
                     "\t<span>$5</span>",  
                     "\t<span slot=\"footer\">",  
                         "\t\t<el-button @click=\"$2 = false\">Cancel</el-button>",  
                         "\t\t<el-button type=\"primary\" @click=\"$6\">OK</el-button>",  
                     "\t</span>",  
                 "</el-dialog>",  
                 "${7}"  
             ],  
             "description": "Element UI <el-dialog>"  
         },  

         "Others: Tooltip": {  
             "prefix": "elto",  
             "body": [  
                 "<el-tooltip content=\"$1\" placement=\"${2|top,top-start,top-end,bottom,bottom-start,bottom-end,left,left-start,left-end,right,right-start,right-end|}\" effect=\"${3|dark,light|}\">",  
                     "\t${4:<!-- content to trigger tooltip here -->}",  
                 "</el-tooltip>",  
                 "${5}"  
             ],  
             "description": "Element UI <el-tooltip>"  
         },  

         "Others: Popover": {  
             "prefix": "elpo",  
             "body": [  
                 "<el-popover",  
                     "\t:ref=\"$1\"",  
                     "\tplacement=\"${2|top,top-start,top-end,bottom,bottom-start,bottom-end,left,left-start,left-end,right,right-start,right-end|}\"",  
                     "\ttitle=\"$3\"",  
                     "\twidth=\"$4\"",  
                     "\ttrigger=\"${5|click,focus,hover,manual|}\"",  
                     "\tcontent=\"$6\">",  
                     "\t${7: <!-- <el-button slot=\"reference\">content</el-button> -->}",  
                 "</el-popover>",  
                 "${8}"  
             ],  
             "description": "Element UI <el-popover>"  
         },  

         "Others: Popconfirm": {  
             "prefix": "elpoco",  
             "body": [  
                 "<el-popconfirm",  
                     "\ttitle=\"$1\"",  
                     "\tconfirmButtonText=\"$2\"",  
                     "\tcancelButtonText=\"$3\"",  
                     "\tconfirmButtonType=\"${4|primary,text,info,success,warning,danger|}\"",  
                     "\tcancelButtonType=\"${5|text,primary,info,success,warning,danger|}\"",  
                     "\ticon=\"${6:el-icon-question}\"",  
                     "\ticonColor=\"${7:#f90}\"",  
                     "\thideIcon=\"${8|false,true|}\">",  
                     "\t<el-button slot=\"reference\">$9</el-button>",  
                 "</el-popconfirm>",  
                 "${10}"  
             ],  
             "description": "Element UI <el-popconfirm>"  
         },  

         "Others: Card": {  
             "prefix": "elcard",  
             "body": [  
                 "<el-card shadow=\"${1|always,hover,never|}\" :body-style=\"${2:{ padding: '20px' }}\">",  
                     "\t<div slot=\"header\">",  
                         "\t\t<span>${3:<!-- card title -->}</span>",  
                     "\t</div>",  
                     "\t${4:<!-- card body -->}",  
                 "</el-card>",  
                 "${5}"  
             ],  
             "description": "Element UI <el-card>"  
         },  

         "Others: Carousel": {  
             "prefix": "elcaro",  
             "body": [  
                 "<el-carousel height=\"${1:150px}\" type=\"${2|default,card|}\" direction=\"${3|horizontal,vertical|}\"",  
                     "\t:initial-index=\"${4:0}\" :autoplay=\"${5|true, false|}\" :interval=\"${6:3000}\" :loop=\"${7|true,false|}\"",  
                     "\ttrigger=\"${8|hover,click|}\" indicator-position=\"${9|outside,inside,none|}\" arrow=\"${10|hover,always,never|}\">",  
                     "\t<el-carousel-item v-for=\"${11:item} in ${12:items}\" :key=\"${11:item}.${13:key}\" :label=\"${14}\">",  
                         "\t\t${15:<!-- content -->}",  
                     "\t</el-carousel-item>",  
                 "</el-carousel>",  
                 "${16}"  
             ],  
             "description": "Element UI <el-carousel> with <el-carousel-item>"  
         },  

         "Others: Carousel Item": {  
             "prefix": "elcaroi",  
             "body": [  
                 "<el-carousel-item :label=\"${1}\">",  
                     "\t${2:<!-- content -->}",  
                 "</el-carousel-item>",  
                 "${3}"  
             ],  
             "description": "Element UI <el-carousel-item>"  
         },  

         "Others: Collapse": {  
             "prefix": "elcolla",  
             "body": [  
                 "<el-collapse v-model=\"${1:activeNames}\" :accordion=\"${2:false}\" @change=\"$3\">",  
                     "\t<el-collapse-item v-for=\"${4:item} in ${5:items}\"",  
                         "\t\t:key=\"${4:item}.${6:id}\"",  
                         "\t\t:title=\"${4:item}.${7:title}\"",  
                         "\t\t:name=\"${4:item}.${6:id}\">",  
                         "\t\t${8:<!-- content -->}",  
                     "\t</el-collapse-item>",  
                 "</el-collapse>",  
                 "${9}"  
             ],  
             "description": "Element UI <el-collapse> with <el-collapse-item>"  
         },  

         "Others: Collapse Item": {  
             "prefix": "elcollai",  
             "body": [  
                 "<el-collapse-item :title=\"$1\" :name=\"$2\">",  
                     "\t${3:<!-- content -->}",  
                 "</el-collapse-item>",  
                 "${4}"  
             ],  
             "description": "Element UI <el-collapse-item>"  
         },  

         "Others: Collapse Timeline": {  
             "prefix": "elti",  
             "body": [  
                 "<el-timeline :reverse=\"$1\">",  
                     "\t<el-timeline-item v-for=\"${2:item} in ${3:items}\"",  
                         "\t\t:key=\"${2:item}.${4:id}\"",  
                         "\t\t:timestamp=\"${2:item}.${5:timestamp}\"",  
                         "\t\tplacement=\"${6|top,bottom|}\"",  
                         "\t\ttype=\"${7|primary,success,warning,danger,info|}\"",  
                         "\t\tsize=\"${8|normal,large|}\">",  
                         "\t\t${9:<!-- content -->}",  
                     "\t</el-timeline-item>",  
                 "</el-timeline>",  
                 "${10}"  
             ],  
             "description": "Element UI <el-timeline> with <el-timeline-item>"  
         },  

         "Others: Collapse Timeline Item": {  
             "prefix": "eltii",  
             "body": [  
                 "<el-timeline-item",  
                     "\ttimestamp=\"${1}\"",  
                     "\tplacement=\"${2|top,bottom|}\"",  
                     "\ttype=\"${3|primary,success,warning,danger,info|}\"",  
                     "\tsize=\"${4|normal,large|}\">",  
                     "\t${5:<!-- content -->}",  
                 "</el-timeline-item>",  
                 "${6}"  
             ],  
             "description": "Element UI <el-timeline-item>"  
         },  

         "Others: Divider": {  
             "prefix": "eld",  
             "body": [  
                 "<el-divider direction=\"${1|horizontal,vertical|}\" content-position=\"${2|left,right,center|}\">$3</el-divider>",  
                 "${4}"  
             ],  
             "description": "Element UI <el-divider>"  
         },  

         "Others: Calendar": {  
             "prefix": "elcal",  
             "body": [  
                 "<el-calendar v-model=\"${1}\" :first-day-of-week=\"${2:1}\"></el-calendar>",  
                 "${3}"  
             ],  
             "description": "Element UI <el-calendar>"  
         },  

         "Others: Image": {  
             "prefix": "elim",  
             "body": [  
                 "<el-image :src=\"${1}\" fit=\"${2|fill,contain,cover,none,scale-down|}\" :lazy=\"${3|true,false|}\"></el-image>",  
                 "${4}"  
             ],  
             "description": "Element UI <el-image>"  
         },  

         "Others: Backtop": {  
             "prefix": "elback",  
             "body": [  
                 "<el-backtop :target=\"${1}\" :right=\"${2:40}\" :bottom=\"${3:40}\">$4</el-backtop>",  
                 "${5}"  
             ],  
             "description": "Element UI <el-backtop>"  
         },  

         "Others: InfiniteScroll": {  
             "prefix": "elinfi",  
             "body": [  
                 "v-infinite-scroll=\"${1}\"",  
                 ":infinite-scroll-delay=\"${2}\"",  
                 ":infinite-scroll-distance=\"${3}\"",  
                 ":infinite-scroll-disabled=\"${4|false,true|}\"",  
                 ":infinite-scroll-immediate=\"${5|true,false|}\""  
             ],  
             "description": "Element UI v-infinite-scroll"  
         },  
         "Others: Drawer": {  
             "prefix": "eldra",  
             "body": [  
                 "<el-drawer title=\"${1}\" :visible.sync=\"${2}\" direction=\"${3|rtl,ltr,ttb,btt|}\" size=\"${4:30%}\"",  
                     "\t:before-close=\"${5}\" :destroy-on-close=\"${6|true,false|}\" :show-close=\"${7|true,false|}\" :wrapperClosable=\"${8|true,false|}\">",  
                 "</el-drawer>",  
                 "${9}"  
             ],  
             "description": "Element UI <el-drawer>"  
         },  
//自己编写  
         "table-column-slot": {  
             "prefix": "elss",  
             "body": [  
                 "<template slot-scope=\"scope\">",  
                 "\t${1}",  
                 "</template>",  
                 "${0}"  
             ],  
             "description": "template slot-scope"  
         }  

    //elementui提示结束  
}  
继续阅读 »

参考:https://github.com/snowffer/Element-UI-Snippets-VSCode
工具-代码设置-vue代码块

{  
    // 注意:本文档仅支持单行注释,并且'//'前不能有任何非空字符!!!  
    //  
    // HBuilderX使用json扩展代码块,兼容vscode的代码块格式  
    // 本文档修改完毕,保存即可生效,无需重启。  
    // 本文档用于用户自定义{1}代码块。  
    // 每个配置项的说明如下:  
    // 'key'    :代码块显示名称,显示在代码助手列表中的名字,以下例子中'console.log'就是一个key。  
    // 'prefix' :代码块的触发字符,就是敲什么字母匹配这个代码块。  
    // 'body'   :代码块的内容。内容中有如下特殊格式  
    //          $1 表示代码块输入后光标的所在位置。如需要多光标,就在多个地方配置$1,如该位置有预置数据,则写法是${1:foo1}。多选项即下拉候选列表使用${1:foo1/foo2/foo3}  
    //          $2 表示代码块输入后再次按tab后光标的切换位置tabstops(代码块展开后按tab可以跳到下一个tabstop)  
    //          $0代表代码块输入后最终光标的所在位置(也可以按回车直接跳过去)。  
    //          双引号使用\\'转义  
    //          换行使用多个数组表示,每个行一个数组,用双引号包围,并用逗号分隔  
    //          缩进需要用\\t表示,不能直接输入缩进!  
    // 'triggerAssist' :为true表示该代码块输入到文档后立即在第一个tabstop上触发代码提示,拉出代码助手,默认为false。  
    // 每个代码块以key为主键,多个代码块需要逗号分隔。  
    // 如果json语法不合法,底部会弹出错误信息,请注意修正。  
    // 例子:  
    // "console.log": {  
    //  "prefix": "logtwo",  
    //  "body": [  
    //      "console.log('$1');",  
    //      "\tconsole.log('$2');"  
    //  ],  
    //  "triggerAssist": false,  
    //  "description": "Log output to console twice"  
    // }  

     //elementui提示  
     //https://github.com/snowffer/Element-UI-Snippets-VSCode/tree/master/snippets  
     "Basic: Layout el-row": {  
             "prefix": "elrow",  
             "body": [  
                 "<el-row :gutter=\"${1:20}\">",  
                     "\t<el-col :span=\"${2:12}\" :offset=\"${3:0}\">${4}</el-col>",  
                     "\t<el-col :span=\"${5:12}\" :offset=\"${6:0}\">${7}</el-col>",  
                 "</el-row>",  
                 "${8}"  
             ],  
             "description": "Element UI <el-row> with <el-col>"  
         },  

         "Basic: Layout el-col": {  
             "prefix": "elcol",  
             "body": [  
                 "<el-col :span=\"${1}\" :offset=\"${2:0}\">",  
                 "\t${3}",  
                 "</el-col>",  
                 "${4}"  
             ],  
             "description": "Element UI <el-col>"  
         },  

         "Basic: Layout hidden class": {  
             "prefix": "elhc",  
             "body": [  
                 "${1|hidden-xs-only,hidden-sm-only,hidden-sm-and-down,hidden-sm-and-up,hidden-md-only,hidden-md-and-down,hidden-md-and-up,hidden-lg-only,hidden-lg-and-down,hidden-lg-and-up,hidden-xl-only|}"  
             ],  
             "description": "Element UI hidden class"  
         },  

         "Basic: Container el-container": {  
             "prefix": "elcon",  
             "body": [  
                 "<el-container :direction=\"${1:vertical}\">",  
                     "\t<el-header height=\"$2\">",  
                         "\t\t${3:<!-- Header content -->}",  
                     "\t</el-header>",  
                     "\t<el-container :direction=\"${4:horizontal}\">",  
                         "\t\t<el-aside width=\"${5:200px}\">",  
                             "\t\t\t${6:<!-- Aside content -->}",  
                         "\t\t</el-aside>",  
                         "\t\t<el-container :direction=\"${7:vertical}\">",  
                             "\t\t\t<el-main height=\"$8\">",  
                                 "\t\t\t\t${9:<!-- Main content -->}",  
                             "\t\t\t</el-main>",  
                             "\t\t\t<el-footer height=\"$10\">",  
                                 "\t\t\t\t${11:<!-- Footer content -->}",  
                             "\t\t\t</el-footer>",  
                         "\t\t</el-container>",  
                     "\t</el-container>",  
                 "</el-container>",  
                 "${12}"  
             ],  
             "description": "Element UI <el-container>"  
         },  

         "Basic: Container el-header": {  
             "prefix": "elhe",  
             "body": [  
                 "<el-header height=\"$1\">",  
                     "\t${2:<!-- Header content -->}",  
                 "</el-header>",  
                 "${3}"  
             ],  
             "description": "Element UI <el-header>"  
         },  

         "Basic: Container el-aside": {  
             "prefix": "elas",  
             "body": [  
                 "<el-aside width=\"${1:200px}\">",  
                     "\t${2:<!-- Aside content -->}",  
                 "</el-aside>",  
                 "${3}"  
             ],  
             "description": "Element UI <el-aside>"  
         },  

         "Basic: Container el-main": {  
             "prefix": "elma",  
             "body": [  
                 "<el-main height=\"${1}\">",  
                     "\t${2:<!-- Main content -->}",  
                 "</el-main>",  
                 "${3}"  
             ],  
             "description": "Element UI <el-main>"  
         },  

         "Basic: Container el-footer": {  
             "prefix": "elfo",  
             "body": [  
                 "<el-footer height=\"${1}\">",  
                     "\t${2:<!-- Footer content -->}",  
                 "</el-footer>",  
                 "${3}"  
             ],  
             "description": "Element UI <el-footer>"  
         },  

         "Basic: Color blue": {  
             "prefix": "elcb",  
             "body": ["#409EFF"],  
             "description": "Element UI Color Blue"  
         },  

         "Basic: Color danger": {  
             "prefix": "elcd",  
             "body": ["#F56C6C"],  
             "description": "Element UI Color Danger"  
         },  

         "Basic: Color info": {  
             "prefix": "elci",  
             "body": ["#909399"],  
             "description": "Element UI Color Info"  
         },  

         "Basic: Color success": {  
             "prefix": "elcs",  
             "body": ["#67C23A"],  
             "description": "Element UI Color Success"  
         },  

         "Basic: Color waring": {  
             "prefix": "elcw",  
             "body": ["#E6A23C"],  
             "description": "Element UI Color Waring"  
         },  

         "Basic: Color primary text": {  
             "prefix": "elcpt",  
             "body": ["#303133"],  
             "description": "Element UI Color Primary Text"  
         },  

         "Basic: Color regular text": {  
             "prefix": "elcrt",  
             "body": ["#606266"],  
             "description": "Element UI Color Regular Text"  
         },  

         "Basic: Color secondary text": {  
             "prefix": "elcst",  
             "body": ["#909399"],  
             "description": "Element UI Color Secondary Text"  
         },  

         "Basic: Color placeholder text": {  
             "prefix": "elcht",  
             "body": ["#C0C4CC"],  
             "description": "Element UI Color Placeholder Text"  
         },  

         "Basic: Color Base Border": {  
             "prefix": "elcbb",  
             "body": ["#DCDFE6"],  
             "description": "Element UI Color Base Border"  
         },  

         "Basic: Color Light Border": {  
             "prefix": "elclb",  
             "body": ["#E4E7ED"],  
             "description": "Element UI Color Light Border"  
         },  

         "Basic: Color Lighter Border": {  
             "prefix": "elclrb",  
             "body": ["#EBEEF5"],  
             "description": "Element UI Color Lighter Border"  
         },  

         "Basic: Color Extra Light Border": {  
             "prefix": "elelb",  
             "body": ["#DCDFE6"],  
             "description": "Element UI Color Extra Light Border"  
         },  

         "Basic: Typography": {  
             "prefix": "eltypo",  
             "body": ["font-family: \"Helvetica Neue\",Helvetica,\"PingFang SC\",\"Hiragino Sans GB\",\"Microsoft YaHei\",\"微软雅黑\",Arial,sans-serif;"],  
             "description": "Element UI Font-family"  
         },  

         "Basic: Border Basic Shadow": {  
             "prefix": "elbbs",  
             "body": ["box-shadow: 0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .04);"],  
             "description": "Element UI Border Basic Shadow"  
         },  

         "Basic: Border Light Shadow": {  
             "prefix": "elbls",  
             "body": ["box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);"],  
             "description": "Element UI Border Light Shadow"  
         },  

         "Basic: Button": {  
             "prefix": "elb",  
             "body": [  
                 "<el-button type=\"${1|primary,text,info,success,warning,danger|}\" size=\"${2|default,medium,small,mini|}\" @click=\"$3\">${4}</el-button>",  
                 "${5}"  
             ],  
             "description": "Element UI <el-button>"  
         },  

         "Basic: Button Group": {  
             "prefix": "elbg",  
             "body": [  
                 "<el-button-group>",  
                     "\t<el-button type=\"${1|primary,text,info,success,warning,danger|}\" size=\"${2|default,medium,small,mini|}\" @click=\"$3\">${4}</el-button>",  
                     "\t<el-button type=\"${5|primary,text,info,success,warning,danger|}\" size=\"${2|default,medium,small,mini|}\" @click=\"$6\">${7}</el-button>",  
                 "</el-button-group>",  
                 "${8}"  
             ],  
             "description": "Element UI <el-button-group>"  
         },  

         "Basic: Link": {  
             "prefix": "ell",  
             "body": [  
                 "<el-link type=\"${1|primary,success,warning,danger,info|}\" :underline=\"${2:false}\" href=\"${3}\" target=\"${4:_blank}\">${5}</el-link>",  
                 "${6}"  
             ],  
             "description": "Element UI <el-button>"  
         },  

         "Form: Radio": {  
             "prefix": "elr",  
             "body": [  
                 "<el-radio v-model=\"${1}\" label=\"${2}\" @change=\"${3}\">${4}</el-radio>",  
                 "${5}"  
             ],  
             "description": "Element UI <el-radio>"  
         },  

         "Form: Radio Group": {  
             "prefix": "elrg",  
             "body": [  
                 "<el-radio-group v-model=\"$1\" @change=\"$2\">",  
                     "\t<el-radio v-for=\"${3:item} in ${4:items}\" :key=\"${3:item}.${5:key}\" :label=\"${3:item}.${6:label}\">",  
                         "\t\t{{${3:item}.${7:title}}}",  
                     "\t</el-radio>",  
                 "</el-radio-group>",  
                 "${8}"  
             ],  
             "description": "Element UI <el-radio-group> with <el-radio>"  
         },  

         "Form: Radio Button Group": {  
             "prefix": "elrbg",  
             "body": [  
                 "<el-radio-group v-model=\"$1\" size=\"${2|normal,medium,small,mini|}\" @change=\"$3\">",  
                     "\t<el-radio-button v-for=\"${4:item} in ${5:items}\" :key=\"${4:item}.${6:key}\" :label=\"${4:item}.${7:label}\">",  
                         "\t\t{{${4:item}.${8:title}}}",  
                     "\t</el-radio-button>",  
                 "</el-radio-group>",  
                 "${9}"  
             ],  
             "description": "Element UI <el-radio-group> with <el-radio-button>"  
         },  

         "Form: Radio Button": {  
             "prefix": "elrb",  
             "body": [  
                 "<el-radio-button v-model=\"${1}\" label=\"${2}\">${3}</el-radio-button>",  
                 "${4}"  
             ],  
             "description": "Element UI <el-radio>"  
         },  

         "Form: Checkbox": {  
             "prefix": "elc",  
             "body": [  
                 "<el-checkbox v-model=\"${1}\" label=\"${2}\" :indeterminate=\"${3:false}\" @change=\"${4}\">{{$5}}</el-checkbox>",  
                 "${6}"  
             ],  
             "description": "Element UI <el-checkbox>"  
         },  

         "Form: Checkbox Group": {  
             "prefix": "elcg",  
             "body": [  
                 "<el-checkbox-group v-model=\"$1\" @change=\"${2}\">",  
                     "\t<el-checkbox v-for=\"${3:item} in ${4:items}\" :key=\"${3:item}.${5:key}\" :label=\"${3:item}.${6:label}\">",  
                         "\t\t{{${3:item}.${7:label}}}",  
                     "\t</el-checkbox>",  
                 "</el-checkbox-group>",  
                 "${8}"  
             ],  
             "description": "Element UI <el-checkbox-group> with <el-checkbox>"  
         },  

         "Form: Checkbox Button Group": {  
             "prefix": "elcbg",  
             "body": [  
                 "<el-checkbox-group v-model=\"$1\" size=\"${2|normal,medium,small,mini|}\"  @change=\"${3}\">",  
                     "\t<el-checkbox-button v-for=\"${4:item} in ${5:items}\" :key=\"${4:item}.${6:key}\" :label=\"${4:item}.${7:label}\">",  
                         "\t\t{{${4:item}.${8:label}}}",  
                     "\t</el-checkbox-button>",  
                 "</el-checkbox-group>",  
                 "${9}"  
             ],  
             "description": "Element UI <el-checkbox-group> with <el-checkbox-button>"  
         },  

         "Form: Checkbox Button": {  
             "prefix": "elcbt",  
             "body": [  
                 "<el-checkbox-button v-model=\"${1}\" label=\"${2}\" :indeterminate=\"${3:false}\" @change=\"${4}\">{{$5}}</el-checkbox-button>",  
                 "${6}"  
             ],  
             "description": "Element UI <el-checkbox-button>"  
         },  

         "Form: Input": {  
             "prefix": "eli",  
             "body": [  
                 "<el-input v-model=\"$1\" placeholder=\"$2\" size=\"${3|normal,medium,small,mini|}\" clearable @change=\"$4\">$5</el-input>",  
                 "${6}"  
             ],  
             "description": "Element UI <el-input>"  
         },  

         "Form: Textarea": {  
             "prefix": "elit",  
             "body": [  
                 "<el-input type=\"${1|text,textarea|}\" :rows=\"${2:2}\" v-model=\"$3\" placeholder=\"$4\" ",  
                     "\t:maxlength=\"${5:-1}\" :show-word-limit=\"${6|false,true|}\" :autosize=\"{ minRows: ${7:2}, maxRows: ${8:4} }\">",  
                 "</el-input>",  
                 "${9}"  
             ],  
             "description": "Element UI <el-input type=\"text,textarea\">"  
         },  

         "Form: Autocomplete": {  
             "prefix": "ela",  
             "body": [  
                 "<el-autocomplete v-model=\"$1\" value-key=\"$2\" placeholder=\"${3}\" clearable",  
                     "\t:debounce=\"$4\" :fetch-suggestions=\"${5}\"  @select=\"$6\">$7</el-autocomplete>",  
                 "${8}"  
             ],  
             "description": "Element UI <el-autocomplete>"  
         },  

         "Form: Input Slot": {  
             "prefix": "elis",  
             "body": [  
                 "<template slot=\"${1|prefix,suffix,prepend,append|}\">$2</template>",  
                 "${3}"  
             ],  
             "description": "Element UI <template slot=''>"  
         },  

         "Form: InputNumber": {  
             "prefix": "elin",  
             "body": [  
                 "<el-input-number v-model=\"$1\" size=\"${2|normal,medium,small,mini|}\" label=\"$3\"",  
                     "\t:min=\"${4:1}\" :max=\"${5:10}\" :step=\"${6:1}\" :controls=\"${7|true,false|}\" controls-position=\"${8|both,right|}\" @change=\"$9\">",  
                 "</el-input-number>",  
                 "${10}"  
             ],  
             "description": "Element UI <el-input-number>"  
         },  

         "Form: Select": {  
             "prefix": "elsel",  
             "body": [  
                 "<el-select v-model=\"$1\" value-key=\"$2\" placeholder=\"$3\" clearable filterable @change=\"$4\">",  
                     "\t<el-option v-for=\"${5:item} in ${6:options}\"",  
                         "\t\t:key=\"${5:item}.${7:value}\"",  
                         "\t\t:label=\"${5:item}.${8:label}\"",  
                         "\t\t:value=\"${5:item}.${9:value}\">",  
                     "\t</el-option>",  
                 "</el-select>",  
                 "${10}"  
             ],  
             "description": "Element UI <el-select>"  
         },  

         "Form: Select Remote Search": {  
             "prefix": "elselr",  
             "body": [  
                 "<el-select v-model=\"$1\" value-key=\"$2\" placeholder=\"$3\" clearable filterable",  
                     "\tremote reserve-keyword :remote-method=\"$4\" :loading=\"$5\" @change=\"$6\">",  
                     "\t<el-option v-for=\"${7:item} in ${8:options}\"",  
                         "\t\t:key=\"${7:item}.${9:value}\"",  
                         "\t\t:label=\"${7:item}.${10:label}\"",  
                         "\t\t:value=\"${7:item}.${11:value}\">",  
                     "\t</el-option>",  
                 "</el-select>",  
                 "${12}"  
             ],  
             "description": "Element UI <el-select>"  
         },  

         "Form: Select Option": {  
             "prefix": "elop",  
             "body": [  
                 "<el-option :key=\"$1\" :label=\"$2\" :value=\"$3\"></el-option>",  
                 "${3}"  
             ],  
             "description": "Element UI <el-option>"  
         },  

         "Form: Select Option Group": {  
             "prefix": "elopg",  
             "body": [  
                 "<el-option-group v-for=\"${1:group} in ${2:options}\"",  
                     "\t:key=\"${1:group}.${3:value}\"",  
                     "\t:label=\"${1:group}.${4:label}\">",  
                     "\t<el-option v-for=\"${5:item} in ${1:group}.${6:options}\"",  
                         "\t\t:key=\"${5:item}.${7:value}\"",  
                         "\t\t:label=\"${5:item}.${8:label}\"",  
                         "\t\t:value=\"${5:item}.${9:value}\">",  
                     "\t</el-option>",  
                 "<el-option-group>",  
                 "${10}"  
             ],  
             "description": "Element UI <el-option-group>"  
         },  

         "Form: Cascader": {  
             "prefix": "elca",  
             "body": [  
                 "<el-cascader :options=\"${1:options}\" v-model=\"${2}\" clearable filterable :show-all-levels=\"${3|false,true|}\"",  
                     "\t:props=\"{ expandTrigger: ${4|'hover','click'|}, multiple: ${5|true,false|}, checkStrictly: ${6|true,false|} }\" @change=\"${7}\">",  
                 "</el-cascader>",  
                 "${8}"  
             ],  
             "description": "Element UI <el-cascader>"  
         },  

         "Form: Cascader Panel": {  
             "prefix": "elcap",  
             "body": [  
                 "<el-cascader :options=\"${1:options}\" v-model=\"${2}\" @change=\"${3}\"",  
                     "\t:props=\"{ expandTrigger: ${4|'hover','click'|}, multiple: ${5|true,false|}, checkStrictly: ${6|true,false|} }\">",  
                 "</el-cascader>",  
                 "${7}"  
             ],  
             "description": "Element UI <el-cascader-panel>"  
         },  

         "Form: Switch": {  
             "prefix": "elsw",  
             "body": [  
                 "<el-switch v-model=\"$1\" :active-value=\"${2:true}\" :inactive-value=\"${3:false}\" @change=\"$4\">",  
                 "</el-switch>",  
                 "${5}"  
             ],  
             "description": "Element UI <el-switch>"  
         },  

         "Form: Slider": {  
             "prefix": "elsl",  
             "body": [  
                 "<el-slider v-model=\"$1\" :min=\"$2\" :max=\"$3\" :step=\"$4\" vertical=\"${5:false}\" @change=\"$6\">",  
                 "</el-slider>",  
                 "${7}"  
             ],  
             "description": "Element UI <el-slider>"  
         },  

         "Form: Time Select": {  
             "prefix": "elts",  
             "body": [  
                 "<el-time-select v-model=\"$1\" size=\"${2|normal,medium,small,mini|}\" placeholder=\"$3\"",  
                     "\t:picker-options=\"{",  
                         "\t\tstart: '${4}',",  
                         "\t\tstep: '${5:00:30}',",  
                         "\t\tend: '${6}',",  
                     "\t}\"",  
                     "\tchange=\"${7}\">",  
                 "</el-time-select>",  
                 "${8}"  
             ],  
             "description": "Element UI <el-time-select>"  
         },  

         "Form: Time Select Range": {  
             "prefix": "eltsr",  
             "body": [  
                 "<el-time-select v-model=\"$1\" size=\"${2|normal,medium,small,mini|}\" placeholder=\"$3\"",  
                     "\t:picker-options=\"{",  
                         "\t\tstart: '${4}',",  
                         "\t\tstep: '${5:00:30}',",  
                         "\t\tend: '${6}',",  
                     "\t}\">",  
                 "</el-time-select>",  
                 "<el-time-select v-model=\"$7\" size=\"${2|normal,medium,small,mini|}\" placeholder=\"$8\"",  
                     "\t:picker-options=\"{",  
                         "\t\tstart: '${4}',",  
                         "\t\tstep: '${5:00:30}',",  
                         "\t\tend: '${6}',",  
                         "\t\tminTime: $1",  
                     "\t}\">",  
                 "</el-time-select>",  
                 "${9}"  
             ],  
             "description": "Element UI <el-time-select> range"  
         },  

         "Form: TimePicker": {  
             "prefix": "eltp",  
             "body": [  
                 "<el-time-picker v-model=\"$1\" size=\"${2|normal,medium,small,mini|}\" arrow-control",  
                     "\t:picker-options=\"{",  
                         "\t\tselectableRange: '${3:18:30:00} - ${4:20:30:00}'",  
                     "\t}\"",  
                     "\tplaceholder=\"${5:任意时间点}\">",  
                 "</el-time-picker>",  
                 "${6}"  
             ],  
             "description": "Element UI <el-time-picker>"  
         },  

         "Form: TimePicker Range": {  
             "prefix": "eltpr",  
             "body": [  
                 "<el-time-picker v-model=\"$1\" size=\"${2|normal,medium,small,mini|}\" arrow-control",  
                     "\tis-range range-separator=\"${3:-}\" start-placeholder=\"$4\" end-placeholder=\"$5\"",  
                     "\t:picker-options=\"{",  
                         "\t\tselectableRange: '${6:18:30:00} - ${7:20:30:00}'",  
                     "\t}\">",  
                 "</el-time-picker>",  
                 "${8}"  
             ],  
             "description": "Element UI <el-time-picker is-range>"  
         },  

         "Form: DatePicker": {  
             "prefix": "eldp",  
             "body": [  
                 "<el-date-picker v-model=\"$1\" type=\"${2|year,month,date,dates,week|}\" size=\"${3|normal,medium,small,mini|}\" placeholder=\"${4:选择日期时间}\">",  
                 "</el-date-picker>",  
                 "${5}"  
             ],  
             "description": "Element UI <el-date-picker>"  
         },  

         "Form: DatePicker Range": {  
             "prefix": "eldpr",  
             "body": [  
                 "<el-date-picker v-model=\"$1\" type=\"${2|daterange,monthrange|}\" size=\"${3|normal,medium,small,mini|}\"",  
                     "\trange-separator=\"${4:-}\" start-placeholder=\"$5\" end-placeholder=\"$6\">",  
                 "</el-date-picker>",  
                 "${7}"  
             ],  
             "description": "Element UI <el-date-picker>"  
         },  

         "Form: DateTimePicker": {  
             "prefix": "eldtp",  
             "body": [  
                 "<el-date-picker v-model=\"$1\" type=\"datetime\" size=\"${2|normal,medium,small,mini|}\" placeholder=\"${3:选择日期时间}\">",  
                 "</el-date-picker>",  
                 "${4}"  
             ],  
             "description": "Element UI <el-date-picker type=\"datetime\">"  
         },  

         "Form: DateTimePicker Range": {  
             "prefix": "eldtpr",  
             "body": [  
                 "<el-date-picker v-model=\"$1\" type=\"datetimerange\" size=\"${2|normal,medium,small,mini|}\"",  
                     "\trange-separator=\"${3:-}\" start-placeholder=\"$4\" end-placeholder=\"$5\">",  
                 "</el-date-picker>",  
                 "${6}"  
             ],  
             "description": "Element UI <el-date-picker type=\"datetime\">"  
         },  

         "Form: Upload": {  
             "prefix": "elu",  
             "body": [  
                 "<el-upload",  
                     "\taction=\"$1\"",  
                     "\tref=\"${2:upload}\"",  
                     "\t:on-remove=\"$3\"",  
                     "\t:auto-upload=\"false\"",  
                     "\tmultiple",  
                     "\t:limit=\"${4:5}\"",  
                     "\t:on-exceed=\"$5\"",  
                     "\t:file-list=\"$6\">",  
                     "\t<el-button slot=\"trigger\" size=\"small\" type=\"primary\">${7:select file}</el-button>",  
                     "\t<el-button style=\"margin-left: 10px;\" size=\"small\" type=\"success\" @click=\"$8\">${9:upload to server}</el-button>",  
                     "\t<div slot=\"tip\" class=\"el-upload__tip\">${10:jpg/png files with a size less than 500kb}</div>",  
                 "</el-upload>",  
                 "${11}"  
             ],  
             "description": "Element UI <el-upload>"  
         },  

         "Form: Rate": {  
             "prefix": "elra",  
             "body": [  
                 "<el-rate v-model=\"$1\" :allow-half=\"${2|false,true|}\" @change=\"$3\"></el-rate>",  
                 "${4}"  
             ],  
             "description": "Element UI <el-rate>"  
         },  

         "Form: ColorPicker": {  
             "prefix": "elcp",  
             "body": [  
                 "<el-color-picker v-model=\"$1\" size=\"${2|normal,medium,small,mini|}\" :show-alpha=\"${3|true,false|}\" ></el-color-picker>",  
                 "${4}"  
             ],  
             "description": "Element UI <el-color-picker>"  
         },  

         "Form: Transfer": {  
             "prefix": "eltr",  
             "body": [  
                 "<el-transfer v-model=\"$1\" :data=\"$2\" target-order=\"${3|original,push,unshift|}\" filterable @change=\"$4\"",  
                     "\t:format=\"{noChecked: '\\${total}',hasChecked: '\\${checked}/\\${total}'}\">",  
                 "</el-transfer>",  
                 "${5}"  
             ],  
             "description": "Element UI <el-transfer>"  
         },  

         "Form: Form": {  
             "prefix": "elf",  
             "body": [  
                 "<el-form :model=\"${1:form}\" ref=\"${2:form}\" :rules=\"${3:rules}\" label-width=\"80px\" :inline=\"${4|false,true|}\" size=\"${5|normal,medium,small,mini|}\">",  
                     "\t<el-form-item label=\"$6\">",  
                         "\t\t<el-input v-model=\"${1:form}.${7}\"></el-input>",  
                     "\t</el-form-item>",  
                     "\t<el-form-item>",  
                         "\t\t<el-button type=\"primary\" @click=\"onSubmit\">${8:立即创建}</el-button>",  
                         "\t\t<el-button>${9:取消}</el-button>",  
                     "\t</el-form-item>",  
                 "</el-form>",  
                 "${10}"  
             ],  
             "description": "Element UI <el-form>"  
         },  

         "Form: Form Item": {  
             "prefix": "elfi",  
             "body": [  
                 "<el-form-item label=\"$1\" size=\"${2|normal,medium,small,mini|}\">",  
                     "\t$3",  
                 "</el-form-item>",  
                 "${4}"  
             ],  
             "description": "Element UI <el-form-item>"  
         },  

         "Data: Table": {  
             "prefix": "elt",  
             "body": [  
                 "<el-table :data=\"$1\" border stripe>",  
                     "\t<el-table-column v-for=\"${2:col} in ${3:columns}\"",  
                         "\t\t:prop=\"${2:col}.${4:id}\"",  
                         "\t\t:key=\"${2:col}.${4:id}\"",  
                         "\t\t:label=\"${2:col}.${5:label}\"",  
                         "\t\t:width=\"${2:col}.${6:width}\">",  
                     "\t</el-table-column>",  
                 "</el-table>",  
                 "${7}"  
             ],  
             "description": "Element UI <el-table>"  
         },  

         "Data: Table Column": {  
             "prefix": "eltc",  
             "body": [  
                 "<el-table-column :label=\"${1}\" :min-width=\"${2}\" :prop=\"${3}\" </el-table-column>",  
                 "${0}"  
             ],  
             "description": "Element UI <el-table-column>"  
         },  

         "Data: Tag": {  
             "prefix": "elta",  
             "body": [  
                 "<el-tag type=\"${1|danger,info,success,warning|}\" size=\"${2|normal,medium,small,mini|}\"  effect=\"${3|dark,plain|}\" closable @close=\"${4}\">$5</el-tag>",  
                 "${6}"  
             ],  
             "description": "Element UI <el-tag>"  
         },  

         "Data: Progress": {  
             "prefix": "elpr",  
             "body": [  
                 "<el-progress type=\"${1|line,circle,dashboard|}\" :percentage=\"$2\" status=\"${3|success,exception,warning|}\" :stroke-width=\"${4:6}\"></el-progress>",  
                 "${5}"  
             ],  
             "description": "Element UI <el-progress>"  
         },  

         "Data: Tree": {  
             "prefix": "eltree",  
             "body": [  
                 "<el-tree ref=\"${1:tree}\" :data=\"$2\" node-key=\"$3\" :props=\"$4\" empty-text=\"$5\" show-checkbox=\"${6|false,true|}\" highlight-current=\"${7|true,false|}\" @node-click=\"$8\">$9</el-tree>",  
                 "${10}"  
             ],  
             "description": "Element UI <el-tree>"  
         },  

         "Data: Pagination": {  
             "prefix": "elp",  
             "body": [  
                 "<el-pagination",  
                     "\t@size-change=\"${1:sizeChange}\"",  
                     "\t@current-change=\"${2:currentChange}\"",  
                     "\t:current-page.sync=\"${3:currentPage}\"",  
                     "\t:page-sizes=\"${4:[20, 40, 80, 100]}\"",  
                     "\t:page-size=\"${5:pageSize}\"",  
                     "\tlayout=\"total, sizes, prev, pager, next, jumper\"",  
                     "\t:total=\"${6:totalNum}\" background>",  
                     "\t:pager-count=\"${7:7}\">",  
                 "</el-pagination>",  
                 "${8}"  
             ],  
             "description": "Element UI <el-pagination>"  
         },  

         "Data: Badge": {  
             "prefix": "elba",  
             "body": [  
                 "<el-badge :value=\"${1}\" :max=\"${2:99}\" :is-dot=\"${3|false,true|}\" :hidden=\"${4|false,true|}\" type=\"${5|primary,success,warning,danger,info|}\">",  
                     "\t<el-button size=\"small\">$6</el-button>",  
                 "</el-badge>",  
                 "${7}"  
             ],  
             "description": "Element UI <el-badge>"  
         },  

         "Data: Avatar": {  
             "prefix": "elav",  
             "body": [  
                 "<el-avatar icon=\"el-icon-user-solid\" size=\"${1|large,medium,small|}\" shape=\"${2|circle,square|}\" :src=\"${3}\" fit=\"${4|fill,contain,cover,none,scale-down|}\"></el-avatar>",  
                 "${5}"  
             ],  
             "description": "Element UI <el-avatar>"  
         },  

         "Notice: Alert": {  
             "prefix": "elal",  
             "body": [  
                 "<el-alert :title=\"$1\" type=\"${2|info,success,warning,error|}\" effect=\"${3|light,dark|}\" show-icon closable></el-alert>",  
                 "${4}"  
             ],  
             "description": "Element UI <el-alert>"  
         },  

         "Notice: Loading": {  
             "prefix": "elloads",  
             "body": [  
                 "element-loading-text=\"${1:拼命加载中}\"",  
                 "element-loading-spinner=\"${2:el-icon-loading}\"",  
                 "element-loading-background=\"${3:rgba(0, 0, 0, 0.8)}\"",  
                 "${4}"  
             ],  
             "description": "Element UI loading options"  
         },  

         "Notice: Message": {  
             "prefix": "elme",  
             "body": [  
                 "this.\\$message({",  
                     "\tmessage: '$1',",  
                     "\ttype: '${2|info,success,warning,error|}',",  
                     "\tshowClose: ${3:true},",  
                     "\tduration: ${4:3000},",  
                 "});",  
                 "${5}"  
             ],  
             "description": "Element UI $message"  
         },  

         "Notice: Messagebox": {  
             "prefix": "elmebox",  
             "body": [  
                 "this.\\$msgbox({",  
                     "\ttitle: '$1',",  
                     "\tmessage: '${2}',",  
                     "\tshowCancelButton: true,",  
                     "\tconfirmButtonText: '${3:OK}',",  
                     "\tcancelButtonText: '${4:Cancel}',",  
                     "\tcenter: ${5:false},",  
                     "\tbeforeClose: (action, instance, done) => {",  
                         "\t\t${6}",  
                     "\t}",  
                 "}).then(action => {",  
                     "\t${7}",  
                 "}).catch(() => {",  
                     "\t${8}",  
                 "});",  
                 "${9}"  
             ],  
             "description": "Element UI $msgbox"  
         },  

         "Notice: Messagebox Alert": {  
             "prefix": "elmeal",  
             "body": [  
                 "this.\\$alert('${1:content}', '${2:title}', {",  
                     "\tconfirmButtonText: '${3:OK}',",  
                     "\tcallback: action => {",  
                         "\t\t${4}",  
                     "\t}",  
                 "})",  
                 "${5}"  
             ],  
             "description": "Element UI $alert"  
         },  

         "Notice: Messagebox Confirm": {  
             "prefix": "elmecon",  
             "body": [  
                 "this.\\$confirm('${1:content}', '${2:title}', {",  
                     "\tconfirmButtonText: '${3:OK}',",  
                     "\tcancelButtonText: '${4:Cancel}',",  
                     "\ttype: '${5|success,info,warning,erro|}',",  
                 "}).then(action => {",  
                     "\t${6}",  
                 "}).catch(() => {",  
                     "\t${7}",  
                 "});",  
                 "${8}"  
             ],  
             "description": "Element UI $confirm"  
         },  

         "Notice: Messagebox Prompt": {  
             "prefix": "elmepro",  
             "body": [  
                 "this.\\$prompt('${1:content}', '${2:title}', {",  
                     "\tconfirmButtonText: '${3:OK}',",  
                     "\tcancelButtonText: '${4:Cancel}',",  
                     "\tinputPattern: / ${5} /,",  
                     "\tinputErrorMessage: '${6}',",  
                 "}).then(({ value }) => {",  
                     "\t${7}",  
                 "}).catch(() => {",  
                     "\t${8}",  
                 "});",  
                 "${9}"  
             ],  
             "description": "Element UI $prompt"  
         },  

         "Notice: Notification": {  
             "prefix": "elno",  
             "body": [  
                 "this.\\$notify({",  
                     "\ttitle: '${1:title}',",  
                     "\tmessage: '${2:message}',",  
                     "\ttype: '${3|info,success,warning,error|}',",  
                     "\tduration: '${4|4500, 0|}',",  
                     "\tposition: '${5|top-right,top-left,bottom-right,bottom-left|}',",  
                     "\tshowClose: '${6:true}',",  
                 "});",  
                 "${7}"  
             ],  
             "description": "Element UI $notify"  
         },  

         "Notice: Notification with type": {  
             "prefix": "elnot",  
             "body": [  
                 "this.\\$notify.${1|info,success,warning,error|}({",  
                     "\ttitle: '${2:title}',",  
                     "\tmessage: '${3:message}',",  
                     "\tduration: '${4|4500, 0|}',",  
                     "\tposition: '${5|top-right,top-left,bottom-right,bottom-left|}',",  
                     "\tshowClose: '${6:true}',",  
                 "});",  
                 "${7}"  
             ],  
             "description": "Element UI $notify.type"  
         },  

         "Navigation: NavMenu Menu": {  
             "prefix": "elmen",  
             "body": [  
                 "<el-menu mode=\"${1|horizontal,vertical|}\" default-active=\"$2\" @select=\"$3\">",  
                     "\t<el-submenu v-for=\"(${4:submenus}, ${5:index}) in ${6:menus}\"",  
                         "\t\t:index=\"${5:index} + 1\"",  
                         "\t\t:key=\"${4:submenus}.${7:key}\">",  
                         "\t\t<template slot=\"title\">{{${4:submenus}.${8:title}}}</template>",  
                         "\t\t<el-menu-item v-for=\"(${9:item}, ${10:subIndex}) in ${4:submenus}.${11:menus}\"",  
                             "\t\t\t:index=\"(${5:index} + 1) + '-' + (${10:subIndex} + 1)\"",  
                             "\t\t\t:key=\"${9:item}.${12:key}\">",  
                                 "\t\t\t\t{{${9:item}.${13:title}}}",  
                         "\t\t</el-menu-item>",  
                     "\t</el-submenu>",  
                 "</el-menu>",  
                 "${14}"  
             ],  
             "description": "Element UI <el-menu> with <el-submenu> and <el-menu-item>"  
         },  

         "Navigation: NavMenu subMenu": {  
             "prefix": "elsubmen",  
             "body": [  
                 "<el-submenu :index=\"$1\">",  
                     "\t<template slot=\"title\">$2</template>",  
                     "\t<el-menu-item v-for=\"(${3:item}, ${4:subIndex}) in $5\"",  
                         "\t\t:index=\"${4:subIndex} + 1\"",  
                         "\t\t:key=\"${3:item}.${6:key}\">",  
                             "\t\t\t{{${3:item}.${7:title}}}",  
                     "\t</el-menu-item>",  
                 "</el-submenu>",  
                 "${8}"  
             ],  
             "description": "Element UI <el-submenu> with <el-menu-item>"  
         },  

         "Navigation: NavMenu Menu Item": {  
             "prefix": "elmeni",  
             "body": [  
                 "<el-menu-item index=\"$1\" key=\"$2\">$3</el-menu-item>",  
                 "${4}"  
             ],  
             "description": "Element UI <el-menu-item>"  
         },  

         "Navigation: Tabs": {  
             "prefix": "eltabs",  
             "body": [  
                 "<el-tabs v-model=\"$1\" type=\"${2|card,border-card,normal|}\" tab-position=\"${3|top,left,right,bottom|}\" @tab-click=\"$4\">",  
                     "\t<el-tab-pane v-for=\"${5:item} in ${6:panes}\"",  
                         "\t\t:key=\"${5:item}.${7:key}\"",  
                         "\t\t:label=\"${5:item}.${8:label}\"",  
                         "\t\t:name=\"${5:item}.${7:key}\">",  
                         "\t\t$9",  
                     "\t</el-tab-pane>",  
                 "</el-tabs>",  
                 "${10}"  
             ],  
             "description": "Element UI <el-tabs> with <el-tab-pane>"  
         },  

         "Navigation: Tabs tab pane": {  
             "prefix": "eltabp",  
             "body": [  
                 "<el-tab-pane :label=\"$1\" :name=\"$2\">",  
                     "\t$3",  
                 "</el-tab-pane>",  
                 "${4}"  
             ],  
             "description": "Element UI <el-tab-pane>"  
         },  

         "Navigation: Breadcrumb": {  
             "prefix": "elbr",  
             "body": [  
                 "<el-breadcrumb separator-class=\"${1:el-icon-arrow-right}\">",  
                     "\t<el-breadcrumb-item :to=\"{ path: '$2', name: '$3' }\">$4</el-breadcrumb-item>",  
                     "\t<el-breadcrumb-item :to=\"{ path: '$5', name: '$6' }\">$7</el-breadcrumb-item>",  
                 "</el-breadcrumb>",  
                 "${8}"  
             ],  
             "description": "Element UI <el-breadcrumb>"  
         },  

         "Navigation: Breadcrumb Item": {  
             "prefix": "elbri",  
             "body": [  
                 "<el-breadcrumb-item :to=\"{ path: '$1', name: '$2' }\">$3</el-breadcrumb-item>",  
                 "${4}"  
             ],  
             "description": "Element UI <el-breadcrumb-item>"  
         },  

         "Navigation: PageHeader": {  
             "prefix": "elpa",  
             "body": [  
                 "<el-page-header @back=\"$1\" content=\"$2\"></el-page-header>",  
                 "${3}"  
             ],  
             "description": "Element UI <el-page-header>"  
         },  

         "Navigation: Dropdown": {  
             "prefix": "eldr",  
             "body": [  
                 "<el-dropdown trigger=\"${1:click}\" size=\"${2|default,medium,small,mini|}\" split-button type=\"${3|primary,success,warning,danger,info,text|}\" @command=\"$4\">",  
                     "\t${5:title}",  
                     "\t<el-dropdown-menu slot=\"dropdown\">",  
                         "\t\t<el-dropdown-item v-for=\"${6:item} in ${7:items}\"",  
                             "\t\t\t:key=\"${6:item}.${8:key}\" :command=\"${6:item}.${9:command}\">",  
                             "\t\t\t{{${6:item}.${10:title}}}",  
                         "\t\t</el-dropdown-item>",  
                     "\t</el-dropdown-menu>",  
                 "</el-dropdown>",  
                 "${11}"  
             ],  
             "description": "Element UI <el-dropdown> with <el-dropdown-item>"  
         },  

         "Navigation: Dropdown Item": {  
             "prefix": "eldri",  
             "body": [  
                 "<el-dropdown-item :command=\"$1\">$2</el-dropdown-item>",  
                 "${3}"  
             ],  
             "description": "Element UI <el-dropdown-item>"  
         },  

         "Navigation: Steps": {  
             "prefix": "elsts",  
             "body": [  
                 "<el-steps :active=\"$1\" direction=\"${2|horizontal,vertical|}\" process-status=\"${3|wait,process,finish,error,success|}\" finish-status=\"${4|wait,process,finish,error,success|}\">",  
                     "\t<el-step v-for=\"${5:item} in ${6:items}\"",  
                         "\t\t:key=\"${5:item}.${7:key}\"",  
                         "\t\t:title=\"${5:item}.${8:title}\"",  
                         "\t\t:description=\"${5:item}.${9:description}\"",  
                         "\t\t:icon=\"${5:item}.${10:icon}\">",  
                     "\t</el-step>",  
                 "</el-steps>",  
                 "${11}"  
             ],  
             "description": "Element UI <el-steps> with <el-step>"  
         },  

         "Navigation: Steps Step": {  
             "prefix": "elst",  
             "body": [  
                 "<el-step :title=\"$1\" :description=\"$2\" :icon=\"$3\"></el-step>",  
                 "${4}"  
             ],  
             "description": "Element UI <el-step>"  
         },  

         "Others: Dialog": {  
             "prefix": "eldi",  
             "body": [  
                 "<el-dialog title=\"$1\" :visible.sync=\"$2\" width=\"${3:30%}\" @close=\"$4\">",  
                     "\t<span>$5</span>",  
                     "\t<span slot=\"footer\">",  
                         "\t\t<el-button @click=\"$2 = false\">Cancel</el-button>",  
                         "\t\t<el-button type=\"primary\" @click=\"$6\">OK</el-button>",  
                     "\t</span>",  
                 "</el-dialog>",  
                 "${7}"  
             ],  
             "description": "Element UI <el-dialog>"  
         },  

         "Others: Tooltip": {  
             "prefix": "elto",  
             "body": [  
                 "<el-tooltip content=\"$1\" placement=\"${2|top,top-start,top-end,bottom,bottom-start,bottom-end,left,left-start,left-end,right,right-start,right-end|}\" effect=\"${3|dark,light|}\">",  
                     "\t${4:<!-- content to trigger tooltip here -->}",  
                 "</el-tooltip>",  
                 "${5}"  
             ],  
             "description": "Element UI <el-tooltip>"  
         },  

         "Others: Popover": {  
             "prefix": "elpo",  
             "body": [  
                 "<el-popover",  
                     "\t:ref=\"$1\"",  
                     "\tplacement=\"${2|top,top-start,top-end,bottom,bottom-start,bottom-end,left,left-start,left-end,right,right-start,right-end|}\"",  
                     "\ttitle=\"$3\"",  
                     "\twidth=\"$4\"",  
                     "\ttrigger=\"${5|click,focus,hover,manual|}\"",  
                     "\tcontent=\"$6\">",  
                     "\t${7: <!-- <el-button slot=\"reference\">content</el-button> -->}",  
                 "</el-popover>",  
                 "${8}"  
             ],  
             "description": "Element UI <el-popover>"  
         },  

         "Others: Popconfirm": {  
             "prefix": "elpoco",  
             "body": [  
                 "<el-popconfirm",  
                     "\ttitle=\"$1\"",  
                     "\tconfirmButtonText=\"$2\"",  
                     "\tcancelButtonText=\"$3\"",  
                     "\tconfirmButtonType=\"${4|primary,text,info,success,warning,danger|}\"",  
                     "\tcancelButtonType=\"${5|text,primary,info,success,warning,danger|}\"",  
                     "\ticon=\"${6:el-icon-question}\"",  
                     "\ticonColor=\"${7:#f90}\"",  
                     "\thideIcon=\"${8|false,true|}\">",  
                     "\t<el-button slot=\"reference\">$9</el-button>",  
                 "</el-popconfirm>",  
                 "${10}"  
             ],  
             "description": "Element UI <el-popconfirm>"  
         },  

         "Others: Card": {  
             "prefix": "elcard",  
             "body": [  
                 "<el-card shadow=\"${1|always,hover,never|}\" :body-style=\"${2:{ padding: '20px' }}\">",  
                     "\t<div slot=\"header\">",  
                         "\t\t<span>${3:<!-- card title -->}</span>",  
                     "\t</div>",  
                     "\t${4:<!-- card body -->}",  
                 "</el-card>",  
                 "${5}"  
             ],  
             "description": "Element UI <el-card>"  
         },  

         "Others: Carousel": {  
             "prefix": "elcaro",  
             "body": [  
                 "<el-carousel height=\"${1:150px}\" type=\"${2|default,card|}\" direction=\"${3|horizontal,vertical|}\"",  
                     "\t:initial-index=\"${4:0}\" :autoplay=\"${5|true, false|}\" :interval=\"${6:3000}\" :loop=\"${7|true,false|}\"",  
                     "\ttrigger=\"${8|hover,click|}\" indicator-position=\"${9|outside,inside,none|}\" arrow=\"${10|hover,always,never|}\">",  
                     "\t<el-carousel-item v-for=\"${11:item} in ${12:items}\" :key=\"${11:item}.${13:key}\" :label=\"${14}\">",  
                         "\t\t${15:<!-- content -->}",  
                     "\t</el-carousel-item>",  
                 "</el-carousel>",  
                 "${16}"  
             ],  
             "description": "Element UI <el-carousel> with <el-carousel-item>"  
         },  

         "Others: Carousel Item": {  
             "prefix": "elcaroi",  
             "body": [  
                 "<el-carousel-item :label=\"${1}\">",  
                     "\t${2:<!-- content -->}",  
                 "</el-carousel-item>",  
                 "${3}"  
             ],  
             "description": "Element UI <el-carousel-item>"  
         },  

         "Others: Collapse": {  
             "prefix": "elcolla",  
             "body": [  
                 "<el-collapse v-model=\"${1:activeNames}\" :accordion=\"${2:false}\" @change=\"$3\">",  
                     "\t<el-collapse-item v-for=\"${4:item} in ${5:items}\"",  
                         "\t\t:key=\"${4:item}.${6:id}\"",  
                         "\t\t:title=\"${4:item}.${7:title}\"",  
                         "\t\t:name=\"${4:item}.${6:id}\">",  
                         "\t\t${8:<!-- content -->}",  
                     "\t</el-collapse-item>",  
                 "</el-collapse>",  
                 "${9}"  
             ],  
             "description": "Element UI <el-collapse> with <el-collapse-item>"  
         },  

         "Others: Collapse Item": {  
             "prefix": "elcollai",  
             "body": [  
                 "<el-collapse-item :title=\"$1\" :name=\"$2\">",  
                     "\t${3:<!-- content -->}",  
                 "</el-collapse-item>",  
                 "${4}"  
             ],  
             "description": "Element UI <el-collapse-item>"  
         },  

         "Others: Collapse Timeline": {  
             "prefix": "elti",  
             "body": [  
                 "<el-timeline :reverse=\"$1\">",  
                     "\t<el-timeline-item v-for=\"${2:item} in ${3:items}\"",  
                         "\t\t:key=\"${2:item}.${4:id}\"",  
                         "\t\t:timestamp=\"${2:item}.${5:timestamp}\"",  
                         "\t\tplacement=\"${6|top,bottom|}\"",  
                         "\t\ttype=\"${7|primary,success,warning,danger,info|}\"",  
                         "\t\tsize=\"${8|normal,large|}\">",  
                         "\t\t${9:<!-- content -->}",  
                     "\t</el-timeline-item>",  
                 "</el-timeline>",  
                 "${10}"  
             ],  
             "description": "Element UI <el-timeline> with <el-timeline-item>"  
         },  

         "Others: Collapse Timeline Item": {  
             "prefix": "eltii",  
             "body": [  
                 "<el-timeline-item",  
                     "\ttimestamp=\"${1}\"",  
                     "\tplacement=\"${2|top,bottom|}\"",  
                     "\ttype=\"${3|primary,success,warning,danger,info|}\"",  
                     "\tsize=\"${4|normal,large|}\">",  
                     "\t${5:<!-- content -->}",  
                 "</el-timeline-item>",  
                 "${6}"  
             ],  
             "description": "Element UI <el-timeline-item>"  
         },  

         "Others: Divider": {  
             "prefix": "eld",  
             "body": [  
                 "<el-divider direction=\"${1|horizontal,vertical|}\" content-position=\"${2|left,right,center|}\">$3</el-divider>",  
                 "${4}"  
             ],  
             "description": "Element UI <el-divider>"  
         },  

         "Others: Calendar": {  
             "prefix": "elcal",  
             "body": [  
                 "<el-calendar v-model=\"${1}\" :first-day-of-week=\"${2:1}\"></el-calendar>",  
                 "${3}"  
             ],  
             "description": "Element UI <el-calendar>"  
         },  

         "Others: Image": {  
             "prefix": "elim",  
             "body": [  
                 "<el-image :src=\"${1}\" fit=\"${2|fill,contain,cover,none,scale-down|}\" :lazy=\"${3|true,false|}\"></el-image>",  
                 "${4}"  
             ],  
             "description": "Element UI <el-image>"  
         },  

         "Others: Backtop": {  
             "prefix": "elback",  
             "body": [  
                 "<el-backtop :target=\"${1}\" :right=\"${2:40}\" :bottom=\"${3:40}\">$4</el-backtop>",  
                 "${5}"  
             ],  
             "description": "Element UI <el-backtop>"  
         },  

         "Others: InfiniteScroll": {  
             "prefix": "elinfi",  
             "body": [  
                 "v-infinite-scroll=\"${1}\"",  
                 ":infinite-scroll-delay=\"${2}\"",  
                 ":infinite-scroll-distance=\"${3}\"",  
                 ":infinite-scroll-disabled=\"${4|false,true|}\"",  
                 ":infinite-scroll-immediate=\"${5|true,false|}\""  
             ],  
             "description": "Element UI v-infinite-scroll"  
         },  
         "Others: Drawer": {  
             "prefix": "eldra",  
             "body": [  
                 "<el-drawer title=\"${1}\" :visible.sync=\"${2}\" direction=\"${3|rtl,ltr,ttb,btt|}\" size=\"${4:30%}\"",  
                     "\t:before-close=\"${5}\" :destroy-on-close=\"${6|true,false|}\" :show-close=\"${7|true,false|}\" :wrapperClosable=\"${8|true,false|}\">",  
                 "</el-drawer>",  
                 "${9}"  
             ],  
             "description": "Element UI <el-drawer>"  
         },  
//自己编写  
         "table-column-slot": {  
             "prefix": "elss",  
             "body": [  
                 "<template slot-scope=\"scope\">",  
                 "\t${1}",  
                 "</template>",  
                 "${0}"  
             ],  
             "description": "template slot-scope"  
         }  

    //elementui提示结束  
}  
收起阅读 »

html5+项目启动卡在正在同步手机端程序文件...

HTML5+

可能项目比较大,50m,启动一直卡在正在同步手机端程序文件,切换了几个版本无效,去官方群询问后得知‘如果你的iOS设备是15以下的系统,可以考虑降到3.3.13来真机运行,如果你是iOS15以上的设备,目前只能使用Mac来运行’的回答,今天尝试一下,去拿一个版本第一点的平板试一下。uniapp没遇到这类问题

继续阅读 »

可能项目比较大,50m,启动一直卡在正在同步手机端程序文件,切换了几个版本无效,去官方群询问后得知‘如果你的iOS设备是15以下的系统,可以考虑降到3.3.13来真机运行,如果你是iOS15以上的设备,目前只能使用Mac来运行’的回答,今天尝试一下,去拿一个版本第一点的平板试一下。uniapp没遇到这类问题

收起阅读 »

【 升级中心 uni-upgrade-center - Admin - DCloud前端团队 】打包h5后准备在自己的网站打开。登录账号提示[uni-id-cf]: request:fail

云函数跨域配置
但是还回报错[uni-id-cf]: request:fail
答案搜索,会出现。
> 用你自己的域名 绑定 bspapp.com 默认域名,配完跨域 用自己的域名登录 就不会有 [uni-id-cf]: request:fail 报错了。前面的条件缺一不可

bspapp.com为。

所以只有阿里云的云函数才可以这样解决,腾讯云。我没看,一般人也不用

继续阅读 »

云函数跨域配置
但是还回报错[uni-id-cf]: request:fail
答案搜索,会出现。
> 用你自己的域名 绑定 bspapp.com 默认域名,配完跨域 用自己的域名登录 就不会有 [uni-id-cf]: request:fail 报错了。前面的条件缺一不可

bspapp.com为。

所以只有阿里云的云函数才可以这样解决,腾讯云。我没看,一般人也不用

收起阅读 »

升级OAID SDK版本崩溃的野路子解决方案

SDK

先吐槽一下,现在都已经2202了,最新的版本中 OAID还是用的 1.0.25 的版本, 那是2-3年前的版本了,对机型适配只有少量的支持,重点是可能不支持最新的Android13

现在最新的OAID SDK版本 1.2.0

遇到的问题,

升级之后直接崩溃,崩溃信息

根据崩溃信息,看到了源码当中有这样的一句话

所以结局崩溃的核心就是 "DeviceInfo.oaids" 这个变量了,

解决方案:

在你的Application 的 onCreate方法中,加入DeviceInfo.oaids="1|1|1"

需要注意:

一: 因为Uni 启动时,会新开启一个线程,所以 DeviceInfo.oaids="1|1|1" 这句话不是随便在哪里加都行的.
推荐是在加在Application 的 onCreate方法中.
二: 如果业务中有用到OAID的,还需要在合适的地方,把正确的 OAID 设置给 DeviceInfo.oaids
如果没有用到OAID的就可以不用管. 甚至可以删除 oaid_sdk_1.0.25.aar (老版本的名称) 或 base_oaid_sdk.aar (新版本的名称)

附上 OAID SDK 升级版本说明,自行评估是否需要更新

最后,希望 Uni 的管理者看到这个文章,把 Uni里面的SDK做个优化, 将OAID sdk不要作为必须的依赖, 或者提供自定义OAID版本方案.

继续阅读 »

先吐槽一下,现在都已经2202了,最新的版本中 OAID还是用的 1.0.25 的版本, 那是2-3年前的版本了,对机型适配只有少量的支持,重点是可能不支持最新的Android13

现在最新的OAID SDK版本 1.2.0

遇到的问题,

升级之后直接崩溃,崩溃信息

根据崩溃信息,看到了源码当中有这样的一句话

所以结局崩溃的核心就是 "DeviceInfo.oaids" 这个变量了,

解决方案:

在你的Application 的 onCreate方法中,加入DeviceInfo.oaids="1|1|1"

需要注意:

一: 因为Uni 启动时,会新开启一个线程,所以 DeviceInfo.oaids="1|1|1" 这句话不是随便在哪里加都行的.
推荐是在加在Application 的 onCreate方法中.
二: 如果业务中有用到OAID的,还需要在合适的地方,把正确的 OAID 设置给 DeviceInfo.oaids
如果没有用到OAID的就可以不用管. 甚至可以删除 oaid_sdk_1.0.25.aar (老版本的名称) 或 base_oaid_sdk.aar (新版本的名称)

附上 OAID SDK 升级版本说明,自行评估是否需要更新

最后,希望 Uni 的管理者看到这个文章,把 Uni里面的SDK做个优化, 将OAID sdk不要作为必须的依赖, 或者提供自定义OAID版本方案.

收起阅读 »

ios 快速解决机审4.3

ios 快速解决机审4.3

无非就是绕过机审,无需大量修改源码。。。

更多咨询QQ:543610866

ios 快速解决机审4.3

无非就是绕过机审,无需大量修改源码。。。

更多咨询QQ:543610866

uni-app 大型项目模版,仅供学习

uni-app 大型项目模版,仅供学习

商城类,新闻类等等。。。

有偿提供源码,QQ:543610866

uni-app 大型项目模版,仅供学习

商城类,新闻类等等。。。

有偿提供源码,QQ:543610866

餐饮点餐小程序源码|点餐小程序源代码

微信小程序

  餐饮点餐小程序是一个使用 PHP/MySQL 的简单项目。该项目是使用 HTML、CSS、PHP、JavaScript (jQuery/Ajax) 和 Bootstrap 开发的。使用 PHP 和 MySQL的餐饮点餐小程序具有管理端和访问者/客户端。管理员将管理网站所需的所有数据和可用菜单列表。客户将浏览网站,探索并选择他/她想要的菜单并将其从购物车中保存以供以后结帐。之后,客户将进入购物车,查看他/她的订单,确认收货地址等信息,然后下订单。这是一个易于使用的项目。

  项目名称:餐饮点餐小程序

  演示:c.ymzan.top

  语言:PHP

  使用的数据库:MySQL

  使用的设计:HTML JavaScript、Ajax、JQuery、Bootstrap

  使用的浏览器: IE8、谷歌浏览器、Opera Mozilla

  使用的软件:WAMP/ XAMPP/ LAMP/MAMP

  最重要的是,要运行这个项目,您必须在您的 PC 上安装一个虚拟服务器,即XAMPP 。在 XAMPP 中启动 Apache 和 MySQL 之后按照以下步骤操作:

  第一步:首先,提取文件

  第二步:之后,复制主项目文件夹

  第三步:所以,你需要粘贴到 xampp/htdocs/

  此外,现在连接数据库

  第 4 步:所以,现在,打开浏览器并转到 URL “http://localhost/phpmyadmin/”

  第 5 步:之后,单击数据库选项卡

  第 6 步:创建一个名为“fos_db”的数据库,然后单击导入选项卡

  第七步:当然,单击浏览文件并选择“ fos_db. sql ”文件,位于“db”文件夹中

  第八步:同时,点击 Go 按钮。

  创建数据库后,

  第九步:此外,打开浏览器并转到 URL “http://localhost/fos”

  package.json

middleware.js   
// ======= GoReplay Middleware helper =============  
// Created by Leonid Bugaev in 2017  
//  
// For questions use GitHub or support@goreplay.org  
//  
// GoReplay: https://github.com/buger/goreplay  
// Middleware package: https://github.com/buger/goreplay/middleware  

var middleware;  

function init() {  
    var proxy = {  
        ch: {},  
        on: function(chan, id, cb) {  
            if (!cb && id) {  
                cb = id;  
            } else if (cb && id) {  
                chan = chan + "#" + id;  
            }  

            if (!proxy.ch[chan]) {  
                proxy.ch[chan] = [];  
            }  

            proxy.ch[chan].push({  
                created: new Date(),  
                cb: cb  
            });  

            return proxy;  
        },  

        emit: function(msg, raw) {  
            var chanPrefix;  

            switch(msg.type) {  
                case "1": chanPrefix = "request"; break;  
                case "2": chanPrefix = "response"; break;  
                case "3": chanPrefix = "replay"; break;  
            }  

            let resp = msg;  

            ["message", chanPrefix, chanPrefix + "#" + msg.ID].forEach(function(chanID, idx){  
                if (proxy.ch[chanID]) {  
                    proxy.ch[chanID].forEach(function(ch){  
                        let r = ch.cb(msg);  
                        if (resp) resp = r; // If one of callback decided not to send response back, do not override it in global callbacks  
                    })  

                    // Cleanup Individual message channels to avoid memory leaks  
                    if (idx == 2) {  
                        delete proxy.ch[chanID]  
                    }  
                }  
            })  

            if (resp) {  
              process.stdout.write(`${resp.rawMeta.toString('hex')}${Buffer.from("\n").toString("hex")}${resp.http.toString('hex')}\n`)  
            }  

            return resp  
        }  
    }  

    // Clean up old messaged ID specific channels if they are older then 60s  
    let gc = function(gcTime){  
        let now = new Date();  
        for (k in proxy.ch) {  
            if (k.indexOf("#") == -1) continue;  

            proxy.ch[k] = proxy.ch[k].filter(function(ch){  
                return (now - ch.created) < gcTime  
            })  

            if (proxy.ch[k].length == 0) {  
                delete proxy.ch[k]  
            }  
        }  
    }  
    proxy.gc = gc  

    setInterval(function(){  
        gc(10 * 1000)  
    }, 1000);  

    const readline = require('readline');  
    const rl = readline.createInterface({  
          input: process.stdin  
    });  

    rl.on('line', function(line) {  
        let msg = parseMessage(line)  
        if (msg) {  
            proxy.emit(msg, line)  
        }  
    });  

    middleware = proxy;  

    return proxy;  
}  

function parseMessage(msg) {  
    try {  
        let payload = Buffer.from(msg, "hex");  
        let metaPos = payload.indexOf("\n");  
        let meta = payload.slice(0, metaPos);  
        let metaArr = meta.toString("ascii").split(" ");  
        let pType = metaArr[0];  
        let pID = metaArr[1];  
        let raw = payload.slice(metaPos + 1, payload.length);  

        return {  
            type: pType,  
            ID: pID,  
            rawMeta: meta,  
            meta: metaArr,  
            http: raw  
        }  
    } catch(e) {  
        fail(`Error while parsing incoming request: ${msg}`)  
    }  
}  

// Used to compare values from original and replayed responses  
// Accepts request id, regexp pattern for searching the compared value (should include capture group), and callback which returns both original and replayed matched value.  
// Example:   
//  
//   // Compare HTTP headers for response and replayed response, and map values  
//   let tokMap = {};  
//  
//   gor.on("request", function(req) {  
//     let tok = gor.httpHeader(req.http, "Auth-Token");  
//     if (tok && tokMap[tok]) {  
//       req.http = gor.setHttpHeader(req.http, "Auth-Token", tokMap[tok])   
//     }  
//  
//     gor.searchResponses(req.ID, "X-Set-Token: (\w+)$", function(respTok, replTok) {  
//       tokMap[respTok] = replTok;  
//     })  
//  
//     return req;  
//   })  
//  
function searchResponses(id, searchPattern, callback) {  
    let re = new RegExp(searchPattern);  

    // Using regexp require converting buffer to string  
    // Before converting to string we can use initial `Buffer.indexOf` check  
    let indexPattern = searchPattern.split("(")[0];  

    if (!indexPattern) {  
        console.error("Search regexp should include capture group, pointing to the value: `prefix-(.*)`")  
        return  
    }  

    middleware.on("response", id, function(resp){  
        if (resp.http.indexOf(indexPattern) == -1) {  
            callback()  
            return resp  
        }  

        let respMatch = resp.http.toString('utf-8').match(re);  
        if (!respMatch) {  
            callback()  
            return resp  
        }  

        middleware.on("replay", id, function(repl) {  
            if (repl.http.indexOf(indexPattern) == -1) {  
                callback(respMatch[1]);  
                return repl;  
            }  

            let replMatch = repl.http.toString('utf-8').match(re);  

            if (!replMatch) {  
                callback(respMatch[1]);  
                return repl;  
            }  

            callback(respMatch[1], replMatch[1]);  

            return repl;  
        })  

        return resp;  
    })  
}  

// =========== HTTP parsing =================  

// Example HTTP payload record (including hidden characters):  
//  
//  POST / HTTP/1.1\r\n  
//  User-Agent: Node\r\n  
//  Content-Length: 5\r\n  
//  \r\n  
//  hello  

function httpMethod(payload) {  
    var pEnd = payload.indexOf(' ');  
    return payload.slice(0, pEnd).toString("ascii");  
}  

function httpPath(payload) {  
    var pStart = payload.indexOf(' ') + 1;  
    var pEnd = payload.indexOf(' ', pStart);  
    return payload.slice(pStart, pEnd).toString("ascii");  
}  

function setHttpPath(payload, newPath) {  
    var pStart = payload.indexOf(' ') + 1;  
    var pEnd = payload.indexOf(' ', pStart);  

    return Buffer.concat([payload.slice(0, pStart), Buffer.from(newPath), payload.slice(pEnd, payload.length)])  
}  

function httpPathParam(payload, name) {  
    let path = httpPath(payload);  
    let re = new RegExp(name + "=([^&$]+)");  
    let match = path.match(re);  

    if (match) return decodeURI(match[1]);  
}  

function setHttpPathParam(payload, name, value) {  
    let path = httpPath(payload);  
    let re = new RegExp(name + "=([^&$]+)");  
    let newPath = path.replace(re, name + "=" + encodeURI(value));  

    // If we should add new param instead  
    if (newPath == path) {  
        if (newPath.indexOf("?") == -1) {  
            newPath += "?"  
        } else {  
            newPath += "&"  
        }  

        newPath += name + "=" + encodeURI(value);  
    }  

    return setHttpPath(payload, newPath)  
}  

// HTTP response have status code in same position as `path` for requests  
function httpStatus(payload) {  
    return httpPath(payload);  
}  

function setHttpStatus(payload, newStatus) {  
    return setHttpPath(payload, newStatus);  
}  

function httpHeaders(payload) {  
    var httpHeaderString = payload.slice(0,payload.indexOf("\r\n\r\n") + 4).toString().split("\n").slice(1);  
    var headers = {};  

    for (var item in httpHeaderString) {  
        var parts = httpHeaderString[item].split(":");  

        if (parts.length > 1) {  
            headers[parts[0]] = parts.slice(1).join(":").trim();      
        }  
    }  

    return headers;  
}  

function httpHeader(payload, name) {  
    var currentLine = 0;  
    var i = 0;  
    var header = { start: -1, end: -1, valueStart: -1 }  
    var nameBuf = Buffer.from(name);  
    var nameBufLower = Buffer.from(name.toLowerCase());  

    while(c = payload[i]) {  
        if (c == 13) { // new line "\n"  
            currentLine++;  
            i++  
            header.end = i  

            if (currentLine > 0 && header.start > 0 && header.valueStart > 0) {  
                if (nameBuf.compare(payload, header.start, header.valueStart - 1) == 0 ||  
                    nameBufLower.compare(payload, header.start, header.valueStart - 1) == 0) { // ensure that headers are not case sensitive  
                    header.value = payload.slice(header.valueStart, header.end - 1).toString("utf-8").trim();  
                    header.name = payload.slice(header.start, header.valueStart - 1).toString("utf-8");  
                    return header  
                }  
            }  

            header.start = -1  
            header.valueStart = -1  
            continue;  
        } else if (c == 10) { // "\r"  
            i++  
            continue;  
        } else if (c == 58) { // ":" Header/value separator symbol  
            if (header.valueStart == -1) {  
                header.valueStart = i + 1;  
                i++  
                continue;  
            }  
        }  

        if (header.start == -1) header.start = i;  

        i++  
    }  

    return  
}  

function setHttpHeader(payload, name, value) {  
    let header = httpHeader(payload, name);  
    if (!header) {  
        let headerStart = payload.indexOf(13) + 1;  
        return Buffer.concat([payload.slice(0, headerStart + 1), Buffer.from(name + ": " + value + "\r\n"), payload.slice(headerStart + 1, payload.length)])  
    } else {  
        return Buffer.concat([payload.slice(0, header.valueStart), Buffer.from(" " + value + "\r\n"), payload.slice(header.end + 1, payload.length)])  
    }  
}  

function deleteHttpHeader(payload, name) {  
    let header = httpHeader(payload, name);  

    if (header) {  
        return Buffer.concat([payload.slice(0, header.start), payload.slice(header.end+1, payload.length)])  
    }  

    return payload  
}  

function httpBody(payload) {  
    let bodyIndex = payload.indexOf("\r\n\r\n");  
    if (-1 != bodyIndex){  
        return payload.slice(bodyIndex + 4, payload.length);     
    } else {  
        return null;  
    }  
}  

function setHttpBody(payload, newBody) {  
    let p = setHttpHeader(payload, "Content-Length", newBody.length)  
    let headerEnd = p.indexOf("\r\n\r\n") + 4;  
    return Buffer.concat([p.slice(0, headerEnd), newBody])  
}  

function httpBodyParam(payload, name) {  
    let body = httpBody(payload);  
    let re = new RegExp(name + "=([^&$]+)");  
    if (body.indexOf(name + "=") != -1) {  
        let param = body.toString('utf-8').match(re);  
        if (param) {  
            return decodeURI(param[1]);  
        }  
    }  
}  

function setHttpBodyParam(payload, name, value) {  
    let body = httpBody(payload);  
    let re = new RegExp(name + "=([^&$]+)");  

    let newBody = body.toString('utf-8');  

    if (newBody.indexOf(name + "=") != -1 ) {  
        newBody = newBody.replace(re, name + "=" + encodeURI(value));  
    } else {  
        if (newBody.indexOf("=") != -1) {  
            newBody += "&";  
        }  
        newBody += name + "=" + value;  
    }  

    return setHttpBody(payload, Buffer.from(newBody));  
}  

function setHttpCookie(payload, name, value) {  
    let h = httpHeader(payload, "Cookie");  
    let cookie = h ? h.value : "";  
    let cookies = cookie.split("; ").filter(function(v){ return v.indexOf(name + "=") != 0 })  
    cookies.push(name + "=" + value)  
    return setHttpHeader(payload, "Cookie", cookies.join("; "))  
}  

function deleteHttpCookie(payload, name) {  
    let h = httpHeader(payload, "Cookie");  
    let cookie = h ? h.value : "";  
    let cookies = cookie.split("; ").filter(function(v){ return v.indexOf(name + "=") != 0 })  
    return setHttpHeader(payload, "Cookie", cookies.join("; "))  
}  

function httpCookie(payload, name) {  
    let h = httpHeader(payload, "Cookie");  
    let cookie = h ? h.value : "";  
    let value;  
    let cookies = cookie.split("; ").forEach(function(v){  
        if (v.indexOf(name + "=") == 0) {  
            value = v.substr(name.length + 1);  
        }  
    })  
    return value;  
}  

module.exports = {  
    init: init,  
    on: function(){ return middleware.on.apply(this, arguments) },  
    parseMessage: parseMessage,  
    searchResponses: searchResponses,  
    httpPath: httpPath,  
    httpMethod: httpMethod,  
    setHttpPath: setHttpPath,  
    httpPathParam: httpPathParam,  
    setHttpPathParam: setHttpPathParam,  
    httpStatus: httpStatus,  
    setHttpStatus: setHttpStatus,  
    httpHeader: httpHeader,  
    setHttpHeader: setHttpHeader,  
    deleteHttpHeader: deleteHttpHeader,  
    httpBody: httpBody,  
    setHttpBody: setHttpBody,  
    httpBodyParam: httpBodyParam,  
    setHttpBodyParam: setHttpBodyParam,  
    httpCookie: httpCookie,  
    setHttpCookie: setHttpCookie,  
    deleteHttpCookie: deleteHttpCookie,  
    test: testRunner,  
    benchmark: testBenchmark,  
    httpHeaders: httpHeaders  
}  

// =========== Tests ==============  

function testRunner(){  
    ["init", "filter", "parseMessage", "httpMethod", "httpPath", "setHttpHeader", "deleteHttpHeader", "httpPathParam", "httpHeader", "httpBody", "setHttpBody", "httpBodyParam", "httpCookie", "setHttpCookie", "deleteHttpCookie", "httpHeaders"].forEach(function(t){  
        console.log(`====== Start ${t} =======`)  
        eval(`TEST_${t}()`)  
        console.log(`====== End ${t} =======`)  
    })  
}  

function testBenchmark(){  
    const child_process = require('child_process');  

    let gor = init();  
    gor.on("message", function(){  
    });  

    gor.on("request", function(){  
    });  

    for (var i = 0; i<256; i++) {  
        let req = parseMessage(Buffer.from("1 2 3\nGET / HTTP/1.1\r\n\r\n").toString('hex'));  
        req.ID = +Date.now()  
        gor.emit(req);  

        gor.on("request", req.ID+"", function(){  
            gor.on("response", req.ID+"", function(){  
            })  
        })  

        if ( i % 3 == 0 ) {  
            let resp = parseMessage(Buffer.from("2 2 3\nHTTP/1.1 200 OK\r\n\r\n").toString('hex'));  
            resp.ID = req.ID  
            gor.emit(resp);  
        }  
    }  

    child_process.execSync("sleep 0.01");  

    gor.gc(1)   

    fail(JSON.stringify(gor.ch))  
}  

// Just print in red color  
function fail(message) {  
    console.error("\x1b[31m[MIDDLEWARE] %s\x1b[0m", message)  
}  

function log(message) {  
    console.error(message)  
}  

function TEST_init() {  
    const child_process = require('child_process');  

    let received = 0;  
    let gor = init();  
    gor.on("message", function(){  
        received++; // should be called 3 times for for every request  
    });  

    gor.on("request", function(){  
        received++; // should be called 1 time only for request  
    });  

    gor.on("response", "2", function(){  
        received++; // should be called 1 time only for specific response  
    })  

    if (Object.keys(gor.ch).length != 3) {  
        return fail("Should create 3 channels");  
    }  

    let req = parseMessage(Buffer.from("1 2 3\nGET / HTTP/1.1\r\n\r\n").toString('hex'));  
    let resp = parseMessage(Buffer.from("2 2 3\nHTTP/1.1 200 OK\r\n\r\n").toString('hex'));  
    let resp2 = parseMessage(Buffer.from("2 3 3\nHTTP/1.1 200 OK\r\n\r\n").toString('hex'));  

    gor.emit(req);  
    gor.emit(resp);  
    gor.emit(resp2);  

    child_process.execSync("sleep 0.01");  

    if (received != 5) {  
        fail(`Should receive 5 messages: ${received}`);  
    }  
}  

function TEST_filter() {  
    const child_process = require('child_process');  

    let gor = init();  
    gor.on("request", function(req){  
        if (httpPath(req.http) != "/filter") {  
            return req  
        }  
    });  

    gor.on("request", function(req){  
        return req  
    });  

    let reqPass = parseMessage(Buffer.from("1 2 3\nGET / HTTP/1.1\r\n\r\n").toString('hex'));  
    let reqFilter = parseMessage(Buffer.from("1 2 3\nGET /filter HTTP/1.1\r\n\r\n").toString('hex'));  

    if (!gor.emit(reqPass)) {  
        return fail("Should not filter request")  
    }  

    if (gor.emit(reqFilter)) {  
        return fail("Should filter request even if one middleware rejected it")  
    }  

}  

function TEST_parseMessage() {  
    const exampleMessage = Buffer.from("1 2 3\nGET / HTTP/1.1\r\n\r\n").toString('hex')  
    let msg = parseMessage(exampleMessage)  
    let expected = { type: '1', ID: '2', meta: ["1", "2", "3"], http: Buffer.from("GET / HTTP/1.1\r\n\r\n") }  

    Object.keys(expected).forEach(function(k){  
        if (msg[k].toString() != expected[k].toString()) {  
            fail(`${k}: '${expected[k]}' != '${msg[k]}'`)  
        }  
    })  
}  

function TEST_httpPath() {  
    const examplePayload = "GET /test HTTP/1.1\r\n\r\n";  

    let payload = Buffer.from(examplePayload);  
    let path = httpPath(payload);  

    if (path != "/test") {  
        return fail(`Path '${patj}' != '/test'`)  
    }  

    let newPayload = setHttpPath(payload, '/')  
    if (newPayload.toString() != "GET / HTTP/1.1\r\n\r\n") {  
        return fail(`Malformed payload '${newPayload}'`)  
    }  

    newPayload = setHttpPath(payload, '/bigger')  
    if (newPayload.toString() != "GET /bigger HTTP/1.1\r\n\r\n") {  
        return fail(`Malformed payload '${newPayload}'`)  
    }  
}  

function TEST_httpMethod() {  
    const examplePayload = "GET /test HTTP/1.1\r\n\r\n";  

    let payload = Buffer.from(examplePayload);  
    let method = httpMethod(payload);  

    if (method != "GET") {  
        return fail(`Path '${method}' != 'GET'`)  
    }  
}  

function TEST_httpPathParam() {  
    let p = Buffer.from("GET / HTTP/1.1\r\n\r\n");  

    if (httpPathParam(p, "test")) {  
        return fail("Should not found param")  
    }  

    p = setHttpPathParam(p, "test", "123");  
    if (httpPath(p) != "/?test=123") {  
        return fail("Should set first param: " + httpPath(p));  
    }  

    if (httpPathParam(p, "test") != "123") {  
        return fail("Should get first param: " + httpPathParam(p, "test"));  
    }  

    p = setHttpPathParam(p, "qwer", "ty");  
    if (httpPath(p) != "/?test=123&qwer=ty") {  
        return fail("Should set second param: " + httpPath(p));  
    }  

    p = setHttpPathParam(p, "test", "4321");  
    if (httpPath(p) != "/?test=4321&qwer=ty") {  
        return fail("Should update first param: " + httpPath(p));  
    }  

    if (httpPathParam(p, "test") != "4321") {  
        return fail("Should update first param: " + httpPath(p));  
    }  
}  

function TEST_httpBodyParam() {  
    let p = Buffer.from("POST / HTTP/1.1\r\n\r\n");  

    if (httpBodyParam(p, "test")) {  
        return fail("Should not found param")  
    }  

    p = setHttpBodyParam(p, "test", "123");  
    if (httpBody(p).toString() != "test=123") {  
        return fail("Should set first param: " + httpBody(p).toString());  
    }  

    if (httpBodyParam(p, "test") != "123") {  
        return fail("Should get first param: " + httpBodyParam(p, "test"));  
    }  

    p = setHttpBodyParam(p, "qwer", "ty");  
    if (httpBody(p).toString() != "test=123&qwer=ty") {  
        return fail("Should set second param: " + httpBody(p).toString());  
    }  

    p = setHttpBodyParam(p, "test", "4321");  
    if (httpBody(p).toString() != "test=4321&qwer=ty") {  
        return fail("Should update first param: " + httpBody(p).toString());  
    }  

    if (httpBodyParam(p, "test") != "4321") {  
        return fail("Should update first param: " + httpBody(p).toString());  
    }  
}  

function TEST_httpHeader() {  
    const examplePayload = "GET / HTTP/1.1\r\nHost: localhost:3000\r\nUser-Agent: Node\r\nContent-Length:5\r\n\r\nhello";  

    let expected = {"Host": "localhost:3000", "User-Agent": "Node", "Content-Length": "5"}  

    Object.keys(expected).forEach(function(name){  
        let payload = Buffer.from(examplePayload);  
        let header = httpHeader(payload, name);  
        if (!header) {  
            fail(`Header not found. Was looking for: ${name}`)  
        }  
        if (header && header.value != expected[name]) {  
            fail(`${name}: '${expected[name]}' != '${header.value}'`)  
        }  
    })  
}  

function TEST_setHttpHeader() {  
    const examplePayload = "GET / HTTP/1.1\r\nUser-Agent: Node\r\nContent-Length: 5\r\n\r\nhello";  

    // Modify existing header  
    ["", "1", "Long test header"].forEach(function(ua){  
        let expected = `GET / HTTP/1.1\r\nUser-Agent: ${ua}\r\nContent-Length: 5\r\n\r\nhello`;  
        let p = Buffer.from(examplePayload);  
        p = setHttpHeader(p, "User-Agent", ua);  
        if (p != expected) {  
            console.error(`setHeader failed, expected User-Agent value: ${ua}.\n${p}`)  
        }  
    })  

    // Adding new header  
    let expected = `GET / HTTP/1.1\r\nX-Test: test\r\nUser-Agent: Node\r\nContent-Length: 5\r\n\r\nhello`;  
    let p = Buffer.from(examplePayload);  
    p = setHttpHeader(p, "X-Test", "test");  
    if (p != expected) {  
        console.error(`setHeader failed, expected new header 'X-Test' header: ${p}`)  
    }  
}  

function TEST_deleteHttpHeader() {  
    const examplePayload = "GET / HTTP/1.1\r\nUser-Agent: Node\r\nContent-Length: 5\r\n\r\nhello";  

    // Adding new header  
    let expected = `GET / HTTP/1.1\r\nContent-Length: 5\r\n\r\nhello`;  
    let p = Buffer.from(examplePayload);  
    p = deleteHttpHeader(p, "User-Agent", "test");  
    if (p != expected) {  
        console.error(`setHeader failed, expected delete header 'User-Agent' header: ${p}`)  
    }  
}  

function TEST_httpBody() {  
    const examplePayload = "GET / HTTP/1.1\r\nUser-Agent: Node\r\nContent-Length: 5\r\n\r\nhello";  
    let body = httpBody(Buffer.from(examplePayload));  
    if (body != "hello") {  
        fail(`'${body}' != 'hello'`)  
    }  

    const exampleInvalidPayload = "Invalid HTTP Response by Network issue";  
    let invalidBody = httpBody(Buffer.from(exampleInvalidPayload));  
    if (invalidBody != null) {  
        fail(`'${invalidBody}' != 'null'`)  
    }  
}  

function TEST_setHttpBody() {  
    const examplePayload = "GET / HTTP/1.1\r\nUser-Agent: Node\r\nContent-Length: 5\r\n\r\nhello";  
    let p = setHttpBody(Buffer.from(examplePayload), Buffer.from("hello, world!"));  

    if (p != "GET / HTTP/1.1\r\nUser-Agent: Node\r\nContent-Length: 13\r\n\r\nhello, world!") {  
        fail(`Wrong body: '${p}'`)  
    }  
}  

function TEST_httpCookie() {  
    const examplePayload = "GET / HTTP/1.1\r\nCookie: a=b; test=zxc\r\n\r\n";  
    let c = httpCookie(Buffer.from(examplePayload), "test");  
    if (c != "zxc") {  
        return fail(`Should get cookie: ${c}`);  
    }  

    c = httpCookie(Buffer.from(examplePayload), "nope");  
    if (c != null) {  
        return fail(`Should not find cookie: ${c}`);  
    }  
}  

function TEST_setHttpCookie() {  
    const examplePayload = "GET / HTTP/1.1\r\nCookie: a=b; test=zxc\r\n\r\n";  
    let p = setHttpCookie(Buffer.from(examplePayload), "test", "1");  
    if (p != "GET / HTTP/1.1\r\nCookie: a=b; test=1\r\n\r\n") {  
        return fail(`Should update cookie: ${p}`)  
    }  

    p = setHttpCookie(Buffer.from(examplePayload), "new", "one");  
    if (p != "GET / HTTP/1.1\r\nCookie: a=b; test=zxc; new=one\r\n\r\n") {  
        return fail(`Should add new cookie: ${p}`)  
    }  
}  

function TEST_deleteHttpCookie() {  
    const examplePayload = "GET / HTTP/1.1\r\nCookie: a=b; test=zxc\r\n\r\n";  
    let p = deleteHttpCookie(Buffer.from(examplePayload), "a");  
    if (p != "GET / HTTP/1.1\r\nCookie: test=zxc\r\n\r\n") {  
        return fail(`Should delete cookie: ${p}`)  
    }  
}  

function TEST_httpHeaders() {  
    const examplePayload = "GET / HTTP/1.1\r\nHost: localhost:3000\r\nUser-Agent: Node\r\nContent-Length:5\r\n\r\nhello";  

    let expectedHeaders = {"Host": "localhost:3000", "User-Agent": "Node", "Content-Length": "5"}  
    let payload = Buffer.from(examplePayload);  
    let headers = httpHeaders(payload);  

    ["Host", "User-Agent", "Content-Length"].forEach(function(header){  
        let actual = headers[header];  
        let expected = expectedHeaders[header];  

        if (!actual) {  
            fail(`${header} Header was not found`);  
        }  

        if (actual != expected) {  
            fail(`${header} Header not Equal to Expected: ${expected} was ${actual}`);  
        }  

    })  
}  

 
  餐饮点餐小程序的特点

  管理员端

  登录页面

  管理员将输入其凭据以访问系统管理员端的页面。

  类别页面

  列出所有产品/菜单类别并由管理员管理的页面。

  菜单页

  列出产品/菜单并可由管理员管理的页面。

  系统设置

  管理员配置网站数据的页面。

  客户端

  主页

  默认情况下将重定向客户端的页面,并且可以选择他/她想要的菜单。

  购物车页面

  列出正在保存购物车的菜单/产品列表的页面。

  关于页面

  显示咖啡厅或餐厅内容的页面。

  结帐页面

  客户下订单的页面。

继续阅读 »

  餐饮点餐小程序是一个使用 PHP/MySQL 的简单项目。该项目是使用 HTML、CSS、PHP、JavaScript (jQuery/Ajax) 和 Bootstrap 开发的。使用 PHP 和 MySQL的餐饮点餐小程序具有管理端和访问者/客户端。管理员将管理网站所需的所有数据和可用菜单列表。客户将浏览网站,探索并选择他/她想要的菜单并将其从购物车中保存以供以后结帐。之后,客户将进入购物车,查看他/她的订单,确认收货地址等信息,然后下订单。这是一个易于使用的项目。

  项目名称:餐饮点餐小程序

  演示:c.ymzan.top

  语言:PHP

  使用的数据库:MySQL

  使用的设计:HTML JavaScript、Ajax、JQuery、Bootstrap

  使用的浏览器: IE8、谷歌浏览器、Opera Mozilla

  使用的软件:WAMP/ XAMPP/ LAMP/MAMP

  最重要的是,要运行这个项目,您必须在您的 PC 上安装一个虚拟服务器,即XAMPP 。在 XAMPP 中启动 Apache 和 MySQL 之后按照以下步骤操作:

  第一步:首先,提取文件

  第二步:之后,复制主项目文件夹

  第三步:所以,你需要粘贴到 xampp/htdocs/

  此外,现在连接数据库

  第 4 步:所以,现在,打开浏览器并转到 URL “http://localhost/phpmyadmin/”

  第 5 步:之后,单击数据库选项卡

  第 6 步:创建一个名为“fos_db”的数据库,然后单击导入选项卡

  第七步:当然,单击浏览文件并选择“ fos_db. sql ”文件,位于“db”文件夹中

  第八步:同时,点击 Go 按钮。

  创建数据库后,

  第九步:此外,打开浏览器并转到 URL “http://localhost/fos”

  package.json

middleware.js   
// ======= GoReplay Middleware helper =============  
// Created by Leonid Bugaev in 2017  
//  
// For questions use GitHub or support@goreplay.org  
//  
// GoReplay: https://github.com/buger/goreplay  
// Middleware package: https://github.com/buger/goreplay/middleware  

var middleware;  

function init() {  
    var proxy = {  
        ch: {},  
        on: function(chan, id, cb) {  
            if (!cb && id) {  
                cb = id;  
            } else if (cb && id) {  
                chan = chan + "#" + id;  
            }  

            if (!proxy.ch[chan]) {  
                proxy.ch[chan] = [];  
            }  

            proxy.ch[chan].push({  
                created: new Date(),  
                cb: cb  
            });  

            return proxy;  
        },  

        emit: function(msg, raw) {  
            var chanPrefix;  

            switch(msg.type) {  
                case "1": chanPrefix = "request"; break;  
                case "2": chanPrefix = "response"; break;  
                case "3": chanPrefix = "replay"; break;  
            }  

            let resp = msg;  

            ["message", chanPrefix, chanPrefix + "#" + msg.ID].forEach(function(chanID, idx){  
                if (proxy.ch[chanID]) {  
                    proxy.ch[chanID].forEach(function(ch){  
                        let r = ch.cb(msg);  
                        if (resp) resp = r; // If one of callback decided not to send response back, do not override it in global callbacks  
                    })  

                    // Cleanup Individual message channels to avoid memory leaks  
                    if (idx == 2) {  
                        delete proxy.ch[chanID]  
                    }  
                }  
            })  

            if (resp) {  
              process.stdout.write(`${resp.rawMeta.toString('hex')}${Buffer.from("\n").toString("hex")}${resp.http.toString('hex')}\n`)  
            }  

            return resp  
        }  
    }  

    // Clean up old messaged ID specific channels if they are older then 60s  
    let gc = function(gcTime){  
        let now = new Date();  
        for (k in proxy.ch) {  
            if (k.indexOf("#") == -1) continue;  

            proxy.ch[k] = proxy.ch[k].filter(function(ch){  
                return (now - ch.created) < gcTime  
            })  

            if (proxy.ch[k].length == 0) {  
                delete proxy.ch[k]  
            }  
        }  
    }  
    proxy.gc = gc  

    setInterval(function(){  
        gc(10 * 1000)  
    }, 1000);  

    const readline = require('readline');  
    const rl = readline.createInterface({  
          input: process.stdin  
    });  

    rl.on('line', function(line) {  
        let msg = parseMessage(line)  
        if (msg) {  
            proxy.emit(msg, line)  
        }  
    });  

    middleware = proxy;  

    return proxy;  
}  

function parseMessage(msg) {  
    try {  
        let payload = Buffer.from(msg, "hex");  
        let metaPos = payload.indexOf("\n");  
        let meta = payload.slice(0, metaPos);  
        let metaArr = meta.toString("ascii").split(" ");  
        let pType = metaArr[0];  
        let pID = metaArr[1];  
        let raw = payload.slice(metaPos + 1, payload.length);  

        return {  
            type: pType,  
            ID: pID,  
            rawMeta: meta,  
            meta: metaArr,  
            http: raw  
        }  
    } catch(e) {  
        fail(`Error while parsing incoming request: ${msg}`)  
    }  
}  

// Used to compare values from original and replayed responses  
// Accepts request id, regexp pattern for searching the compared value (should include capture group), and callback which returns both original and replayed matched value.  
// Example:   
//  
//   // Compare HTTP headers for response and replayed response, and map values  
//   let tokMap = {};  
//  
//   gor.on("request", function(req) {  
//     let tok = gor.httpHeader(req.http, "Auth-Token");  
//     if (tok && tokMap[tok]) {  
//       req.http = gor.setHttpHeader(req.http, "Auth-Token", tokMap[tok])   
//     }  
//  
//     gor.searchResponses(req.ID, "X-Set-Token: (\w+)$", function(respTok, replTok) {  
//       tokMap[respTok] = replTok;  
//     })  
//  
//     return req;  
//   })  
//  
function searchResponses(id, searchPattern, callback) {  
    let re = new RegExp(searchPattern);  

    // Using regexp require converting buffer to string  
    // Before converting to string we can use initial `Buffer.indexOf` check  
    let indexPattern = searchPattern.split("(")[0];  

    if (!indexPattern) {  
        console.error("Search regexp should include capture group, pointing to the value: `prefix-(.*)`")  
        return  
    }  

    middleware.on("response", id, function(resp){  
        if (resp.http.indexOf(indexPattern) == -1) {  
            callback()  
            return resp  
        }  

        let respMatch = resp.http.toString('utf-8').match(re);  
        if (!respMatch) {  
            callback()  
            return resp  
        }  

        middleware.on("replay", id, function(repl) {  
            if (repl.http.indexOf(indexPattern) == -1) {  
                callback(respMatch[1]);  
                return repl;  
            }  

            let replMatch = repl.http.toString('utf-8').match(re);  

            if (!replMatch) {  
                callback(respMatch[1]);  
                return repl;  
            }  

            callback(respMatch[1], replMatch[1]);  

            return repl;  
        })  

        return resp;  
    })  
}  

// =========== HTTP parsing =================  

// Example HTTP payload record (including hidden characters):  
//  
//  POST / HTTP/1.1\r\n  
//  User-Agent: Node\r\n  
//  Content-Length: 5\r\n  
//  \r\n  
//  hello  

function httpMethod(payload) {  
    var pEnd = payload.indexOf(' ');  
    return payload.slice(0, pEnd).toString("ascii");  
}  

function httpPath(payload) {  
    var pStart = payload.indexOf(' ') + 1;  
    var pEnd = payload.indexOf(' ', pStart);  
    return payload.slice(pStart, pEnd).toString("ascii");  
}  

function setHttpPath(payload, newPath) {  
    var pStart = payload.indexOf(' ') + 1;  
    var pEnd = payload.indexOf(' ', pStart);  

    return Buffer.concat([payload.slice(0, pStart), Buffer.from(newPath), payload.slice(pEnd, payload.length)])  
}  

function httpPathParam(payload, name) {  
    let path = httpPath(payload);  
    let re = new RegExp(name + "=([^&$]+)");  
    let match = path.match(re);  

    if (match) return decodeURI(match[1]);  
}  

function setHttpPathParam(payload, name, value) {  
    let path = httpPath(payload);  
    let re = new RegExp(name + "=([^&$]+)");  
    let newPath = path.replace(re, name + "=" + encodeURI(value));  

    // If we should add new param instead  
    if (newPath == path) {  
        if (newPath.indexOf("?") == -1) {  
            newPath += "?"  
        } else {  
            newPath += "&"  
        }  

        newPath += name + "=" + encodeURI(value);  
    }  

    return setHttpPath(payload, newPath)  
}  

// HTTP response have status code in same position as `path` for requests  
function httpStatus(payload) {  
    return httpPath(payload);  
}  

function setHttpStatus(payload, newStatus) {  
    return setHttpPath(payload, newStatus);  
}  

function httpHeaders(payload) {  
    var httpHeaderString = payload.slice(0,payload.indexOf("\r\n\r\n") + 4).toString().split("\n").slice(1);  
    var headers = {};  

    for (var item in httpHeaderString) {  
        var parts = httpHeaderString[item].split(":");  

        if (parts.length > 1) {  
            headers[parts[0]] = parts.slice(1).join(":").trim();      
        }  
    }  

    return headers;  
}  

function httpHeader(payload, name) {  
    var currentLine = 0;  
    var i = 0;  
    var header = { start: -1, end: -1, valueStart: -1 }  
    var nameBuf = Buffer.from(name);  
    var nameBufLower = Buffer.from(name.toLowerCase());  

    while(c = payload[i]) {  
        if (c == 13) { // new line "\n"  
            currentLine++;  
            i++  
            header.end = i  

            if (currentLine > 0 && header.start > 0 && header.valueStart > 0) {  
                if (nameBuf.compare(payload, header.start, header.valueStart - 1) == 0 ||  
                    nameBufLower.compare(payload, header.start, header.valueStart - 1) == 0) { // ensure that headers are not case sensitive  
                    header.value = payload.slice(header.valueStart, header.end - 1).toString("utf-8").trim();  
                    header.name = payload.slice(header.start, header.valueStart - 1).toString("utf-8");  
                    return header  
                }  
            }  

            header.start = -1  
            header.valueStart = -1  
            continue;  
        } else if (c == 10) { // "\r"  
            i++  
            continue;  
        } else if (c == 58) { // ":" Header/value separator symbol  
            if (header.valueStart == -1) {  
                header.valueStart = i + 1;  
                i++  
                continue;  
            }  
        }  

        if (header.start == -1) header.start = i;  

        i++  
    }  

    return  
}  

function setHttpHeader(payload, name, value) {  
    let header = httpHeader(payload, name);  
    if (!header) {  
        let headerStart = payload.indexOf(13) + 1;  
        return Buffer.concat([payload.slice(0, headerStart + 1), Buffer.from(name + ": " + value + "\r\n"), payload.slice(headerStart + 1, payload.length)])  
    } else {  
        return Buffer.concat([payload.slice(0, header.valueStart), Buffer.from(" " + value + "\r\n"), payload.slice(header.end + 1, payload.length)])  
    }  
}  

function deleteHttpHeader(payload, name) {  
    let header = httpHeader(payload, name);  

    if (header) {  
        return Buffer.concat([payload.slice(0, header.start), payload.slice(header.end+1, payload.length)])  
    }  

    return payload  
}  

function httpBody(payload) {  
    let bodyIndex = payload.indexOf("\r\n\r\n");  
    if (-1 != bodyIndex){  
        return payload.slice(bodyIndex + 4, payload.length);     
    } else {  
        return null;  
    }  
}  

function setHttpBody(payload, newBody) {  
    let p = setHttpHeader(payload, "Content-Length", newBody.length)  
    let headerEnd = p.indexOf("\r\n\r\n") + 4;  
    return Buffer.concat([p.slice(0, headerEnd), newBody])  
}  

function httpBodyParam(payload, name) {  
    let body = httpBody(payload);  
    let re = new RegExp(name + "=([^&$]+)");  
    if (body.indexOf(name + "=") != -1) {  
        let param = body.toString('utf-8').match(re);  
        if (param) {  
            return decodeURI(param[1]);  
        }  
    }  
}  

function setHttpBodyParam(payload, name, value) {  
    let body = httpBody(payload);  
    let re = new RegExp(name + "=([^&$]+)");  

    let newBody = body.toString('utf-8');  

    if (newBody.indexOf(name + "=") != -1 ) {  
        newBody = newBody.replace(re, name + "=" + encodeURI(value));  
    } else {  
        if (newBody.indexOf("=") != -1) {  
            newBody += "&";  
        }  
        newBody += name + "=" + value;  
    }  

    return setHttpBody(payload, Buffer.from(newBody));  
}  

function setHttpCookie(payload, name, value) {  
    let h = httpHeader(payload, "Cookie");  
    let cookie = h ? h.value : "";  
    let cookies = cookie.split("; ").filter(function(v){ return v.indexOf(name + "=") != 0 })  
    cookies.push(name + "=" + value)  
    return setHttpHeader(payload, "Cookie", cookies.join("; "))  
}  

function deleteHttpCookie(payload, name) {  
    let h = httpHeader(payload, "Cookie");  
    let cookie = h ? h.value : "";  
    let cookies = cookie.split("; ").filter(function(v){ return v.indexOf(name + "=") != 0 })  
    return setHttpHeader(payload, "Cookie", cookies.join("; "))  
}  

function httpCookie(payload, name) {  
    let h = httpHeader(payload, "Cookie");  
    let cookie = h ? h.value : "";  
    let value;  
    let cookies = cookie.split("; ").forEach(function(v){  
        if (v.indexOf(name + "=") == 0) {  
            value = v.substr(name.length + 1);  
        }  
    })  
    return value;  
}  

module.exports = {  
    init: init,  
    on: function(){ return middleware.on.apply(this, arguments) },  
    parseMessage: parseMessage,  
    searchResponses: searchResponses,  
    httpPath: httpPath,  
    httpMethod: httpMethod,  
    setHttpPath: setHttpPath,  
    httpPathParam: httpPathParam,  
    setHttpPathParam: setHttpPathParam,  
    httpStatus: httpStatus,  
    setHttpStatus: setHttpStatus,  
    httpHeader: httpHeader,  
    setHttpHeader: setHttpHeader,  
    deleteHttpHeader: deleteHttpHeader,  
    httpBody: httpBody,  
    setHttpBody: setHttpBody,  
    httpBodyParam: httpBodyParam,  
    setHttpBodyParam: setHttpBodyParam,  
    httpCookie: httpCookie,  
    setHttpCookie: setHttpCookie,  
    deleteHttpCookie: deleteHttpCookie,  
    test: testRunner,  
    benchmark: testBenchmark,  
    httpHeaders: httpHeaders  
}  

// =========== Tests ==============  

function testRunner(){  
    ["init", "filter", "parseMessage", "httpMethod", "httpPath", "setHttpHeader", "deleteHttpHeader", "httpPathParam", "httpHeader", "httpBody", "setHttpBody", "httpBodyParam", "httpCookie", "setHttpCookie", "deleteHttpCookie", "httpHeaders"].forEach(function(t){  
        console.log(`====== Start ${t} =======`)  
        eval(`TEST_${t}()`)  
        console.log(`====== End ${t} =======`)  
    })  
}  

function testBenchmark(){  
    const child_process = require('child_process');  

    let gor = init();  
    gor.on("message", function(){  
    });  

    gor.on("request", function(){  
    });  

    for (var i = 0; i<256; i++) {  
        let req = parseMessage(Buffer.from("1 2 3\nGET / HTTP/1.1\r\n\r\n").toString('hex'));  
        req.ID = +Date.now()  
        gor.emit(req);  

        gor.on("request", req.ID+"", function(){  
            gor.on("response", req.ID+"", function(){  
            })  
        })  

        if ( i % 3 == 0 ) {  
            let resp = parseMessage(Buffer.from("2 2 3\nHTTP/1.1 200 OK\r\n\r\n").toString('hex'));  
            resp.ID = req.ID  
            gor.emit(resp);  
        }  
    }  

    child_process.execSync("sleep 0.01");  

    gor.gc(1)   

    fail(JSON.stringify(gor.ch))  
}  

// Just print in red color  
function fail(message) {  
    console.error("\x1b[31m[MIDDLEWARE] %s\x1b[0m", message)  
}  

function log(message) {  
    console.error(message)  
}  

function TEST_init() {  
    const child_process = require('child_process');  

    let received = 0;  
    let gor = init();  
    gor.on("message", function(){  
        received++; // should be called 3 times for for every request  
    });  

    gor.on("request", function(){  
        received++; // should be called 1 time only for request  
    });  

    gor.on("response", "2", function(){  
        received++; // should be called 1 time only for specific response  
    })  

    if (Object.keys(gor.ch).length != 3) {  
        return fail("Should create 3 channels");  
    }  

    let req = parseMessage(Buffer.from("1 2 3\nGET / HTTP/1.1\r\n\r\n").toString('hex'));  
    let resp = parseMessage(Buffer.from("2 2 3\nHTTP/1.1 200 OK\r\n\r\n").toString('hex'));  
    let resp2 = parseMessage(Buffer.from("2 3 3\nHTTP/1.1 200 OK\r\n\r\n").toString('hex'));  

    gor.emit(req);  
    gor.emit(resp);  
    gor.emit(resp2);  

    child_process.execSync("sleep 0.01");  

    if (received != 5) {  
        fail(`Should receive 5 messages: ${received}`);  
    }  
}  

function TEST_filter() {  
    const child_process = require('child_process');  

    let gor = init();  
    gor.on("request", function(req){  
        if (httpPath(req.http) != "/filter") {  
            return req  
        }  
    });  

    gor.on("request", function(req){  
        return req  
    });  

    let reqPass = parseMessage(Buffer.from("1 2 3\nGET / HTTP/1.1\r\n\r\n").toString('hex'));  
    let reqFilter = parseMessage(Buffer.from("1 2 3\nGET /filter HTTP/1.1\r\n\r\n").toString('hex'));  

    if (!gor.emit(reqPass)) {  
        return fail("Should not filter request")  
    }  

    if (gor.emit(reqFilter)) {  
        return fail("Should filter request even if one middleware rejected it")  
    }  

}  

function TEST_parseMessage() {  
    const exampleMessage = Buffer.from("1 2 3\nGET / HTTP/1.1\r\n\r\n").toString('hex')  
    let msg = parseMessage(exampleMessage)  
    let expected = { type: '1', ID: '2', meta: ["1", "2", "3"], http: Buffer.from("GET / HTTP/1.1\r\n\r\n") }  

    Object.keys(expected).forEach(function(k){  
        if (msg[k].toString() != expected[k].toString()) {  
            fail(`${k}: '${expected[k]}' != '${msg[k]}'`)  
        }  
    })  
}  

function TEST_httpPath() {  
    const examplePayload = "GET /test HTTP/1.1\r\n\r\n";  

    let payload = Buffer.from(examplePayload);  
    let path = httpPath(payload);  

    if (path != "/test") {  
        return fail(`Path '${patj}' != '/test'`)  
    }  

    let newPayload = setHttpPath(payload, '/')  
    if (newPayload.toString() != "GET / HTTP/1.1\r\n\r\n") {  
        return fail(`Malformed payload '${newPayload}'`)  
    }  

    newPayload = setHttpPath(payload, '/bigger')  
    if (newPayload.toString() != "GET /bigger HTTP/1.1\r\n\r\n") {  
        return fail(`Malformed payload '${newPayload}'`)  
    }  
}  

function TEST_httpMethod() {  
    const examplePayload = "GET /test HTTP/1.1\r\n\r\n";  

    let payload = Buffer.from(examplePayload);  
    let method = httpMethod(payload);  

    if (method != "GET") {  
        return fail(`Path '${method}' != 'GET'`)  
    }  
}  

function TEST_httpPathParam() {  
    let p = Buffer.from("GET / HTTP/1.1\r\n\r\n");  

    if (httpPathParam(p, "test")) {  
        return fail("Should not found param")  
    }  

    p = setHttpPathParam(p, "test", "123");  
    if (httpPath(p) != "/?test=123") {  
        return fail("Should set first param: " + httpPath(p));  
    }  

    if (httpPathParam(p, "test") != "123") {  
        return fail("Should get first param: " + httpPathParam(p, "test"));  
    }  

    p = setHttpPathParam(p, "qwer", "ty");  
    if (httpPath(p) != "/?test=123&qwer=ty") {  
        return fail("Should set second param: " + httpPath(p));  
    }  

    p = setHttpPathParam(p, "test", "4321");  
    if (httpPath(p) != "/?test=4321&qwer=ty") {  
        return fail("Should update first param: " + httpPath(p));  
    }  

    if (httpPathParam(p, "test") != "4321") {  
        return fail("Should update first param: " + httpPath(p));  
    }  
}  

function TEST_httpBodyParam() {  
    let p = Buffer.from("POST / HTTP/1.1\r\n\r\n");  

    if (httpBodyParam(p, "test")) {  
        return fail("Should not found param")  
    }  

    p = setHttpBodyParam(p, "test", "123");  
    if (httpBody(p).toString() != "test=123") {  
        return fail("Should set first param: " + httpBody(p).toString());  
    }  

    if (httpBodyParam(p, "test") != "123") {  
        return fail("Should get first param: " + httpBodyParam(p, "test"));  
    }  

    p = setHttpBodyParam(p, "qwer", "ty");  
    if (httpBody(p).toString() != "test=123&qwer=ty") {  
        return fail("Should set second param: " + httpBody(p).toString());  
    }  

    p = setHttpBodyParam(p, "test", "4321");  
    if (httpBody(p).toString() != "test=4321&qwer=ty") {  
        return fail("Should update first param: " + httpBody(p).toString());  
    }  

    if (httpBodyParam(p, "test") != "4321") {  
        return fail("Should update first param: " + httpBody(p).toString());  
    }  
}  

function TEST_httpHeader() {  
    const examplePayload = "GET / HTTP/1.1\r\nHost: localhost:3000\r\nUser-Agent: Node\r\nContent-Length:5\r\n\r\nhello";  

    let expected = {"Host": "localhost:3000", "User-Agent": "Node", "Content-Length": "5"}  

    Object.keys(expected).forEach(function(name){  
        let payload = Buffer.from(examplePayload);  
        let header = httpHeader(payload, name);  
        if (!header) {  
            fail(`Header not found. Was looking for: ${name}`)  
        }  
        if (header && header.value != expected[name]) {  
            fail(`${name}: '${expected[name]}' != '${header.value}'`)  
        }  
    })  
}  

function TEST_setHttpHeader() {  
    const examplePayload = "GET / HTTP/1.1\r\nUser-Agent: Node\r\nContent-Length: 5\r\n\r\nhello";  

    // Modify existing header  
    ["", "1", "Long test header"].forEach(function(ua){  
        let expected = `GET / HTTP/1.1\r\nUser-Agent: ${ua}\r\nContent-Length: 5\r\n\r\nhello`;  
        let p = Buffer.from(examplePayload);  
        p = setHttpHeader(p, "User-Agent", ua);  
        if (p != expected) {  
            console.error(`setHeader failed, expected User-Agent value: ${ua}.\n${p}`)  
        }  
    })  

    // Adding new header  
    let expected = `GET / HTTP/1.1\r\nX-Test: test\r\nUser-Agent: Node\r\nContent-Length: 5\r\n\r\nhello`;  
    let p = Buffer.from(examplePayload);  
    p = setHttpHeader(p, "X-Test", "test");  
    if (p != expected) {  
        console.error(`setHeader failed, expected new header 'X-Test' header: ${p}`)  
    }  
}  

function TEST_deleteHttpHeader() {  
    const examplePayload = "GET / HTTP/1.1\r\nUser-Agent: Node\r\nContent-Length: 5\r\n\r\nhello";  

    // Adding new header  
    let expected = `GET / HTTP/1.1\r\nContent-Length: 5\r\n\r\nhello`;  
    let p = Buffer.from(examplePayload);  
    p = deleteHttpHeader(p, "User-Agent", "test");  
    if (p != expected) {  
        console.error(`setHeader failed, expected delete header 'User-Agent' header: ${p}`)  
    }  
}  

function TEST_httpBody() {  
    const examplePayload = "GET / HTTP/1.1\r\nUser-Agent: Node\r\nContent-Length: 5\r\n\r\nhello";  
    let body = httpBody(Buffer.from(examplePayload));  
    if (body != "hello") {  
        fail(`'${body}' != 'hello'`)  
    }  

    const exampleInvalidPayload = "Invalid HTTP Response by Network issue";  
    let invalidBody = httpBody(Buffer.from(exampleInvalidPayload));  
    if (invalidBody != null) {  
        fail(`'${invalidBody}' != 'null'`)  
    }  
}  

function TEST_setHttpBody() {  
    const examplePayload = "GET / HTTP/1.1\r\nUser-Agent: Node\r\nContent-Length: 5\r\n\r\nhello";  
    let p = setHttpBody(Buffer.from(examplePayload), Buffer.from("hello, world!"));  

    if (p != "GET / HTTP/1.1\r\nUser-Agent: Node\r\nContent-Length: 13\r\n\r\nhello, world!") {  
        fail(`Wrong body: '${p}'`)  
    }  
}  

function TEST_httpCookie() {  
    const examplePayload = "GET / HTTP/1.1\r\nCookie: a=b; test=zxc\r\n\r\n";  
    let c = httpCookie(Buffer.from(examplePayload), "test");  
    if (c != "zxc") {  
        return fail(`Should get cookie: ${c}`);  
    }  

    c = httpCookie(Buffer.from(examplePayload), "nope");  
    if (c != null) {  
        return fail(`Should not find cookie: ${c}`);  
    }  
}  

function TEST_setHttpCookie() {  
    const examplePayload = "GET / HTTP/1.1\r\nCookie: a=b; test=zxc\r\n\r\n";  
    let p = setHttpCookie(Buffer.from(examplePayload), "test", "1");  
    if (p != "GET / HTTP/1.1\r\nCookie: a=b; test=1\r\n\r\n") {  
        return fail(`Should update cookie: ${p}`)  
    }  

    p = setHttpCookie(Buffer.from(examplePayload), "new", "one");  
    if (p != "GET / HTTP/1.1\r\nCookie: a=b; test=zxc; new=one\r\n\r\n") {  
        return fail(`Should add new cookie: ${p}`)  
    }  
}  

function TEST_deleteHttpCookie() {  
    const examplePayload = "GET / HTTP/1.1\r\nCookie: a=b; test=zxc\r\n\r\n";  
    let p = deleteHttpCookie(Buffer.from(examplePayload), "a");  
    if (p != "GET / HTTP/1.1\r\nCookie: test=zxc\r\n\r\n") {  
        return fail(`Should delete cookie: ${p}`)  
    }  
}  

function TEST_httpHeaders() {  
    const examplePayload = "GET / HTTP/1.1\r\nHost: localhost:3000\r\nUser-Agent: Node\r\nContent-Length:5\r\n\r\nhello";  

    let expectedHeaders = {"Host": "localhost:3000", "User-Agent": "Node", "Content-Length": "5"}  
    let payload = Buffer.from(examplePayload);  
    let headers = httpHeaders(payload);  

    ["Host", "User-Agent", "Content-Length"].forEach(function(header){  
        let actual = headers[header];  
        let expected = expectedHeaders[header];  

        if (!actual) {  
            fail(`${header} Header was not found`);  
        }  

        if (actual != expected) {  
            fail(`${header} Header not Equal to Expected: ${expected} was ${actual}`);  
        }  

    })  
}  

 
  餐饮点餐小程序的特点

  管理员端

  登录页面

  管理员将输入其凭据以访问系统管理员端的页面。

  类别页面

  列出所有产品/菜单类别并由管理员管理的页面。

  菜单页

  列出产品/菜单并可由管理员管理的页面。

  系统设置

  管理员配置网站数据的页面。

  客户端

  主页

  默认情况下将重定向客户端的页面,并且可以选择他/她想要的菜单。

  购物车页面

  列出正在保存购物车的菜单/产品列表的页面。

  关于页面

  显示咖啡厅或餐厅内容的页面。

  结帐页面

  客户下订单的页面。

收起阅读 »

希望官方可以给picker组件增加农历选择的功能

uniapp

希望官方可以给picker组件增加农历选择的功能

希望官方可以给picker组件增加农历选择的功能

【经验分享】解决打包出现Duplicate class a.a.a.a found in modules

uniapp原生插件 uniapp离线打包 云打包冲突

背景

在某些极端场景下,需要接多个第三方 jar /aar包,但是 jar/aar 包都是各家按自己的规则混淆过的,很容易就出现了两个 jar /aar包中都包含 a.a.a.a 这个类的(前面几个 a 是包名,最后一个 a 是类名)

解决办法

下载新版本 proguard Releases · Guardsquare/proguard

下载后进入bin目录,执行一下操作

  1. 解压aar,得到classes.jar

  2. 然后将classes.jar放到bin目录下

  3. 创建 convert.txt,输入如下内容:

    -injars 'classes.jar'  
    -outjars 'classes-out.jar'  
    
    -dontskipnonpubliclibraryclassmembers  
    -dontshrink  
    -dontoptimize  
    -dontusemixedcaseclassnames  
    # 在这里指定要转换成的包名(将a.a.a替换成的包名)  
    -repackageclasses com.itfenbao  
    -dontpreverify  
    -dontnote  
    -dontwarn  
    -keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,LocalVariable*Table,*Annotation*,Synthetic,EnclosingMethod  
    
    # 需要注意观察原始 jar 包中哪些是没有混淆的,需要保留  
    -keep class com.** {*;}  
    -keep class vivo.** {*;}  
    # 因为我们的目的只是替换外层包名,类内部的一些东西都不用管  
    -keepclassmembers class ** {*;}  
  4. 执行sh

    ./proguard.sh @convert.txt  
  5. classes-out.jar替换aar解压后的classes.jar

  6. 使用jar cvf 重新打包aar

    jar cvf output.aar -C aar_unzip/ .  
继续阅读 »

背景

在某些极端场景下,需要接多个第三方 jar /aar包,但是 jar/aar 包都是各家按自己的规则混淆过的,很容易就出现了两个 jar /aar包中都包含 a.a.a.a 这个类的(前面几个 a 是包名,最后一个 a 是类名)

解决办法

下载新版本 proguard Releases · Guardsquare/proguard

下载后进入bin目录,执行一下操作

  1. 解压aar,得到classes.jar

  2. 然后将classes.jar放到bin目录下

  3. 创建 convert.txt,输入如下内容:

    -injars 'classes.jar'  
    -outjars 'classes-out.jar'  
    
    -dontskipnonpubliclibraryclassmembers  
    -dontshrink  
    -dontoptimize  
    -dontusemixedcaseclassnames  
    # 在这里指定要转换成的包名(将a.a.a替换成的包名)  
    -repackageclasses com.itfenbao  
    -dontpreverify  
    -dontnote  
    -dontwarn  
    -keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,LocalVariable*Table,*Annotation*,Synthetic,EnclosingMethod  
    
    # 需要注意观察原始 jar 包中哪些是没有混淆的,需要保留  
    -keep class com.** {*;}  
    -keep class vivo.** {*;}  
    # 因为我们的目的只是替换外层包名,类内部的一些东西都不用管  
    -keepclassmembers class ** {*;}  
  4. 执行sh

    ./proguard.sh @convert.txt  
  5. classes-out.jar替换aar解压后的classes.jar

  6. 使用jar cvf 重新打包aar

    jar cvf output.aar -C aar_unzip/ .  
收起阅读 »

接外包,全栈、前端、后端、个人、团队等 vx:pan123chong

转让项目 外包接单 混合开发

干程序已经干了六七年了,目前在杭州全职接项目、做项目,有需求的或者喜欢交朋友的,欢迎与我联系交流啊,后面人多了就建个微信群

干程序已经干了六七年了,目前在杭州全职接项目、做项目,有需求的或者喜欢交朋友的,欢迎与我联系交流啊,后面人多了就建个微信群

uniapp整包更新和热更新组件升级版 支持vue3 支持打开安卓自带的应用市场和苹果appstore

热更新

一键式检查更新,同时支持整包升级与wgt资源包更新 支持打开安卓自带的应用市场和苹果appstore

好看、实用、可自定义的客户端提示框

支持强制更新,无法退出

插件地址 https://ext.dcloud.net.cn/plugin?id=7286

继续阅读 »

一键式检查更新,同时支持整包升级与wgt资源包更新 支持打开安卓自带的应用市场和苹果appstore

好看、实用、可自定义的客户端提示框

支持强制更新,无法退出

插件地址 https://ext.dcloud.net.cn/plugin?id=7286

收起阅读 »