分类 未分类 下的文章

缘起

2021/11.
想选基于vue的UI框架, 搜索一圈后, 发现比较集中于以下3个选项:

  • 饿了么的ElementUI
  • Vuetify
  • Quasar
    通过知乎的了解, 似乎ElementUI上手容易但永久了会发现一些小毛病. 于是在Vuetify和Quasar里面选择.
    看了两者的安装文档, 发现Vuetify是完全基于vue-cli的, 而Quasar更推荐使用自己的cli工具. 尝试在vuetify基础上再装Quasar, 发现结果不能渲染... 也许是某种冲突? 另外Quasar是默认使用vue3, 而vuetify默认是vue2. 目前这个时间看vue-cli默认的还是vue2, 那就先用基于vue-cli和vue2的vuetify吧, 再者说了, EvanYou在知乎上也推荐的是这个.

文档

不少知乎上的回答者说vuetify的文档跟屎一样... 我开始也是摸不到门儿, 按文档的Getting Started安装以后, 后面的章节不是按入门学习逻辑顺序排列而是按字母序排列的, 哈...
另外还有个问题是, 中文翻译的文档/网站和英文存在一定的差异性. 我开始是在中文下阅读的, 读到一个莫名其妙的断点的概念的时候, 点链接进去竟然是响应式布局! 连忙切换英文看看, 原来这一章节名字就是Display Breakpoints 显示断点, 而译者意译为了响应式布局, 因为断点的作用就是为了响应式布局. 然而, 除了标题以外,其他地方的翻译又统统变成了断点. 这个时候忽然看了下右上角菜单有个Learn, 里面有个Guide!这不就是要找的学习指南吗?! 点进去, 这个章节竟然不在Getting Started里面, 而是Introduction->Why Vuetify文章的一个子章节! 我想很多看文档的人是为了开始学习, 大概已经不需要告诉自己为什么还要用Vuetify了吧, 估计都会跳过这最重要的入门一章不看了.

安装

倒也简单. 基于vue-cli的. vue-cli的安装方式和以前不一样了. 以前是npm i -g vue-cli,现在变成了:

npm i -g @vue/cli

安装完以后, 创建一个项目, 再加上vuetify插件支持就搞定!

npm create someproject
cd someproject
vue add vuetify

生产环境编译使用npm run build,会在dist目录下生成目标文件.
开发环境编译使用npm run serve. 提示建立了服务器后, 在浏览器打开即可. 后面开发保存即编译. 后面语法错误/编译问题都会在浏览器中查阅.

源文件

都在src目录中. 其中:

  • 入口文件main.js是不需要改的.
  • app.vue是页面框架, 包括页头页尾和中间的内容, 其中页头页尾需要在这儿修改. Vuetify的根标签是, 内容标签是. 页头可以用
  • components/HelloWorld.vue是内容区, 主要修改的内容在这儿. 当然HelloWorld这个名称根据自己需要修改就好了.
  • plugins/vuetify.js在需要配置修改vuetify的时候, 就需要修改这个文件, 而不是修改main.js哦.
  • 自定义css的话, 需要建立一个sass/variables.scss的目录和文件.

基础概念

接着看文档的Why Vuetify最后一个章节功能指南.
双向性可以跳过, 反正我们都是从左到右的.
全局配置可以花10秒看一下, 里面只有一句话就是在vuetify.js中可以配置一个全局参数Vuetify.config且目前只有一个布尔值silent能配置.

海拔

所有元素都支持elevation=n属性, n取值0~24.

图标icon

快速了解下, 就是Vuetify默认带了一套Material Design的图标, 可以直接在Vue的Template里面调用. 图标名称是mdi-加上Material Design图标网站中搜索出来的图标名称. 不过要注意的是, 其中的图标有可能部分在@mdi/js图标库中没有. 这时候可以试着重新安装最新的版本npm install @mdi/js -D

<v-icon large color="yellow">mdi-dots-horizontal</v-icon>

有一系列的大小属性: x-small, small, medium (默认), large, and x-large
有left/right的位置属性, 可以放置在v-btn内,指示图标的位置.
颜色可以通过color属性修改

要将图标嵌入打包的文件, 而不是每次都从CDN上获取, 查看https://vuetifyjs.com/zh-Hans/features/icon-fonts/#material-design56fe6807, 这儿也可以搜索图标名称.
方法是:

$ yarn add @mdi/js -D
// 或
$ npm install @mdi/js -D
// src/plugins/vuetify.js

import Vue from 'vue'
import Vuetify from 'vuetify/lib'

Vue.use(Vuetify)

export default new Vuetify({
  icons: {
    iconfont: 'mdiSvg',
  },
})

在.vue文件中如下书写,导入需要的图标

<!-- Vue Component -->

<template>
  <v-icon>{{ svgPath }}</v-icon>
</template>

<script>
  import { mdiAccount } from '@mdi/js'

  export default {
    data: () => ({
      svgPath: mdiAccount
    }),
  }
</script>

布局layouts

文档说的太简单, 就给了一个下面的格式.

<v-app>
  <v-app-bar app></v-app-bar>

  <v-main>
    <v-container>
      Hello World
    </v-container>
  </v-main>
</v-app>

除了前面说过的v-app, v-app-bar, v-main以外, 还有一个v-footer. 其中v-app-barv-footer需要与v-main并列, 而且需要有app这个属性. 有了这个属性后, 页头页脚才会挤占main的空间, 并且在每个页面上都显示出来.
v-container属于网格布局Grid的一部分, 后面讲到网格布局的时候再说.
跟布局相关的有这么几个

  • 断点breakpoints
  • 网格grids
  • 弹性布局flex
  • 显示辅助display Helpers属性

主题Themes

需要修改vuetify.js文件.
如下.
默认的颜色库需要单独引入.
默认的主题名称是light, 如果不需要换主题的话, 只需要在这儿增加light就可以.

// src/plugins/vuetify.js

import Vue from 'vue'
import Vuetify from 'vuetify/lib'

import colors from 'vuetify/lib/util/colors'

const vuetify = new Vuetify({
  theme: {
    themes: {
      light: {
        primary: colors.purple,
        secondary: colors.grey.darken1,
        accent: colors.shades.black,
        error: colors.red.accent3,
      },
      dark: {
        primary: colors.blue.lighten3,
      },
    },
  },
})

主题的使用方式, 如建一个按钮, 使用primary主题, 定义color属性即可.

            <v-btn tile outlined color="primary">
              <v-icon left>mdi-pencil</v-icon> Edit
            </v-btn>

断点布局breakpoint

不知道为什么要起这样奇怪的名字. 断点实际上是设备的大小分类. 从超小号到超大号分成了5类. 其中超小号是默认类

  • xs, 超小号, 指的是手机
  • sm, 小号, 指的是平板
  • md, 中号, 指的是笔记本电脑(或特大号平板)
  • lg, 大号, 指的是台式机
  • xl, 超大号, 指的是4k显示设备

网格Grid

网格是12列的
网格由上到下结构依次为<v-container>, <v-row>, <v-col>也就是面-行-列的顺序. 其中<v-row>标准是24px的.
另外还有一个<v-spacer>可以夹在中间或者中间, 用于均分剩余的空白.

  • no-gutters属性在一行中不留"排水沟", 也就是列与列中间没有空隙.
  • align属性是垂直对齐方式, 也适用于v-col
  • justify属性是水平对齐方式, 如justify="end"是所有列对齐到最后面

内容可以是<v-card>, 感觉类似一个div.

  • cols属性指定占用的列数, 如cols=3. 不指定则所有列均分. 其他尺寸屏幕下直接用断点名称指定, 如sm=4
  • offset属性是偏移的列数, 如offset=2, 其他尺寸用offset-断点指定, 如offset-sm=2
  • order属性是指定位置. order=数字, 数字越小越靠前. 但没有order属性的将排在最前面. order="first"是排在第一 order="last"是排在最后.

显示辅助display Helpers

实际是一类class,以d-开头, 指示标签css的display属性类型以及适配的断点类型.
包括none,inline, block, inline-block, flex, inline-flex,table, table-row, table-cell等. 如d-inline. 其中d-none是隐藏的意思.
其他屏幕大小, 将断电名放在中间, 如d-sm-inline

flex弹性布局

  • 父元素class都是d-flex就可以使用.
  • 父元素class可以增加flex-方向可以设置浮动方向(轴),包括flex-row, flex-row-reverse, flex-column, flex-column-reverse, 相当于改变css的flex-direction
  • 父元素class增加justify-位置来设置沿轴浮动位置, 包括justify-start, justify-center, justify-end, justify-space-between, justify-space-around, 相当于改变css的justify
  • 父元素class增加align-位置来设置垂直于轴的浮动位置, 包括align-start, align-, align-center, align-end, align-baseline, align-stretch, 相当于改变css的align-items.
  • 元素自身class增加align-self-位置可修改自身的位置. 相当于改变css的align-self
  • 元素自身class增加m位置字母-auto, (位置字母是l, r, t, b之一, 指的是left/right/top/bottom)似乎可以让此元素的对应位置(m指的是margin)充满空间, 将其他元素挤到边上.
  • 元素自身class增加order-数字可以排序. n=0~12,或者first/last
  • 元素自身class增加flex-grow-布尔值``flex-shrink-布尔值可以让此元素在空间不足的时候挤占其他元素空间或者被其他元素挤占.

间距margin/padding

是一组class, 构成是这样的:
m位置字母-可选断点-数字p可选位置字母-可选断点-数字

  • 位置字母是a/l/r/t/b/x/y
  • 可选断点是断点名称
  • 数字为n16(负16)~16, 每加1表示4px.
    举个例子,如ma-4',pa-n5,mr-sm-7`

字体

全部通过class设置.
字体大小是一组class
text-值, 具体为如下之一:

text-h1
text-h2
text-h3
text-h4
text-h5
text-h6
text-subtitle-1
text-subtitle-2
text-body-1
text-body-2
text-button
text-caption
text-overline

字体重量一组class, 具体为如下之一:

font-weight-black
font-weight-bold
font-weight-medium
font-weight-regular
font-weight-light
font-weight-thin

斜体是font-italic
文字横向位置:

text-left
text-center
text-right

https://igghelper.com/helper/?p=402

  1. 版本要大于0.17
  2. General->Service Mode->Manage打开并Install, Install成功后小地球点亮;
  3. Settings->Profile Mixin->Edit粘贴下面代码
    mixin:
    dns:
      enable: true
      enhanced-mode: redir-host
      nameserver:
        - 223.5.5.5 # 真实请求DNS,可多设置几个
        - 8.8.8.8 # 真实请求DNS,可多设置几个
        - 114.114.114.114
    # interface-name: WLAN # 出口网卡名称,或者使用下方的自动检测
    tun:
      enable: true
      stack: gvisor # 使用 system 需要 Premium 2021.05.08 及更高版本
      dns-hijack:
        - 198.18.0.2:53 # 请勿更改
      auto-route: true
      auto-detect-interface: true # 自动检测出口网卡
  4. 状态栏图标右键, 对Mixin打上勾. 测试命令行ping一下, ping通了就搞定.

MCU(C89 Keil编译)上用printf(以及vsprintf), 会出现超过4个动态参数就会出问题的情况.
如: printf("%d,%d,%d,%d,%d", a,b,c,d,e);, 那么参数e很可能显示不准确. 原因不明.

好些天前做的, 记不住全部步骤了😅, 如前面的步骤不通, 再baidu一下吧😅
环境是win10.

步骤

  1. 下载mingw64_posix并解压;
  2. Vscode安装C/C++插件; 其他插件包括code runner, 我不确定是不是一定需要;
  3. 嵌入式插件可选, 包括keil assistant, PlatformIO IDE.
  4. 最重要的是要在代码根目录下建立.vscode的文件夹, 里面放四个文件(这几个保证正确)
  5. 非常重要, 编译器和调试器gcc.exe gdb.exe需要在vscode的终端中可以访问,即所在目录需要预先加入系统path. 否则编译会一直报错, 而且错误提示总让你以为是你的代码问题. 这一点我也很奇怪, json中已经有了编译器和调试器的配置为何再次需要.

文件

c_cpp_properties.json

里面的mingw64_posix路径根据实际情况修改

{   
  "configurations": [       
   {          
       "name": "Win32",       
       "includePath": [
       "${workspaceRoot}",               
       "D:/r/mingw64_posix/mingw64/include/**",               
       "D:/r/mingw64_posix/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++",
       "D:/r/mingw64_posix/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/x86_64-w64-mingw32",
       "D:/r/mingw64_posix/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/backward",
       "D:/r/mingw64_posix/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/include",
       "D:/r/mingw64_posix/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/include-fixed",
       "D:/r/mingw64_posix/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/../../../../x86_64-w64-mingw32/include"
  ],      
  "defines": [
      "_DEBUG",
      "_WIN_DEBUG_",               
      "UNICODE",
      "__GNUC__=6",               
      "__cdecl=__attribute__((__cdecl__))"            
      ],           
  "intelliSenseMode": "msvc-x64",
  "browse": {              
      "limitSymbolsToIncludedHeaders": true,
      "databaseFilename": "",
      "path": [                   
          "${workspaceRoot}",                   
          "D:/r/mingw64_posix/mingw64/include/**",                   
          "D:/r/mingw64_posix/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++",
          "D:/r/mingw64_posix/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/x86_64-w64-mingw32",
          "D:/r/mingw64_posix/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/backward",
          "D:/r/mingw64_posix/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/include",
          "D:/r/mingw64_posix/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/include-fixed",
          "D:/r/mingw64_posix/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/../../../../x86_64-w64-mingw32/include"
         ]        
      }       
   }   
],   
 "version": 4
}

launch.json

{
  // 使用 IntelliSense 了解相关属性。 
  // 悬停以查看现有属性的描述。
  // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
  "version": "0.2.0",
  "configurations": [
    {
      "name": "gcc.exe - 生成和调试活动文件",
      "type": "cppdbg",
      "request": "launch",
      "program": "${fileDirname}\\${fileBasenameNoExtension}.exe",
      "args": [],
      "stopAtEntry": false,
      "cwd": "${fileDirname}",
      "environment": [],
      "externalConsole": false,
      "MIMode": "gdb",
      "miDebuggerPath": "D:\\r\\mingw64_posix\\mingw64\\bin\\gdb.exe",
      "setupCommands": [
        {
          "description": "为 gdb 启用整齐打印",
          "text": "-enable-pretty-printing",
          "ignoreFailures": true
        }
      ],
      "preLaunchTask": "C/C++: gcc.exe 生成活动文件"
    }
  ]
}

settings.json

{
  "files.associations": {
    "*.cjson": "jsonc",
    "*.wxss": "css",
    "*.wxs": "javascript",
    "*.task": "javascript",
    "*.html": "html",
    "esp.h": "c",
    "function2.h": "c",
    "common.h": "c",
    "driver.h": "c",
    "ts_service.h": "c",
    "stdlib.h": "c",
    "stdio.h": "c",
    "conio.h": "c",
    "time.h": "c",
    "math.h": "c",
    "uart_stub.h": "c"
  }
}

tasks.json

这个文件中的args就是gcc的args, 需要根据情况修改. 类似简单的makefile了.
多文件编译的时候, 这儿需要把需要编译的其他文件放进来.
需要编译引入预定义#define的时候, 加入-D预定义名

{
  "tasks": [
    {
      "type": "cppbuild",
      "label": "C/C++: gcc.exe 生成活动文件",
      "command": "D:\\Strawberryperl\\c\\bin\\gcc.exe",
      "args": [
        "-fdiagnostics-color=always",
        "-D_WIN_DEBUG_",
        "-g",
        "${file}","${fileDirname}\\common.c", "${fileDirname}\\driver.c", "${fileDirname}\\..\\..\\function2.c", 
        "${fileDirname}\\..\\..\\esp.c","${fileDirname}\\uart_stub.c",
        "-o",
        "${fileDirname}\\${fileBasenameNoExtension}.exe"
      ],
      "options": {
        "cwd": "${fileDirname}"
      },
      "problemMatcher": [
        "$gcc"
      ],
      "group": {
        "kind": "build",
        "isDefault": true
      },
      "detail": "调试器生成的任务。"
    }
  ],
  "version": "2.0.0"
}

#ifdef _WIN_DEBUG_  
#define DEBUG_PRINTF(format,...) printf("File: "__FILE__", Line: %05d: "format"\n", __LINE__, ##__VA_ARGS__)  
#else  
#define DEBUG_PRINTF(format,...)  
#endif  

上面这个代码的问题是只支持C99以上编译, 如果遇到了C89, 还不支持可变参数宏定义.
这个链接比较完整地进行了讨论. https://newbedev.com/define-macro-for-debug-printing-in-c
C89下可以这样定义

#ifdef _WIN_DEBUG_  
#define DEBUG_PRINTF(msg) printf msg
#else  
#define DEBUG_PRINTF(msg)
#endif  

int main(){
  DEBUG_PRINTF(("%s, %d\n", "abc", 123));  // 作者说使用的时候一定要用双括号. 
}

8266 进入烧录状态

8266进入烧录状态, 需要所谓的三个strapping管脚高低电平处在UART MODE, 其值为1
strapping管脚依次是[GPIO15,GPIO0,GPIO2], 组成的三位二进制数字就是strapping值

Strapping 管脚的 3 位值 [GPIO15,GPIO0,GPIO2] Boot 模式
7 [1,1,1] SDIO HighSpeed V2 IO
6 [1,1,0] SDIO LowSpeed V1 IO
5 [1,0,1] SDIO HighSpeed V1 IO
4 [1,0,0] SDIO LowSpeed V2 IO
3 [0,1,1] Flash Boot
2 [0,1,0] Jump Boot
1 [0,0,1] UART Boot
0 [0,0,0] Remapping

strapping值可以从8266串口的隐藏状态打印出来. 为啥是隐藏状态? 因为8266启动的时候, 会使用一个很不常见的串口波特率是74880(晶振为26M, 是默认的晶振. 如果是40M则是115200).

8266 SDK的make命令帮助

在项目目录中(有makefile和sdkconfig的文件夹)执行make help

Welcome to Espressif IDF build system. Some useful make targets:

make menuconfig - Configure IDF project
make defconfig - Set defaults for all new configuration options

make all - Build app, bootloader, partition table
make flash - Flash app, bootloader, partition table to a chip
make clean - Remove all build output
make size - Display the static memory footprint of the app
make size-components, size-files - Finer-grained memory footprints
make size-symbols - Per symbol memory footprint. Requires COMPONENT=<component>
make erase_flash - Erase entire flash contents
make monitor - Run idf_monitor tool to monitor serial output from app
make simple_monitor - Monitor serial output on terminal console
make list-components - List all components in the project

make app - Build just the app
make app-flash - Flash just the app
make app-clean - Clean just the app
make print_flash_cmd - Print the arguments for esptool when flash

See also 'make bootloader', 'make bootloader-flash', 'make bootloader-clean',
'make partition_table', etc, etc.

#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>

void driverUartPrintf(const unsigned char *fmt, ...){
    va_list args;
    va_start(args, fmt);
    vsprintf(gucUartBuf, fmt,args);
    driverUartSendStr(gucUartBuf);  // 这一句要调用实际串口发送驱动
    va_end(args);
}

参考https://blog.csdn.net/zh458042230/article/details/8630469

这个是中断进程和主函数进程(或其他中断)都调用了同一个函数A的缘故. 中断进程会打断主函数进程而运行, 这时如果打断的地方是主函数进程运行函数A还没有结束的地方, 那么中断再次运行到函数A就会发生函数重入.
如果一定要这么做, 需要加上reentrant这个关键词.
当然中断最好是快进快出. 避免重入的方式, 一般应该是中断中设置需要做函数A任务的标志, 然后在主函数里去完成.

人类很容易把手段当成目标,从而忘记了本来的目标. 毛爷爷说这个就叫"教条化".
我发现很多宗教的问题, 甚至包括宗教本身就是这么产生的."教条化"这个词确实很形象.
孔夫子提出"礼",是针对东周末年朝纲崩坏, 诸侯甚至乱用天子之礼的问题, 目的是为了回复秩序. 而后来孔夫子的话就被当成圣旨不可违抗, 然后就变成了儒教.
同样老子为解释天地万物写了道德经, 里面少不了用一些象征比喻, 因为"道可道非常道", 本来就不好解释清楚嘛. 然后后人看不懂的比喻就强行解释, 或者强制解释为表面意思, 或者胡乱引申为其他意思. 有的是蠢, 有的是坏. 这就有了道教.
同理见其他宗教. 道教的三峰派, 印度教的性力派, 藏传佛教的密宗灌顶, 多多少少都把性从手段变成了目标.
而要是考量基督教,伊斯兰教和佛教的起源, 更都是将先贤的话教条化产生的宗教.

原始的目标只在一定的环境下存在. 教条化就是不顾原始目标,甚至不知道原始目标, 却一定要将手段实现.

甚至现在的企业管理也存在这样的问题. 比如马云的996是福报论. 996作为手段对于马云的目标来说确实是福报, 然而对于码农来说996变成了目标就不见得是福报了, 除非他和马云目标一致.