├── .commitlintrc.js
├── .gitattributes
├── .gitignore
├── .husky
└── commit-msg
├── LICENSE
├── README.md
├── docs
├── .vuepress
│ ├── client.ts
│ ├── config.ts
│ ├── navbar.ts
│ ├── public
│ │ ├── avatar.png
│ │ ├── dslogo.png
│ │ ├── favicon.ico
│ │ ├── ikun.jpeg
│ │ └── logo.png
│ ├── sidebar.ts
│ ├── styles
│ │ ├── config.scss
│ │ ├── index.scss
│ │ ├── palette.scss
│ │ └── rainbow.scss
│ ├── templateBuild.html
│ └── theme.ts
├── README.md
├── apps
│ ├── AppNotes.md
│ ├── Applist.md
│ ├── ChatGPT.md
│ ├── Chrome.md
│ └── design.md
├── back_end
│ ├── database
│ │ ├── mongodb
│ │ │ └── 01.md
│ │ └── mysql
│ │ │ ├── 01.md
│ │ │ ├── 02.md
│ │ │ ├── 03.md
│ │ │ ├── 04.md
│ │ │ ├── 05.md
│ │ │ ├── 06.md
│ │ │ ├── 07.md
│ │ │ ├── 08.md
│ │ │ ├── 09.md
│ │ │ ├── 10.md
│ │ │ └── 11.md
│ ├── linux
│ │ ├── 01.md
│ │ ├── 02.md
│ │ ├── 03.md
│ │ ├── 04.md
│ │ ├── 05.md
│ │ ├── 06.md
│ │ ├── 07.md
│ │ ├── 08.md
│ │ ├── 09.md
│ │ ├── 10.md
│ │ └── 11.md
│ └── nodeJs
│ │ ├── 01.md
│ │ ├── 02.md
│ │ ├── 03.md
│ │ ├── 04.md
│ │ ├── 05.md
│ │ ├── 06.md
│ │ ├── 07.md
│ │ ├── 08.md
│ │ ├── 09.md
│ │ ├── 10.md
│ │ ├── 11.md
│ │ ├── 12.md
│ │ ├── 13.md
│ │ ├── 14.md
│ │ ├── 15.md
│ │ ├── 16.md
│ │ ├── 17.md
│ │ └── 18.md
├── deploy
│ ├── Cloudflare.md
│ ├── DNS.md
│ ├── GitHub.md
│ ├── Static.md
│ └── VPS.md
├── front_end
│ ├── css_advanced
│ │ ├── less
│ │ │ └── 01.md
│ │ ├── scss
│ │ │ ├── 01.md
│ │ │ ├── 02.md
│ │ │ ├── 03.md
│ │ │ ├── 04.md
│ │ │ ├── 05.md
│ │ │ ├── 06.md
│ │ │ ├── 07.md
│ │ │ ├── 08.md
│ │ │ ├── 09.md
│ │ │ ├── 10.md
│ │ │ └── 11.md
│ │ └── tailwind
│ │ │ ├── 01.md
│ │ │ ├── 02.md
│ │ │ ├── 03.md
│ │ │ └── 04.md
│ ├── front_end_base
│ │ ├── html_css
│ │ │ ├── 01.md
│ │ │ ├── 02.md
│ │ │ ├── 03.md
│ │ │ ├── 04.md
│ │ │ ├── 05.md
│ │ │ ├── 06.md
│ │ │ ├── 07.md
│ │ │ ├── 08.md
│ │ │ ├── 09.md
│ │ │ ├── 10.md
│ │ │ ├── 11.md
│ │ │ ├── 12.md
│ │ │ ├── 13.md
│ │ │ ├── 14.md
│ │ │ ├── 15.md
│ │ │ ├── 16.md
│ │ │ ├── 17.md
│ │ │ ├── 18.md
│ │ │ ├── 19.md
│ │ │ ├── 20.md
│ │ │ ├── 21.md
│ │ │ ├── 22.md
│ │ │ └── 23.md
│ │ └── javascript
│ │ │ ├── 01.md
│ │ │ ├── 02.md
│ │ │ ├── 03.md
│ │ │ ├── 04.md
│ │ │ ├── 05.md
│ │ │ ├── 06.md
│ │ │ ├── 07.md
│ │ │ ├── 08.md
│ │ │ ├── 09.md
│ │ │ ├── 10.md
│ │ │ ├── 11.md
│ │ │ ├── 12.md
│ │ │ ├── 13.md
│ │ │ ├── 14.md
│ │ │ ├── 15.md
│ │ │ ├── 16.md
│ │ │ ├── 17.md
│ │ │ ├── 18.md
│ │ │ ├── 19.md
│ │ │ ├── 20.md
│ │ │ ├── 21.md
│ │ │ ├── 22.md
│ │ │ ├── 23.md
│ │ │ ├── 24.md
│ │ │ ├── 25.md
│ │ │ ├── 26.md
│ │ │ ├── 27.md
│ │ │ ├── 28.md
│ │ │ ├── 29.md
│ │ │ ├── 30.md
│ │ │ ├── 31.md
│ │ │ ├── 32.md
│ │ │ ├── 33.md
│ │ │ ├── 34.md
│ │ │ ├── 35.md
│ │ │ └── 36.md
│ ├── front_end_framework
│ │ ├── react
│ │ │ ├── 01.md
│ │ │ ├── 02.md
│ │ │ ├── 03.md
│ │ │ ├── 04.md
│ │ │ ├── 05.md
│ │ │ ├── 06.md
│ │ │ ├── 07.md
│ │ │ ├── 08.md
│ │ │ ├── 09.md
│ │ │ ├── 10.md
│ │ │ ├── 11.md
│ │ │ ├── 12.md
│ │ │ ├── 13.md
│ │ │ ├── 14.md
│ │ │ ├── 15.md
│ │ │ ├── 16.md
│ │ │ ├── 17.md
│ │ │ ├── 18.md
│ │ │ ├── 19.md
│ │ │ ├── 20.md
│ │ │ ├── 21.md
│ │ │ ├── 22.md
│ │ │ └── 23.md
│ │ ├── uniapp
│ │ │ ├── 01.md
│ │ │ ├── 02.md
│ │ │ ├── 03.md
│ │ │ ├── 04.md
│ │ │ ├── 05.md
│ │ │ ├── 06.md
│ │ │ ├── 07.md
│ │ │ ├── 08.md
│ │ │ ├── 09.md
│ │ │ ├── 10.md
│ │ │ └── 11.md
│ │ ├── vue2
│ │ │ ├── 01.md
│ │ │ ├── 02.md
│ │ │ ├── 03.md
│ │ │ ├── 04.md
│ │ │ ├── 05.md
│ │ │ ├── 06.md
│ │ │ ├── 07.md
│ │ │ ├── 08.md
│ │ │ ├── 09.md
│ │ │ ├── 10.md
│ │ │ ├── 11.md
│ │ │ ├── 12.md
│ │ │ ├── 13.md
│ │ │ ├── 14.md
│ │ │ ├── 15.md
│ │ │ └── 16.md
│ │ └── vue3
│ │ │ ├── 01.md
│ │ │ ├── 02.md
│ │ │ ├── 03.md
│ │ │ ├── 04.md
│ │ │ ├── 06.md
│ │ │ ├── 07.md
│ │ │ ├── 08.md
│ │ │ ├── 09.md
│ │ │ ├── 10.md
│ │ │ ├── 11.md
│ │ │ ├── 12.md
│ │ │ ├── 13.md
│ │ │ ├── 14.md
│ │ │ ├── 15.md
│ │ │ ├── 16.md
│ │ │ ├── 17.md
│ │ │ └── 18.md
│ ├── js_advanced
│ │ ├── ajax
│ │ │ ├── 01.md
│ │ │ ├── 02.md
│ │ │ ├── 03.md
│ │ │ └── 04.md
│ │ ├── echarts
│ │ │ ├── 01.md
│ │ │ ├── 02.md
│ │ │ ├── 03.md
│ │ │ ├── 04.md
│ │ │ └── 05.md
│ │ ├── es6
│ │ │ ├── 01.md
│ │ │ ├── 02.md
│ │ │ ├── 03.md
│ │ │ ├── 04.md
│ │ │ ├── 05.md
│ │ │ ├── 06.md
│ │ │ ├── 07.md
│ │ │ ├── 08.md
│ │ │ ├── 09.md
│ │ │ ├── 10.md
│ │ │ ├── 11.md
│ │ │ ├── 12.md
│ │ │ ├── 13.md
│ │ │ └── 14.md
│ │ ├── typescript
│ │ │ ├── 01.md
│ │ │ ├── 02.md
│ │ │ ├── 03.md
│ │ │ ├── 04.md
│ │ │ ├── 05.md
│ │ │ └── 06.md
│ │ └── webpack
│ │ │ ├── 01.md
│ │ │ ├── 02.md
│ │ │ ├── 03.md
│ │ │ └── 04.md
│ └── other
│ │ └── electron
│ │ ├── 01.md
│ │ ├── 02.md
│ │ ├── 03.md
│ │ ├── 04.md
│ │ ├── 05.md
│ │ ├── 06.md
│ │ ├── 07.md
│ │ ├── 08.md
│ │ ├── 09.md
│ │ └── 10.md
├── intro.md
├── professional_knowledge
│ ├── computer_network
│ │ ├── 01.md
│ │ ├── 02.md
│ │ ├── 03.md
│ │ ├── 04.md
│ │ ├── 05.md
│ │ └── 06.md
│ └── software_engineer
│ │ ├── 01.md
│ │ ├── 02.md
│ │ ├── 03.md
│ │ ├── 04.md
│ │ ├── 05.md
│ │ ├── 06.md
│ │ ├── 07.md
│ │ ├── 08.md
│ │ ├── 09.md
│ │ └── 10.md
├── tool
│ ├── efficiency
│ │ ├── bookmark-scripts.md
│ │ ├── online-tools.md
│ │ └── software
│ │ │ ├── browser.md
│ │ │ ├── cross-platform.md
│ │ │ ├── images
│ │ │ └── instasll.jpg
│ │ │ ├── vscode.md
│ │ │ ├── webstorm.md
│ │ │ └── windows.md
│ ├── git
│ │ ├── 01.md
│ │ ├── 02.md
│ │ ├── 03.md
│ │ └── 04.md
│ └── lint
│ │ ├── 01.md
│ │ ├── 02.md
│ │ └── 03.md
└── web
│ ├── Comments.md
│ ├── VuePress.md
│ └── docsify.md
└── package.json
/.commitlintrc.js:
--------------------------------------------------------------------------------
1 | // @see: https://cz-git.qbenben.com/zh/guide
2 | /** @type {import('cz-git').UserConfig} */
3 |
4 | module.exports = {
5 | ignores: [commit => commit.includes('init')],
6 | extends: ['@commitlint/config-conventional'],
7 | rules: {
8 | // @see: https://commitlint.js.org/#/reference-rules
9 | 'body-leading-blank': [2, 'always'],
10 | 'footer-leading-blank': [1, 'always'],
11 | 'header-max-length': [2, 'always', 108],
12 | 'subject-empty': [2, 'never'],
13 | 'type-empty': [2, 'never'],
14 | 'subject-case': [0],
15 | 'type-enum': [
16 | 2,
17 | 'always',
18 | [
19 | 'feat',
20 | 'fix',
21 | 'docs',
22 | 'style',
23 | 'refactor',
24 | 'perf',
25 | 'test',
26 | 'build',
27 | 'ci',
28 | 'chore',
29 | 'revert',
30 | 'wip',
31 | 'workflow',
32 | 'types',
33 | 'release',
34 | ],
35 | ],
36 | },
37 | prompt: {
38 | messages: {
39 | type: '选择你要提交的类型 :',
40 | scope: '选择一个提交范围(可选):',
41 | customScope: '请输入自定义的提交范围 :',
42 | subject: '填写简短精炼的变更描述 :\n',
43 | body: '填写更加详细的变更描述(可选)。使用 "|" 换行 :\n',
44 | breaking: '列举非兼容性重大的变更(可选)。使用 "|" 换行 :\n',
45 | footerPrefixesSelect: '选择关联issue前缀(可选):',
46 | customFooterPrefix: '输入自定义issue前缀 :',
47 | footer: '列举关联issue (可选) 例如: #31, #I3244 :\n',
48 | confirmCommit: '是否提交或修改commit ?',
49 | },
50 | types: [
51 | { value: 'feat', name: 'feat: ✨ 新增功能 | A new feature', emoji: ':sparkles:' },
52 | { value: 'fix', name: 'fix: 🐛 修复缺陷 | A bug fix', emoji: ':bug:' },
53 | { value: 'docs', name: 'docs: 📝 文档更新 | Documentation only changes', emoji: ':memo:' },
54 | {
55 | value: 'style',
56 | name: 'style: 💄 代码格式 | Changes that do not affect the meaning of the code',
57 | emoji: ':lipstick:',
58 | },
59 | {
60 | value: 'refactor',
61 | name: 'refactor: ♻️ 代码重构 | A code change that neither fixes a bug nor adds a feature',
62 | emoji: ':recycle:',
63 | },
64 | { value: 'perf', name: 'perf: ⚡️ 性能提升 | A code change that improves performance', emoji: ':zap:' },
65 | {
66 | value: 'test',
67 | name: 'test: ✅ 测试相关 |Adding missing tests or correcting existing tests',
68 | emoji: ':white_check_mark:',
69 | },
70 | {
71 | value: 'build',
72 | name: 'build: 📦️ 构建相关 | Changes that affect the build system or external dependencies',
73 | emoji: ':package:',
74 | },
75 | {
76 | value: 'ci',
77 | name: 'ci: 🎡 持续集成 | Changes to our CI configuration files and scripts',
78 | emoji: ':ferris_wheel:',
79 | },
80 | {
81 | value: 'chore',
82 | name: "chore: 🔨 其他修改 | Other changes that don't modify src or test files",
83 | emoji: ':hammer:',
84 | },
85 | { value: 'revert', name: 'revert: ⏪️ 回退代码 | Reverts a previous commit', emoji: ':rewind:' },
86 | ],
87 | useEmoji: true,
88 | themeColorCode: '',
89 | scopes: [],
90 | allowCustomScopes: true,
91 | allowEmptyScopes: true,
92 | customScopesAlign: 'bottom',
93 | customScopesAlias: 'custom',
94 | emptyScopesAlias: 'empty',
95 | upperCaseSubject: false,
96 | allowBreakingChanges: ['feat', 'fix'],
97 | breaklineNumber: 100,
98 | breaklineChar: '|',
99 | skipQuestions: [],
100 | issuePrefixs: [{ value: 'closed', name: 'closed: ISSUES has been processed' }],
101 | customIssuePrefixsAlign: 'top',
102 | emptyIssuePrefixsAlias: 'skip',
103 | customIssuePrefixsAlias: 'custom',
104 | allowCustomIssuePrefixs: true,
105 | allowEmptyIssuePrefixs: true,
106 | confirmColorize: true,
107 | maxHeaderLength: Infinity,
108 | maxSubjectLength: Infinity,
109 | minSubjectLength: 0,
110 | scopeOverrides: undefined,
111 | defaultBody: '',
112 | defaultIssues: '',
113 | defaultScope: '',
114 | defaultSubject: '',
115 | },
116 | }
117 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .temp
3 | .cache
4 | dist
--------------------------------------------------------------------------------
/.husky/commit-msg:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 | . "$(dirname -- "$0")/_/husky.sh"
3 |
4 | npx --no-install commitlint --edit $1
5 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 dselegent
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 博客地址
2 |
3 | [博客地址](https://blog.dselegent.icu)
4 |
5 | 有什么错误的地方可以提出来,笔记在我的另外一个仓库[Learning-Notes](https://github.com/dselegent/Learning-Notes)
6 |
7 | # 必看
8 |
9 | 1. 由于以前书写方法不规范,所以有些文章在博客网站上展示不太好,正在修改格式中
10 | 2. 因为改文章进行了大量替换,可能把图片链接的字符给替换导致图片失效,请一定要告诉我,我在 csdn 也是发布了一份,可以引用那边的进行修复。当然你也可以直接去我的 csdn 进行阅读[DSelegent 的博客\_CSDN 博客](https://blog.csdn.net/DSelegent)
11 |
--------------------------------------------------------------------------------
/docs/.vuepress/client.ts:
--------------------------------------------------------------------------------
1 | import { defineClientConfig } from '@vuepress/client'
2 | import { onMounted } from 'vue'
3 |
4 | export default defineClientConfig({
5 | setup() {
6 | onMounted(() => {
7 | console.log(String.raw`
8 |
9 | __ __ _ _ _ _ _
10 | \ \ / / | | | | | | | | | |
11 | \ \ /\ / /__| | ___ ___ _ __ ___ ___ | |_ ___ _ __ ___ _ _ | |__ | | ___ __ _| |
12 | \ \/ \/ / _ \ |/ __/ _ \| '_ ${'`'} _ \ / _ \ | __/ _ \ | '_ ${'`'} _ \| | | | | '_ \| |/ _ \ / _${'`'} | |
13 | \ /\ / __/ | (_| (_) | | | | | | __/ | || (_) | | | | | | | |_| | | |_) | | (_) | (_| |_|
14 | \/ \/ \___|_|\___\___/|_| |_| |_|\___| \__\___/ |_| |_| |_|\__, | |_.__/|_|\___/ \__, (_)
15 | __/ | __/ |
16 | |___/ |___/
17 |
18 | `)
19 | })
20 | },
21 | })
22 |
--------------------------------------------------------------------------------
/docs/.vuepress/config.ts:
--------------------------------------------------------------------------------
1 | import { defineUserConfig } from 'vuepress'
2 | // import { webpackBundler } from "@vuepress/bundler-webpack";
3 | // import { defineUserConfig } from "@vuepress/cli";
4 | // import { searchProPlugin } from 'vuepress-plugin-search-pro'
5 | import { docsearchPlugin } from '@vuepress/plugin-docsearch'
6 | import { sitemapPlugin } from 'vuepress-plugin-sitemap2'
7 | import { googleAnalyticsPlugin } from '@vuepress/plugin-google-analytics'
8 | import { path } from '@vuepress/utils'
9 | import theme from './theme'
10 |
11 | export default defineUserConfig({
12 | // 网站语言,默认为中文
13 | lang: 'zh-CN',
14 | // 网站标题
15 | title: 'dselegent-blog',
16 | // 网站描述
17 | description: '开源工具、效率方法的自我提升笔记,记录并输出一切能让自己提升的知识。',
18 |
19 | // 网站路径默认为主域名。如果网站部署在子路径下,比如 xxx.com/yyy,那么 base 应该被设置为 "/yyy/"
20 | base: '/',
21 | head: [['meta', { name: 'referrer', content: 'no-referrer' }]],
22 | theme,
23 | // 是否开启页面预拉取,如果服务器宽带足够,可改为 true,会提升其他页面加载速度
24 | shouldPrefetch: false,
25 |
26 | // 修改页面模板,https://github.com/vuepress-theme-hope/vuepress-theme-hope/blob/main/packages/theme/templates/index.build.html
27 | // 配置参考:https://vuepress.github.io/zh/reference/theme-api.html#templatebuild
28 | templateBuild: path.resolve(__dirname, 'templateBuild.html'),
29 |
30 | // 禁止文件夹生成静态文件,参考 [VuePress 文档](https://v2.vuepress.vuejs.org/zh/guide/page.html#routing)
31 | pagePatterns: ['**/*.md', '!_temp', '!reading', '!.vuepress', '!node_modules'],
32 |
33 | plugins: [
34 | // algolia 全文搜索:没设置爬虫的话,需删除 docsearchPlugin 区块以使用节点搜索
35 | // docsearchPlugin({
36 | // indexName: 'newzone',
37 | // appId: 'M4EXXEZIEG',
38 | // apiKey: 'fd8891a9c4cc21e0ef4f11bf44f7a11e',
39 | // }),
40 | docsearchPlugin({
41 | appId: 'B1SZXOAN50',
42 | apiKey: '3068368ebb2ca88821ae37fa2b2813a0',
43 | indexName: 'dselegent',
44 | placeholder: '搜索文档',
45 | translations: { button: { buttonText: '搜索文档' } },
46 | }),
47 | sitemapPlugin({
48 | hostname: 'https://blog.dselegent.icu',
49 | }),
50 | // 本地搜索,删除上方 docsearchPlugin 区块后生效
51 | // searchProPlugin({
52 | // indexContent: true,
53 | // hotReload: true,
54 | // customFields: [
55 | // {
56 | // getter: ({ frontmatter }) => frontmatter.tag as string[],
57 | // formatter: `Tag: $content`,
58 | // },
59 | // ],
60 | // }),
61 | // 谷歌分析 ID
62 | googleAnalyticsPlugin({
63 | id: 'G-RWKZTY2P9R',
64 | }),
65 | ],
66 | })
67 |
--------------------------------------------------------------------------------
/docs/.vuepress/public/avatar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dselegent/dselegent-blog/39b171793b69ed8b3bc914bd88d42174e534fd3c/docs/.vuepress/public/avatar.png
--------------------------------------------------------------------------------
/docs/.vuepress/public/dslogo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dselegent/dselegent-blog/39b171793b69ed8b3bc914bd88d42174e534fd3c/docs/.vuepress/public/dslogo.png
--------------------------------------------------------------------------------
/docs/.vuepress/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dselegent/dselegent-blog/39b171793b69ed8b3bc914bd88d42174e534fd3c/docs/.vuepress/public/favicon.ico
--------------------------------------------------------------------------------
/docs/.vuepress/public/ikun.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dselegent/dselegent-blog/39b171793b69ed8b3bc914bd88d42174e534fd3c/docs/.vuepress/public/ikun.jpeg
--------------------------------------------------------------------------------
/docs/.vuepress/public/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dselegent/dselegent-blog/39b171793b69ed8b3bc914bd88d42174e534fd3c/docs/.vuepress/public/logo.png
--------------------------------------------------------------------------------
/docs/.vuepress/styles/config.scss:
--------------------------------------------------------------------------------
1 | // 代码块主题设置,而非网站主题
2 | // https://vuepress-theme-hope.gitee.io/v2/zh/guide/interface/code-theme.html
3 | @use './rainbow';
4 |
5 | // $theme-colors: #2196f3, #f26d6d, #3eaf7c, #fb9b5f;
6 |
7 | $code-light-theme: 'one-light';
8 | $code-dark-theme: 'one-dark';
9 |
--------------------------------------------------------------------------------
/docs/.vuepress/styles/index.scss:
--------------------------------------------------------------------------------
1 | // toc.scss, navbar.scss, sidebar.scss
2 |
3 | .toc-place-holder {
4 | // 从原本距离导航栏 2rem 改为 5rem
5 | top: calc(var(--navbar-height) + 5rem);
6 | }
7 |
8 | // #toc {
9 | // // 增加 toc 与内容区的距离
10 | // // left: calc(100% + 2rem);
11 |
12 | // // 隐藏目录文字「此页内容」
13 | // .toc-header {
14 | // visibility: hidden;
15 | // }
16 | // }
17 |
18 | /*爱的魔力转圈圈*/
19 | .vp-project-home .vp-hero-image {
20 | width: 300px;
21 | height: 300px;
22 | border-radius: 50%;
23 |
24 | &:hover {
25 | transform: translate(-50%, -50%) rotate(666turn) !important;
26 | transition: transform 59s 1s cubic-bezier(0.3, 0, 0.8, 1) !important;
27 | }
28 | }
29 |
30 | :root {
31 | --vp-home-hero-image-background-image: linear-gradient(-45deg, var(--theme-color) 30%, var(--theme-color-next));
32 | --vp-home-hero-image-filter: blur(80px);
33 | }
34 |
35 | .vp-hero-info-wrapper {
36 | position: relative;
37 | z-index: 0;
38 |
39 | &::after {
40 | content: '';
41 | position: absolute;
42 | z-index: -1;
43 | top: 50%;
44 | left: 11%;
45 | border-radius: 50%;
46 | transform: translateY(-50%);
47 | width: 320px;
48 | height: 320px;
49 | opacity: 0.8;
50 | transition: opacity 1s ease;
51 | background-image: var(--vp-home-hero-image-background-image);
52 | filter: var(--vp-home-hero-image-filter);
53 | }
54 | }
55 |
56 | @media (max-width: 960px) {
57 | .vp-hero-info-wrapper::after {
58 | top: 23%;
59 | left: 35%;
60 | width: 280px;
61 | height: 280px;
62 | }
63 | }
64 |
65 | @media (max-width: 640px) {
66 | .vp-hero-info-wrapper::after {
67 | top: 24%;
68 | left: 24%;
69 | width: 256px;
70 | height: 256px;
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/docs/.vuepress/styles/palette.scss:
--------------------------------------------------------------------------------
1 | /*
2 | 参考样式:
3 | https://moonvy.com/blog/post/2022/diffusion-accelerates-diffusion/#%E7%BB%98%E7%94%BB%E8%BE%85%E5%8A%A9%E5%B7%A5%E5%85%B7
4 | 代码来源:https://theme-hope.vuejs.press/zh/config/style.html
5 | */
6 |
7 | $text-color: (
8 | light: #2c3e50,
9 | dark: #b0aeb7,
10 | );
11 |
12 | // content
13 | $bg-color: (
14 | light: #fff,
15 | dark: #252232,
16 | );
17 |
18 | $bg-color-secondary: (
19 | light: #f8f8f8,
20 | dark: #2c293d,
21 | );
22 |
23 | $bg-color-tertiary: (
24 | light: #efeef4,
25 | dark: #3a3755,
26 | );
27 |
28 | // 边框
29 | $border-color: (
30 | light: #eaecef,
31 | dark: #302d28,
32 | );
33 |
34 | // shadow
35 | $box-shadow: (
36 | light: #f0f1f2,
37 | dark: #282a32,
38 | );
39 |
40 | $card-shadow: (
41 | light: rgb(0 0 0 / 15%),
42 | dark: rgb(0 0 0 / 30%),
43 | );
44 |
--------------------------------------------------------------------------------
/docs/.vuepress/templateBuild.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
22 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/docs/.vuepress/theme.ts:
--------------------------------------------------------------------------------
1 | import { path } from '@vuepress/utils'
2 | import { hopeTheme } from 'vuepress-theme-hope'
3 | import navbar from './navbar'
4 | import sidebar from './sidebar'
5 |
6 | export default hopeTheme({
7 | // 主题选项:https://theme-hope.vuejs.press/zh/config/theme/layout.html
8 | hostname: 'https://blog.dselegent.icu',
9 |
10 | author: {
11 | name: 'dselegent',
12 | url: 'https://blog.dselegent.icu',
13 | },
14 |
15 | iconAssets: 'iconfont',
16 | logo: '/logo.png',
17 |
18 | // 是否全局启用路径导航
19 | breadcrumb: true,
20 |
21 | // 页面元数据:贡献者,最后修改时间,编辑链接
22 | contributors: false,
23 | lastUpdated: true,
24 | editLink: true,
25 |
26 | darkmode: 'toggle',
27 | themeColor: false,
28 |
29 | // 默认为 GitHub. 同时也可以是一个完整的 URL
30 | repo: 'dselegent/dselegent-blog',
31 | // 编辑此页的地址设置
32 | docsRepo: 'https://github.com/dselegent/dselegent-blog',
33 | docsBranch: 'main',
34 | docsDir: 'docs',
35 | editLinkPattern: ':repo/edit/:branch/:path',
36 | // 自定义仓库链接文字。默认从 `repo` 中自动推断为 "GitHub" / "GitLab" / "Gitee" / "Bitbucket" 其中之一,或是 "Source"。
37 | repoLabel: 'GitHub',
38 | // 是否在导航栏内显示仓库链接,默认为 `true`
39 | repoDisplay: true,
40 |
41 | // navbar
42 | navbar: navbar,
43 | // 导航栏布局
44 | navbarLayout: {
45 | start: ['Brand', 'Search'],
46 | center: ['Links'],
47 | end: ['Repo', 'Outlook'],
48 | },
49 | // 是否在向下滚动时自动隐藏导航栏
50 | // navbarAutoHide: "always",
51 |
52 | // sidebar
53 | sidebar: sidebar,
54 | // 侧边栏排序规则
55 | // sidebarSorter: ['readme', 'order', 'title'],
56 |
57 | // footer: "默认页脚",
58 | displayFooter: true,
59 |
60 | // 页面布局 Frontmatter 配置:https://theme-hope.vuejs.press/zh/config/frontmatter/layout.html#pageinfo
61 | pageInfo: ['Category', 'Tag', 'Word', 'ReadingTime', 'PageView'],
62 |
63 | // 主题功能选项:https://theme-hope.vuejs.press/zh/config/theme/feature.html
64 | blog: {
65 | articleInfo: ['Date', 'PageView', 'Category', 'Tag', 'ReadingTime'],
66 | name: 'dselegent',
67 | avatar: '/avatar.png',
68 | description: '迷信新工具,热衷于研究开源软件,定期分享探索成果',
69 | intro: '/intro.html',
70 | roundAvatar: true,
71 | medias: {
72 | GitHub: 'https://github.com/dselegent',
73 | Gitee: 'https://gitee.com/dselegent',
74 | QQ: 'https://i0.hdslb.com/bfs/album/93b93def4e70622a4f53d86cd06be2af72c5c845.png',
75 | Wechat: 'https://i0.hdslb.com/bfs/album/c8869ecfc0fcae869a2b6999d3e56b6c3abf3227.png',
76 | Email: 'mailto:1799661558@qq.com',
77 | Gmail: 'mailto:dselegent@gmail.com',
78 | BiliBili: 'https://space.bilibili.com/95443509',
79 | },
80 | },
81 | // 开发模式下是否启动热更新,显示所有更改并重新渲染
82 | hotReload: true,
83 | plugins: {
84 | blog: {
85 | excerpt: true,
86 | },
87 |
88 | // 评论配置(仅做样例,记得更换)
89 | comment: {
90 | provider: 'Waline',
91 | serverURL: 'https://waline.dselegent.icu',
92 | reaction: [
93 | 'https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-y/twemoji/13.1.0/72x72/1f44d.png',
94 | 'https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-y/twemoji/13.1.0/72x72/1f44f.png',
95 | 'https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-y/twemoji/13.1.0/72x72/1f60e.png',
96 | 'https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-y/twemoji/13.1.0/72x72/1f602.png',
97 | 'https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-y/twemoji/13.1.0/72x72/1f635-200d-1f4ab.png',
98 | ],
99 | // 部署 Waline:https://waline.js.org/guide/get-started.html
100 | pageview: true, // 浏览量统计
101 | locales: {
102 | '/': {
103 | // 表情互动提示文字
104 | reactionTitle: '已到达文章底部,欢迎留言、表情互动~',
105 | reaction0: '赞一个',
106 | reaction1: '支持下',
107 | reaction2: '有点酷',
108 | reaction3: '啥玩意',
109 | reaction4: '看不懂',
110 | // Waline 等级标签
111 | admin: '盛年不重来,一日难再晨',
112 | level0: '锻体',
113 | level1: '炼气',
114 | level2: '筑基',
115 | level3: '金丹',
116 | level4: '元婴',
117 | level5: '化神',
118 | },
119 | },
120 |
121 | // Giscus 备用配置
122 | /*
123 | provider: "Giscus",
124 | repo: "rockbenben/LearnData",
125 | repoId: "R_kgDOHdfk6Q",
126 | category: "Comments",
127 | categoryId: "DIC_kwDOHdfk6c4CQYNn",
128 | */
129 | },
130 |
131 | // 组件库
132 | // components: {
133 | // components: ['Badge', 'BiliBili', 'VideoPlayer', 'YouTube'],
134 | // },
135 |
136 | // 禁用不需要的配置
137 | mdEnhance: {
138 | align: true,
139 | attrs: true, // 使用特殊标记为 Markdown 元素添加属性
140 | // chart: true,
141 | // codetabs: true, // 代码块分组
142 | container: true,
143 | // demo: true, //代码演示
144 | // echarts: true,
145 | // flowchart: true,
146 | gfm: true,
147 | imgLazyload: true,
148 | // imgMark: true,
149 | imgSize: true,
150 | figure: true,
151 | include: true, //导入文件
152 | // katex: true,
153 | mark: true,
154 | // mermaid: true,
155 | footnote: true,
156 | tasklist: true,
157 | sub: true, // 上下角标
158 | sup: true,
159 | // tabs: true, // 选项卡
160 | // vpre: true,
161 | // vuePlayground: true, // Vue 交互演示
162 | },
163 |
164 | // rss 属性
165 | feed: {
166 | rss: true,
167 | count: 10,
168 | },
169 |
170 | // pwa
171 | pwa: {
172 | favicon: '/favicon.ico',
173 | },
174 | },
175 | })
176 |
--------------------------------------------------------------------------------
/docs/README.md:
--------------------------------------------------------------------------------
1 | ---
2 | #博客首页设置:https://theme-hope.vuejs.press/zh/guide/blog/home.html
3 | home: true
4 | # layout: BlogHome
5 | icon: home
6 | heroImage: /dslogo.png
7 | heroText: dselegent-blog
8 | tagline: 目前域名已更换为 blog.dselegent.icu,之前的 blog.dselegent.cf 域名已设置重定向到此域名,请小伙伴们更新一下链接
9 | bgImage: http://tc.seoipo.com/home-bg-1.jpg
10 | # heroFullScreen: true
11 | actions:
12 | - text: 前端导航
13 | link: /front_end/
14 | type: primary
15 |
16 | - text: 后端导航
17 | link: /back_end/
18 | type: primary
19 |
20 | features:
21 | - title: 页面开发
22 | icon: network
23 | details: 静态站点生成器
24 | link: /web/
25 |
26 | - title: 应用
27 | icon: computer
28 | details: 应用推荐
29 | link: /apps/
30 |
31 | - title: 专业知识
32 | icon: computer
33 | details: 计算机基础知识笔记
34 | link: /professional_knowledge/
35 |
36 | - title: 前端导航
37 | icon: html
38 | details: 前端笔记
39 | link: /front_end/
40 |
41 | - title: 后端导航
42 | icon: network
43 | details: 后端笔记
44 | link: /back_end/
45 |
46 | - title: 工具导航
47 | icon: tool
48 | details: 编程工具记录
49 | link: /tool/
50 |
51 | - title: 笔记
52 | icon: note
53 | details: Github 笔记源文件仓库
54 | link: https://github.com/dselegent/Learning-Notes
55 |
56 | #footer: 自定义你的页脚文字
57 | ---
58 |
--------------------------------------------------------------------------------
/docs/apps/design.md:
--------------------------------------------------------------------------------
1 | ---
2 | article: false
3 | title: 平面设计
4 | icon: pic
5 | order: 3
6 | ---
7 |
8 | ## 电子白板
9 |
10 | 在电子白板功能普及之前,我用 Figma 对海报、图片素材进行简单剪辑,制作流程图。但电子白板的美观与自由度远胜 Figma,我现在的流程图与示意图都通过 Excalidraw 与 canvas 来完成。
11 |
12 | 在电子白板功能普及之前,我使用 Figma 对海报、图片素材进行简单剪辑,制作流程图。但是,电子白板的美观和自由度远远超过 Figma,我现在的流程图和示意图都是通过 Excalidraw 和 Canvas 完成的。
13 |
14 | ### Excalidraw
15 |
16 | [Excalidraw](https://github.com/excalidraw/excalidraw) 是一款开源免费的手绘风格画图应用,可以简单地制作美观漂亮的流程图、示意图和开发架构图等常用图片,也支持插入图片,是一款自由便捷的电子白板应用。Excalidraw 已被集成到各类白板应用中。
17 |
18 | 不过,Excalidraw 没有中文手写字体,需手动修改,比如 [Excalidraw 官方版添加中文手写字体](https://blog.csdn.net/qq_34802028/article/details/127927960),[Obsidian 中文手写体设置](https://blog.csdn.net/qq_26176515/article/details/126005295),[网页端中文手写字体配置](https://zhuanlan.zhihu.com/p/577420136)。
19 |
20 | 
21 |
22 | ### Canvas
23 |
24 | Canvas(画布)是所有 UI 组件的「容器」。一个场景中,可以允许多个 canvas 对象存在,也允许 canvas 之间进行「嵌套」使用。需要注意的是,场景中的任何一个 UI 对象,都必定是某个 canvas 对象的「子级」。我最常用的是 Obsidian 和秒笔的 Canvas 功能:
25 |
26 | - Obsidian Canvas:可以将图片、视频、文本、网页、文件和 Excalidraw 聚合在一起,并建立连接线和分组。
27 |
28 | 
29 |
30 | - 秒笔白板:支持聚合图片、文本、表格、清单、看板和 Excalidraw,但根据作者回复,妙笔的连接线和分组功能会在 2023 的下半年才摆上开发计划。
31 |
32 | ## 获取页面 logo
33 |
34 | 一些页面图标路径是隐藏的,无法在前端获取,可以使用 [ImageAssistant](https://chrome.google.com/webstore/detail/imageassistant-batch-imag/dbjbempljhcmhlfpfacalomonjpalpko) 扩展提取页面所有图片,或者通过搜索引擎搜索,获取网站提交给搜索引擎的 logo 图片。
35 |
36 | 如果获取的图标较小,可以使用 [waifu2x](http://waifu2x.udp.jp/index.zh-CN.html) 进行最大降噪,然后多次放大 logo。其他放大算法会令 logo 变化,而 waifu2x 不会改变原图。
37 |
38 | 如果图标 svg 不符合要求,可以使用 [SVG-edit](https://svgedit.netlify.app/editor/index.html) 进行简单编辑。
39 |
40 | ## Eagle
41 |
42 | Eagle 非常适合管理图片素材。其优势之一是去重,我的素材库有几十万个文件,无法一个个清理,但导入 Eagle 就可以去除重复素材。
43 |
44 | Eagle 导入流程:搜索文件夹中的 ZIP/RAR 文件,确认全部解压。
45 |
46 | ## 字体
47 |
48 | 字体是海报的灵魂,海报主标题不要用纯黑色,建议 `#1F2937`。
49 |
50 | 以下是我常用的几种字体:
51 |
52 | - [阿里巴巴普惠体 2.0](https://fonts.alibabagroup.com/#/font):简称「Alibaba PuHuiTi 2.0」,免费可商用,覆盖中英文。
53 | - [阿里妈妈数黑体](https://fonts.alibabagroup.com/#/more):简称「Alimama ShuHeiTi」,数黑体为中文简体字库,适用于电商、广告、品牌形象、推广物料等场景。
54 | - [思源字体](https://github.com/adobe-fonts/source-han-sans/):简称「Source Han Sans」,这是比较规规矩矩的一款字体,谷歌出品。用在商务风 PPT,或者是用在正文中,阅读效果都很赞。
55 | - [FOT-MatissePro](https://www.mianfeiziti.com/fonts-fotmatisseprom):原本为 EVA 的常用日语字体,也支持大部分的繁体。
56 | - [优设标题黑](https://www.fonts.net.cn/font-38213257557.html):简称「YouSheBiaoTiHei-2」,以黑体字型为基础,整体字形沉稳,同时采用较大字面和粗壮的笔画来强化力量感。每个字体水平倾斜 8° 的设计,赋予了字体极强的速度感,为了让字体倾斜后也能保持稳固,设计师将整体字身设定宽扁。而起笔和弯钩上独具匠心的尖角设计,不仅突显了设计的几何感,而且方便后期修改。
57 | - [优设好身体](https://www.fonts.net.cn/font-38877223362.html):简称「YSHaoShenTi-2」,一款亲和力、现代感极强的专业美术标题字体。它以圆体字型为基础,通过瘦高的字面、偏向几何的曲线,让整宽字体富有亲和力和时尚感。在同样的面积里,更窄的字面就意味着能容纳更多的信息,所以这款字体非常适用在需要体现亲和力与时尚感的各类品牌宣传广告和产品包装设计的标题上。
58 | - [851 手书体](https://www.100font.com/thread-114.htm):851 手書き雑フォント,虽为日系字体但覆盖了大部分的中英文,是以硬笔为主的手写字型,我喜欢用在 Excalidraw。
59 | - [濑户体](https://www.100font.com/thread-69.htm):简称「SetoFont」,是一款偏可爱风的字体,支持简体中文、繁体中文、日文。
60 | - [杨任东竹石体](https://www.fonts.net.cn/font-35850420097.html):手写字体,简称为「YRDZST」。
61 | - [得意黑字体](https://github.com/atelier-anchor/smiley-sans/releases):非手写字体,但用在 Excalidraw 也不错。
62 | - [锐字真言体](https://www.fonts.net.cn/font-35961736892.html):简称「Zhenyan」,真言体笔触浑厚有力,笔画曲折有度,字形个性鲜明,刚柔并济,落笔简洁有序,给人以遒劲有力、端正凝练的感受。直角与圆角的错落搭配使得字体婉转有度,落落大方,具有自己独到的风格!这款字体特别适用于文字标题、竞技视觉、广告设计、个性品牌设计推广、企业宣传及时尚品牌的设计应用。
63 |
64 | 字体格式建议 OTC > OTF > TTC > TTF,如果只在 Windows 平台使用,TTC/TTF 体验更佳。如果您是一名设计师并进行大量的印刷设计,您可以使用 Adobe 软件进行大量工作。在这种情况下,建议使用 OTF 字体,因为 .otf 是 基于 postscript(类似于 PDF) 并由 Adobe 开发。OTF 格式还提供了更多风格的替代方案和字距调整选项,设计师可能会觉得这些 选项有用。如果您使用 MS Ofce 进行大量工作时,建议使用 TTF 字体,因为 .ttf 是由 Microsoft 和 Apple 开发的。例如:您只能将.ttf 字体嵌入到 MS Word 和 MS PowerPoint 中,而不能嵌入 .otf 字体。
65 |
--------------------------------------------------------------------------------
/docs/back_end/database/mysql/05.md:
--------------------------------------------------------------------------------
1 | # 05 【排序与分页】
2 |
3 | ## 1.排序数据
4 |
5 | ==注:如果没有使用排序操作,默认情况下查询返回的数据是按照添加数据的顺序显示的。==
6 |
7 | ### 1.1 排序规则
8 |
9 | - 使用 ORDER BY 子句排序
10 | - **ASC(ascend): 升序(默认)**
11 | - **DESC(descend):降序**
12 | - **ORDER BY 子句在SELECT语句的结尾。**
13 |
14 | ### 1.2 单列排序
15 |
16 | ```sql
17 | SELECT last_name, job_id, department_id, hire_date
18 | FROM employees
19 | ORDER BY hire_date;
20 | ```
21 |
22 | 
23 |
24 | ```sql
25 | SELECT last_name, job_id, department_id, hire_date
26 | FROM employees
27 | ORDER BY hire_date DESC ;
28 | ```
29 |
30 | 
31 |
32 | ```sql
33 | SELECT employee_id, last_name, salary*12 annsal
34 | FROM employees
35 | ORDER BY annsal;
36 | ```
37 |
38 | 
39 |
40 | 列的别名只能在 ORDER BY中使用,不能在WHERE中使用。
41 |
42 | ```sql
43 | -- 如下操作报错!
44 | SELECT employee_id, last_name, salary*12 annsal
45 | FROM employees
46 | where annal > 10000
47 | ```
48 |
49 | ### 1.3 多列排序
50 |
51 | ```sql
52 | SELECT last_name, department_id, salary
53 | FROM employees
54 | ORDER BY department_id, salary DESC;
55 | ```
56 |
57 | 
58 |
59 | - 可以使用不在SELECT列表中的列排序。
60 | - 在对多列进行排序的时候,首先排序的第一列必须有相同的列值,才会对第二列进行排序。如果第一列数据中所有值都是唯一的,将不再对第二列进行排序。
61 |
62 | ## 2.分页
63 |
64 | ### 2.1 背景
65 |
66 | 背景1:查询返回的记录太多了,查看起来很不方便,怎么样能够实现分页查询呢?
67 |
68 | 背景2:表里有 4 条数据,我们只想要显示第 2、3 条数据怎么办呢?
69 |
70 | ### 2.2 实现规则
71 |
72 | - 分页原理
73 |
74 | 所谓分页显示,就是将数据库中的结果集,一段一段显示出来需要的条件。
75 |
76 | - **MySQL中使用 LIMIT 实现分页**
77 |
78 | - 格式:
79 |
80 | ```sql
81 | LIMIT [位置偏移量,] 行数
82 | ```
83 |
84 | 第一个“位置偏移量”参数指示MySQL从哪一行开始显示(`默认从0开始`),是一个可选参数,如果不指定“位置偏移量”,将会从表中的第一条记录开始(第一条记录的位置偏移量是0,第二条记录的位置偏移量是1,以此类推);第二个参数“行数”指示返回的记录条数。
85 |
86 | - 举例
87 |
88 | ```sql
89 | -- 前10条记录:
90 | SELECT * FROM 表名 LIMIT 0,10;
91 | 或者
92 | SELECT * FROM 表名 LIMIT 10;
93 |
94 | -- 第11至20条记录:
95 | SELECT * FROM 表名 LIMIT 10,10;
96 |
97 | -- 第21至30条记录:
98 | SELECT * FROM 表名 LIMIT 20,10;
99 | ```
100 |
101 | MySQL 8.0中可以使用“`LIMIT 3 OFFSET 4`”,意思是获取从第5条记录开始后面的3条记录,和“LIMIT 4,3;”返回的结果相同。
102 |
103 | - 分页显式公式**:`(当前页数-1)\*每页条数,每页条数`**
104 |
105 | ```sql
106 | SELECT * FROM table
107 | LIMIT (PageNo - 1)*PageSize,PageSize;
108 | ```
109 |
110 | - **注意:LIMIT 子句必须放在整个SELECT语句的最后!**
111 | - 使用 LIMIT 的好处
112 |
113 | 约束返回结果的数量可以`减少数据表的网络传输量`,也可以`提升查询效率`。如果我们知道返回结果只有 1 条,就可以使用`LIMIT 1`,告诉 SELECT 语句只需要返回一条记录即可。这样的好处就是 SELECT 不需要扫描完整的表,只需要检索到一条符合条件的记录即可返回。
114 |
115 | ## 3.课后练习
116 |
117 | **1. 查询员工的姓名和部门号和年薪,按年薪降序 按姓名升序显示**
118 |
119 | ```sql
120 | SELECT last_name,department_id,salary * 12 annual_sal
121 | FROM employees
122 | ORDER BY annual_sal DESC,last_name ASC;
123 | ```
124 |
125 | **2.选择工资不在 8000 到17000 员工的姓名和工资,按工资降序,显示第 21到40位置的数据**
126 |
127 | ```sql
128 | SELECT last_name,salary
129 | FROM employees
130 | WHERE salary NOT BETWEEN 8000 AND 17000
131 | ORDER BY salary DESC
132 | LIMIT 20,20;
133 | ```
134 |
135 | **3. 查询邮箱中包含 e 的员工信息,并先按邮箱的字节数降序,再按部门号 升序**
136 |
137 | ```sql
138 | SELECT last_name,email,department_id
139 | FROM employees
140 | -- where email like '%e%'
141 | WHERE email REGEXP '[e]'
142 | ORDER BY LENGTH(email) DESC,department_id ASC;
143 | ```
--------------------------------------------------------------------------------
/docs/back_end/nodeJs/02.md:
--------------------------------------------------------------------------------
1 | # 02 【nodejs开发环境安装】
2 |
3 | ## 1.版本介绍
4 |
5 | - 在命令窗口中输入 node -v 可以查看版本
6 | - 0.x 完全不技术 ES6
7 | - 4.x 部分支持 ES6 特性
8 | - 5.x 部分支持ES6特性(比4.x多些),属于过渡产品,现在来说应该没有什么理由去用这个了
9 | - 6.x 支持98%的 ES6 特性
10 | - 8.x 支持 ES6 特性
11 |
12 | ## 2.Node.js 运行环境配置:通过 Node.js 安装包(不推荐)
13 |
14 | 去 Node.js 的[官网](https://nodejs.org/en/)下载安装包:
15 |
16 | 
17 |
18 | 我们也可以在https://nodejs.org/en/download/releases/ 里下载历史版本。
19 |
20 | 
21 |
22 | 后续如果需要安装其他版本,可以这样做:重新下载最新的安装包,覆盖安装即可。
23 |
24 | 但我们并不推荐直接采用 Node.js.msi(windows)或者 Node.js.pkg(Mac) 安装包进行安装,因为会产生如下问题。
25 |
26 | **通过 Node.js 安装包产生的问题**:
27 |
28 | - 安装新版本时,需要覆盖就版本;而且以前版本安装的很多全局工具包,需要重新安装。
29 | - 无法回滚到之前的旧版本。
30 | - 无法在多个版本之间切换(很多时候,不同的项目需要使用特定版本。或者,我想临时尝鲜一下新版本的特性)
31 |
32 | 因此,我们暂时先不用安装 Node.js,稍后用 NVM 的方式来安装 Node.js。通过 NVM 的方式,可以让多个版本的 Node.js 共存,并灵活切换。
33 |
34 | > ### Node.js 版本常识
35 | >
36 | > - 偶数版本为稳定版(0.6.x ,0.8.x ,8.10.x)
37 | > - 奇数版本为非稳定版(0.7.x ,0.9.x ,9.11.x)
38 | > - LTS(Long Term Support)
39 | >
40 | > 参考链接:[node.js 中 LTS 和 Current 的区别](https://blog.csdn.net/u012532033/article/details/73332099)
41 |
42 | ## 3.Node.js 运行环境安装:通过 NVM(推荐)
43 |
44 | **[NVM](https://github.com/nvm-sh/nvm)**:node.js version manager,用来管理 node 的版本。
45 |
46 | **我们可以先安装 NVM,然后通过 NVM 安装 Node.js**。这是官方推荐的做法。
47 |
48 | Windows 安装的 Node.js 的步骤如下。
49 |
50 | ### 3.1 安装 NVM:
51 |
52 | (1)我们去 https://github.com/coreybutler/nvm-windows/releases 下载 NVM 的安装包:
53 |
54 | 
55 |
56 | 下载下来后,直接解压到 `D:\web`目录下:
57 |
58 | 
59 |
60 | (2)在上面的目录中,新建一个`settings.txt`文件,里面的内容填充如下:
61 |
62 | ```sh
63 | root: D:\web\nvm
64 | path: D:\web\nodejs
65 | arch: 64
66 | proxy
67 | ```
68 |
69 | 上方内容的解释:
70 |
71 | - root 配置为:当前 nvm.exe 所在的目录
72 | - path 配置为:node 快捷方式所在的目录
73 | - arch 配置为:当前操作系统的位数(32/64)
74 | - proxy 不用配置
75 |
76 | (3)配置环境变量:
77 |
78 | - `NVM_HOME` = `D:\web\nvm`(当前 nvm.exe 所在目录)
79 | - `NVM_SYMLINK` = `D:\web\nodejs` (node 快捷方式所在的目录)
80 | - PATH += `;%NVM_HOME%;%NVM_SYMLINK%`
81 |
82 | 配置成功后,重启资源管理器。
83 |
84 | ### 3.2 验证
85 |
86 | (1)输入`nvm`命令查看环境变量是否配置成功
87 |
88 | (2)输入 `nvm ls`,查看已安装的所有 node 版本。
89 |
90 | (3)输入 `nvm -v`,查看 已安装的 nvm 版本。
91 |
92 | (4)输入 `node -v`,查看正在使用的 node 版本。
93 |
94 | 如果 Node 安装失败,可以参考上面这个链接。
95 |
96 | ### 3.3 安装指定版本的 Node.js
97 |
98 | ```shell
99 | nvm install 版本号
100 |
101 | # 举例
102 | nvm install 8.10.0
103 | ```
104 |
105 | 输入 `node -v`,查看当前使用的 node 版本。
106 |
107 | 关于 NVM 的常用命令,详见下一段。
108 |
109 | 补充:
110 |
111 | 如果 Node 安装失败,可以在上方的 `settings.txt`文件中,新增如下两行,修改镜像源:
112 |
113 | ```text
114 | node_mirror: https://npmmirror.com/mirrors/node/
115 | npm_mirror: https://npmmirror.com/mirrors/npm/
116 | ```
117 |
118 | - 参考链接:[安装 npm,nvm,node](https://segmentfault.com/a/1190000011114680)
119 |
120 | ## 4.NVM 的常用命令
121 |
122 | > 注意,这一段说的是 NVM 的常用命令,不是 Node 的常用命令。
123 |
124 | 查看当前使用的 nvm 版本:
125 |
126 | ```bash
127 | nvm --version
128 | ```
129 |
130 | 查看本地安装的所有的 Node.js 版本:
131 |
132 | ```bash
133 | # 方式1
134 | nvm ls
135 |
136 | # 方式2
137 | nvm list
138 | ```
139 |
140 | **安装指定版本的 Node.js:**
141 |
142 | ```bash
143 | nvm install 版本号
144 |
145 | # 举例
146 | nvm install 8.10.0
147 | ```
148 |
149 | 卸载指定版本 Node.js:
150 |
151 | ```bash
152 | nvm uninstall 版本号
153 | ```
154 |
155 | **切换使用指定版本的 node**:
156 |
157 | ```bash
158 | nvm use 版本号
159 | ```
160 |
161 | **设置node的默认版本**:
162 |
163 | ```bash
164 | nvm alias default 版本号
165 | ```
166 |
167 | **查看全局npm包的安装路径**:
168 |
169 | ```text
170 | npm root -g
171 | ```
172 |
173 | 查看远程服务器端的所有 Node 版本:
174 |
175 | ```bash
176 | nvm ls-remote
177 | ```
178 |
179 | 执行上面的命令后,在列出的版本清单中,凡是用 `Latest LTS`标注的版本,则表明是**长期维护**的版本。我们在安装时,建议安装这些版本。当然,我们也可以在网址 https://nodejs.org/en/download/releases/ 查看 LTS 的历史版本。
180 |
181 | ## 5.Node.js 的常用命令
182 |
183 | 查看 node 的版本:
184 |
185 | ```bash
186 | $ node -v
187 | ```
188 |
189 | 执行脚本字符串:
190 |
191 | ```bash
192 | $ node -e 'console.log("Hello World")'
193 | ```
194 |
195 | 运行脚本文件:
196 |
197 | ```bash
198 | $ node index.js
199 |
200 | $ node path/index.js
201 |
202 | $ node path/index
203 | ```
204 |
205 | 查看帮助:
206 |
207 | ```bash
208 | $ node --help
209 | ```
--------------------------------------------------------------------------------
/docs/back_end/nodeJs/11.md:
--------------------------------------------------------------------------------
1 | # 11 【Express服务端渲染】
2 |
3 | ## 1.Express脚手架的安装
4 |
5 | 安装Express脚手架有两种方式:
6 |
7 | ### 1.1 使用express-generator安装
8 |
9 | 使用命令行进入项目目录,依次执行:
10 |
11 | ```bash
12 | cnpm i -g express-generator
13 | ```
14 |
15 | 可通过express -h查看命令行的指令含义
16 |
17 | ```bash
18 | express -h
19 | ```
20 |
21 | ```bash
22 | Usage: express [options] [dir]
23 | ```
24 |
25 | ```bash
26 | Options:
27 | --version 输出版本号
28 | -e, --ejs 添加对 ejs 模板引擎的支持
29 | --pug 添加对 pug 模板引擎的支持
30 | --hbs 添加对 handlebars 模板引擎的支持
31 | -H, --hogan 添加对 hogan.js 模板引擎的支持
32 | -v, --view 添加对视图引擎(view) 的支持 (ejs|hbs|hjs|jade|pug|twig|vash) (默认是 jade 模板引擎)
33 | --no-view 创建不带视图引擎的项目
34 | -c, --css 添加样式表引擎 的支持 (less|stylus|compass|sass) (默认是普通的 css 文件)
35 | --git 添加 .gitignore
36 | -f, --force 强制在非空目录下创建
37 | -h, --help 输出使用方法
38 | ```
39 |
40 | 创建了一个名为 myapp 的 Express 应用,并使用ejs模板引擎
41 |
42 | ```bash
43 | express --view=ejs myapp
44 | ```
45 |
46 | 进入app,并安装依赖
47 |
48 | ```bash
49 | cd myapp
50 | npm install
51 | ```
52 |
53 | **在Windows 下,使用以下命令启Express应用:**
54 |
55 | ```bash
56 | set DEBUG=app:* & npm start
57 | ```
58 |
59 | **在 MacOS 或 Linux 下,使用以下命令启Express应用:**
60 |
61 | ```bash
62 | DEBUG=app:* npm start
63 | ```
64 |
65 | ### 1.2 使用 express 命令 来快速从创建一个项目目录
66 |
67 | express 项目文件夹的名字 -e 如 使用命令行进入项目目录,依次执行:
68 |
69 | ```bash
70 | express app -e
71 | cd app
72 | cnpm install
73 | ```
74 |
75 | 这时,你也可以看到在app文件夹下的文件结构;
76 |
77 | ```bash
78 | bin: 启动目录 里面包含了一个启动文件 www 默认监听端口是 3000 (直接node www执行即可)
79 | node_modules:依赖的模块包
80 | public:存放静态资源
81 | routes:路由操作
82 | views:存放ejs模板引擎
83 | app.js:主文件
84 | package.json:项目描述文件
85 | ```
86 |
87 | 第一个Express应用“Hello World”
88 |
89 | 在这里,我们不使用npm构建的脚手架,而是向最开始那样直接在主目录中新建一个app.js文件。
90 |
91 | 在app.js中输入
92 |
93 | ```js
94 | const express = require('express'); //引入express模块
95 | var app= express(); //express()是express模块顶级函数
96 |
97 | app.get('/',function(req,res){ //访问根路径时输出hello world
98 | res.send(`hello world
`);
99 | });
100 |
101 | app.listen(8080); //设置访问端口号
102 | ```
103 |
104 | 命令行进入项目文件夹后,键入
105 |
106 | ```
107 | npm run start/npm start
108 | ```
109 |
110 | 即已开启服务器,接下来只需在浏览器中运行 http://localhost:3000/ 就可以访问到服务器得到响应后的数据
111 |
112 | ## 2.模板引擎简介
113 |
114 | 相比于jade模板引擎,ejs对原HTML语言就未作出结构上的改变,只不过在其交互数据方面做出了些许修改,相比于jade更加简单易用。因此其学习成本是很低的。您也可参考ejs官网:https://ejs.bootcss.com/
115 |
116 | 
117 |
118 | > 服务端渲染可以在源码中看到,客户端渲染不能再源码中看到
119 |
120 | ## 3.ejs基本使用
121 |
122 | 需要在应用中进行如下设置才能让 Express 渲染模板文件:
123 |
124 | 
125 |
126 | 这里我们使用如下配置文件:
127 |
128 | 可以通过下面的方式实现基本的ejs操作: app.js文件:
129 |
130 | ```js
131 | const express=require("express");
132 | const ejs=require("ejs");
133 | const fs=require("fs");
134 |
135 | var app=express();
136 |
137 | //引用ejs
138 | app.set('views',"./views"); //设置视图的对应目录
139 | app.set("view engine","ejs"); //设置默认的模板引擎
140 |
141 | app.get("/",function(req,res){
142 | res.render("index",{title: "express
"});
143 | //会去找views目录下的index.ejs文件
144 | });
145 |
146 | app.listen(8080);
147 | ```
148 |
149 | ejs文件:
150 |
151 | ```ejs
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 | <% for(var i=0;i<10;i++){ %>
160 | <%= i %>
161 | <% } %>
162 |
163 |
164 |
获取变量:
165 | <%- title %>
166 | <%= title %>
167 |
168 |
169 |
170 | ```
171 |
172 | 由此可以知道:
173 |
174 | ```ejs
175 | <% xxx %>:里面写入的是js语法,
176 | <%= xxx %>:里面是服务端发送给ejs模板转义后的变量,输出为原数据
177 | <%- xxx %>:里面也是服务端发送给ejs模板后的变量,解析html
178 | 如果写html的注释,那样会在源码中显示,下面这种ejs注释不会在源码中显示
179 | <%# 注释标签,不执行、不输出内容 %>
180 | ```
181 |
182 | 同理res.render()函数也是支持回调的:
183 |
184 | ```js
185 | res.render('user', { name: 'Tobi' }, function(err, html) {
186 | console.log(html);
187 | });
188 | ```
189 |
190 | 这样我们即可将看到html的内容。
191 |
192 | **关于res.redirect()**
193 |
194 | ```js
195 | const express = require('express');
196 | const router = express.Router();
197 |
198 | router.get('/', (req, res) => {
199 | res.render('login', {
200 | isShow: false,
201 | error: '',
202 | });
203 | });
204 |
205 | router.post('/', (req, res) => {
206 | if (req.body.username === 'ds' && req.body.password === '123') {
207 | console.log('登录成功');
208 | // res.send("成功")
209 | // 重定向到home
210 | res.redirect('/index');
211 | } else {
212 | console.log('登录失败');
213 | res.render('login', { error: '用户名密码不匹配', isShow: true });
214 | }
215 | });
216 |
217 | module.exports = router;
218 |
219 | ```
220 |
221 | ## 4.ejs 标签各种含义
222 |
223 | ```ejs
224 | <% '脚本' 标签,用于流程控制,无输出。
225 | <%_ 删除其前面的空格符
226 | <%= 输出数据到模板(输出是转义 HTML 标签)
227 | <%- 输出非转义的数据到模板
228 | <%# 注释标签,不执行、不输出内容
229 | <%% 输出字符串 '<%'
230 | %> 一般结束标签
231 | -%> 删除紧随其后的换行符
232 | _%> 将结束标签后面的空格符删除
233 | ```
234 |
235 | 
236 |
237 | 以上就为ejs基本用法,往后对数据库操作就直接把json数据从服务器返送给模板引擎就行;
238 |
239 | ## 5.导入公共模板样式
240 |
241 | `header.ejs`
242 |
243 | ```ejs
244 |
252 | ```
253 |
254 | `index.ejs`
255 |
256 | ```ejs
257 | <%- include("./header.ejs",{ isShowSchool:true }) %> index <%# 我的注释 %>
258 | ```
259 |
260 | 
261 |
262 |
--------------------------------------------------------------------------------
/docs/back_end/nodeJs/13.md:
--------------------------------------------------------------------------------
1 | # 13 【操作mysql数据库】
2 |
3 | ## 1.mysql 介绍
4 |
5 | 付费的商用数据库:
6 |
7 | - Oracle,典型的高富帅;
8 | - SQL Server,微软自家产品,Windows定制专款;
9 | - DB2,IBM的产品,听起来挺高端;
10 | - Sybase,曾经跟微软是好基友,后来关系破裂,现在家境惨淡。
11 |
12 | 这些数据库都是不开源而且付费的,最大的好处是花了钱出了问题可以找厂家解决,不过在Web的世界里,常常需要部署成千上万的数据库服务器,当然不能把大把大把的银子扔给厂家,所以,无论是Google、Facebook,还是国内的BAT,无一例外都选择了免费的开源数据库:
13 |
14 | - MySQL,大家都在用,一般错不了;
15 | - PostgreSQL,学术气息有点重,其实挺不错,但知名度没有MySQL高;
16 | - sqlite,嵌入式数据库,适合桌面和移动应用。
17 |
18 | 作为一个JavaScript全栈工程师,选择哪个免费数据库呢?当然是MySQL。因为MySQL普及率最高,出了错,可以很容易找到解决方法。而且,围绕MySQL有一大堆监控和运维的工具,安装和使用很方便。
19 |
20 | 
21 |
22 |
23 |
24 | ## 2.与非关系数据库区别
25 |
26 | 关系型和非关系型数据库的主要差异是数据存储的方式。关系型数据天然就是表格式的,因此存储在数据表的行和列中。数据表可以彼此关联协作存储,也很容易提取数据。
27 |
28 | 与其相反,非关系型数据不适合存储在数据表的行和列中,而是大块组合在一起。非关系型数据通常存储在数据集中,就像文档、键值对或者图结构。你的数据及其特性是选择数据存储和提取方式的首要影响因素。
29 |
30 | **关系型数据库最典型的数据结构是表,由二维表及其之间的联系所组成的一个数据组织**
31 | 优点:
32 | 1、易于维护:都是使用表结构,格式一致;
33 | 2、使用方便:SQL语言通用,可用于复杂查询;
34 | 3、复杂操作:支持SQL,可用于一个表以及多个表之间非常复杂的查询。
35 | 缺点:
36 | 1、读写性能比较差,尤其是海量数据的高效率读写;
37 | 2、固定的表结构,灵活度稍欠;
38 | 3、高并发读写需求,传统关系型数据库来说,硬盘I/O是一个很大的瓶颈。
39 |
40 | **非关系型数据库严格上不是一种数据库,应该是一种数据结构化存储方法的集合,可以是文档或者键值对等。**
41 |
42 | 优点:
43 |
44 | 1、格式灵活:存储数据的格式可以是key,value形式、文档形式、图片形式等等,文档形式、图片形式等等,使用灵活,应用场景广泛,而关系型数据库则只支持基础类型。
45 | 2、速度快:nosql可以使用硬盘或者随机存储器作为载体,而关系型数据库只能使用硬盘;
46 | 3、高扩展性;
47 | 4、成本低:nosql数据库部署简单,基本都是开源软件。
48 |
49 | 缺点:
50 |
51 | 1、不提供sql支持;
52 | 2、无事务处理;
53 | 3、数据结构相对复杂,复杂查询方面稍欠。
54 |
55 | ## 3.MySQL2的历史以及选择原因
56 |
57 | MySQL2 项目是 [MySQL-Native](https://github.com/sidorares/nodejs-mysql-native) 的延续。 协议解析器代码从头开始重写,api 更改为匹配流行的 [mysqljs/mysql](https://github.com/mysqljs/mysql)。 MySQL2 团队正在与 [mysqljs/mysql](https://github.com/mysqljs/mysql) 团队合作,将共享代码分解并移至 [mysqljs](https://github.com/mysqljs/mysql) 组织下。
58 |
59 | MySQL2 大部分 API 与 [mysqljs](https://github.com/mysqljs/mysql) 兼容,并支持大部分功能。 MySQL2 还提供了更多的附加功能
60 |
61 | - 更快、更好的性能
62 | - [支持预处理](https://github.com/sidorares/node-mysql2/tree/master/documentation/Prepared-Statements.md)
63 | - MySQL二进制日志协议
64 | - [MySQL Server](https://github.com/sidorares/node-mysql2/tree/master/documentation/MySQL-Server.md)
65 | - 对编码和排序规则有很好的支持
66 | - [Promise封装](https://github.com/sidorares/node-mysql2/tree/master/documentation/Promise-Wrapper.md)
67 | - 支持压缩
68 | - SSL 和 [Authentication Switch](https://github.com/sidorares/node-mysql2/tree/master/documentation/Authentication-Switch.md)
69 | - [自定义流](https://github.com/sidorares/node-mysql2/tree/master/documentation/Extras.md)
70 | - [连接池](https://github.com/sidorares/node-mysql2/tree/master/documentation_zh-cn#using-connection-pools)
71 |
72 | MySQL2 可以跨平台使用,毫无疑问可以安装在 Linux、Mac OS 或 Windows 上。
73 |
74 | ```bash
75 | npm install --save mysql2
76 | ```
77 |
78 | ## 4.连接数据库
79 |
80 | `config/db.config.js`
81 |
82 | ```js
83 | const mysql = require('mysql2/promise')
84 |
85 | // 通过createPool方法连接服务器
86 | const db = mysql.createPool({
87 | host: '127.0.0.1', // 表示连接某个服务器上的mysql数据库
88 | user: 'root', // 数据库的用户名 (默认为root)
89 | password: '123456', // 数据库的密码 (默认为root)
90 | database: 'dbtest11', // 创建的本地数据库名称
91 | })
92 |
93 | // 测试数据库是否连接成功
94 | db.getConnection((err, conn) => {
95 | conn.connect(err => {
96 | if (err) {
97 | console.log('连接失败~')
98 | } else {
99 | console.log('连接成功~')
100 | }
101 | })
102 | })
103 |
104 | module.exports = db
105 | ```
106 |
107 | ## 5.查询
108 |
109 | - 导入mysql
110 | - 通过createPool方法将mysql数据库连接到服务器,并声明一个db变量
111 | - 通过db.query方法测试是否连接成功
112 | - 将数据返回给客户端
113 | - 导入express
114 | - 创建服务器
115 | - 启动服务器
116 | - 注册路由
117 | - 通过db.query(查询数据库)来执行sql语句
118 | - 如果执行成功将数据响应给客户端
119 |
120 | ```js
121 | var express = require('express')
122 | const db = require('../config/db.config')
123 | var router = express.Router()
124 |
125 | // 通过nodejs获取数据库中的数据 并返回给客户端-
126 | router.get('/', async (req, res) => {
127 | // 通过db.query方法来执行mysql 测试是否连接成功
128 | // 查询语句 data 得到的是一个数组, 增删改得到的是受影响的行数
129 | let users = await db.query('select * from users')
130 | console.log(users[0])
131 | res.send({
132 | ok: 1,
133 | data: users[0],
134 | })
135 | })
136 |
137 | module.exports = router
138 | ```
139 |
140 | 控制台输出:
141 |
142 | 
143 |
144 | 返回的数据:
145 |
146 | 
147 |
148 | ## 6.插入
149 |
150 | ```js
151 | // 给user中添加用户名和密码
152 | router.get('/addUser', async (req, res) => {
153 | const sql = 'insert into users (userid,department_id) values (?,?)' // 构建sql语句
154 | // 执行sql语句
155 | let ret = await db.query(sql, ['Mary', 2])
156 | console.log(ret)
157 | res.send({
158 | ok: 1,
159 | })
160 | })
161 | ```
162 |
163 | 控制台输出:
164 |
165 | 
166 |
167 | ## 7.修改
168 |
169 | ````js
170 | // 修改数据
171 | router.get('/updateUser', async (req, res) => {
172 | const sql = 'update users set userid=?,department_id=? where id=?' // 构建sql语句
173 | // 执行sql语句
174 | let ret = await db.query(sql, ['Jerry', 10, 8])
175 | console.log(ret)
176 | res.send({
177 | ok: 1,
178 | })
179 | })
180 | ````
181 |
182 | 控制台输出:
183 |
184 | 
185 |
186 | ## 8.删除
187 |
188 | ```js
189 | // 删除数据
190 | router.get('/deleteUser', async (req, res) => {
191 | const sql = 'delete from users where id=?' // 构建sql语句
192 | // 执行sql语句
193 | let ret = await db.query(sql, [8])
194 | console.log(ret)
195 | res.send({
196 | ok: 1,
197 | })
198 | })
199 | ```
200 |
201 | 控制台输出:
202 |
203 | 
--------------------------------------------------------------------------------
/docs/deploy/DNS.md:
--------------------------------------------------------------------------------
1 | ---
2 | article: false
3 | title: 域名 DNS 托管
4 | icon: sitemap
5 | order: 5
6 | ---
7 |
8 | 国内访问为主的话,域名建议备案后托管在国内厂商。之前试过 Cloudflare,光域名解析就用了 500 ms,换回阿里云后速度稳定许多。
9 |
10 | - DNS 迁移是在域名管理商处修改。比如我的域名是在阿里云购买,试过 DNS 迁移到 Cloudflare,之后再次迁移 DNS,需要回到阿里云操作。
11 | - 如果阿里云的安全验证一直被卡住,可以换个浏览器,比如 Firefox。
12 | - 子域名可以使用 [NS 记录](https://help.aliyun.com/document_detail/29725.html?#h2-ns-7),托管到其他域名服务商。但 Cloudflare 不支持单独子域名托管。
13 |
14 | 域名 DNS 服务器修改(阿里云):
15 |
--------------------------------------------------------------------------------
/docs/deploy/GitHub.md:
--------------------------------------------------------------------------------
1 | ---
2 | article: false
3 | title: GitHub
4 | icon: github
5 | order: 3
6 | ---
7 |
8 | ## GitHub Actions
9 |
10 | GitHub Actions 是一个持续集成和持续交付 (CI/CD) 平台,可用于自动执行构建、测试和部署管道。您可以创建工作流程来构建和测试存储库的每个拉取请求,或将合并的拉取请求部署到生产环境。将 GitHub Actions 命令保存为 `main.yml`,放于 `.github\workflows` 目录下,repo 发生指定调节的改变时,Actions 会自动运行。^[[了解 GitHub Actions](https://docs.github.com/cn/actions/learn-github-actions/understanding-github-actions)]
11 |
12 | - [GitHub Actions 官方市场](https://github.com/marketplace?type=actions)
13 | - [Awesome Actions](https://github.com/sdras/awesome-actions)
14 |
15 | 如果 GitHub Actions 命令中有涉及密码等私密信息,则进入项目仓库的「setting」>「Secrets」>「Action」,添加密钥进行加密处理。比如新建密钥 PERSONAL_TOKEN,Actions 命令中使用 `${{ secrets.PERSONAL_TOKEN }}` 来指代该密钥。
16 |
17 | ### 不同仓库间复制
18 |
19 | 复制文件到目的地,文档没变化则不会执行。案例为将当前仓库 main 分支下 docs 的 README.md 文件复制到另一个仓库 rockbenben/LearnData/ 路径下,如果目标路径存在相同文件,则将覆盖。如果让 `clean: true` 生效,Actions 会将目标路径情况,然后执行复制。
20 |
21 | 此动作需按 [Creating a personal access token](https://docs.github.com/cn/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token#creating-a-token) 建立[个人访问令牌](https://github.com/settings/tokens),勾选权限「repo Full control of private repositories」,然后将该 token 值其保存在项目仓库的 Action 密钥。
22 |
23 | ```yml
24 | - name: Copy file
25 | uses: andstor/copycat-action@v3
26 | with:
27 | personal_token: ${{ secrets.PERSONAL_TOKEN }}
28 | src_path: docs/README.md
29 | dst_path: /
30 | dst_owner: rockbenben
31 | dst_repo_name: LearnData
32 | dst_branch: main
33 | src_branch: main
34 | #clean: true
35 | ```
36 |
37 | ### Actions 失败重试
38 |
39 | 在 job 和 step 中使用 if 语句,只有满足条件时才执行具体的 job 或 step。^[[最全总结,GitHub Action 自动化部署](https://blog.csdn.net/Ber_Bai/article/details/120310024)]
40 |
41 | ```bash
42 | # 任务状态检查函数
43 | success() # 当上一步执行成功时返回 true
44 | always() # 总是返回 true
45 | cancelled() # 当 workflow 被取消时返回 true
46 | failure() # 当上一步执行失败时返回 true
47 | ```
48 |
49 | first_step 会总是执行,second_step 需要上一步 first_step 执行成功才会执行,third_step 只有上一步 second_step 执行失败才执行。当 third_step 与 second_step 命令相同时,就可以达到失败重试的效果了。
50 |
51 | ```yml
52 | jobs:
53 | first_job:
54 | name: My first job
55 | runs-on: ubuntu-latest
56 | steps:
57 | - name: first_step
58 | if: always()
59 |
60 | - name: second_step
61 | if: success()
62 |
63 | - name: third_step
64 | if: failure()
65 | ```
66 |
67 | ### uses 版本号
68 |
69 | `uses: SamKirkland/FTP-Deploy-Action@4.3.1`:uses 会指定此步骤运行 SamKirkland/FTP-Deploy-Action 存储库中的 4.3.1 版本。
70 |
71 | 但有时 Actions 的版本不会这么快更新,又必须使用最新版,可以将版本号改为 branch name,比如 `uses: SamKirkland/FTP-Deploy-Action@master`。
72 |
73 | ## 常见问题
74 |
75 | ### GitHub 忽略指定文件
76 |
77 | 项目路径新建一个命名为 .gitignore 的文件,将想要忽略的文件夹和文件写入 .gitignore 文件,换行分隔。
78 |
79 | 比如要忽略 node_modules 文件夹,就直接在文件中输入 node_modules。
80 |
--------------------------------------------------------------------------------
/docs/deploy/Static.md:
--------------------------------------------------------------------------------
1 | ---
2 | article: false
3 | title: 静态部署
4 | icon: generic
5 | order: 1
6 | ---
7 |
8 | ## 静态托管
9 |
10 | 如果国内静态资源库没有你要的静态包,推荐用 `npm i` 命令将静态包下载到本地,并部署到阿里云/七牛云的国内服务器上,避免网页受 UNPKG 和 jsDelivr 屏蔽影响而出现偏差。
11 |
12 | 静态资源库:
13 |
14 | - [字节 CDN](https://cdn.bytedance.com/):国内测速表现最佳,缓存过期时间最长设置一年。
15 | - [Staticfile CDN](https://www.staticfile.org/):CDN 加速由七牛云提供。
16 |
17 | emoji 等可以使用静态资源库上的项目,比如 twemoji,上面有集成 png 图片。
18 |
19 | ### NPM 包
20 |
21 | - UNPKG:**有墙风险且不稳定**,默认为最新版本,无需 `@latest` 标签。
22 | - 将静态文件发布为 npm 包,参考[一分钟教你发布 npm 包](https://segmentfault.com/a/1190000023075167)。
23 | - 加速:在 [npm 官方源](https://www.npmjs.com/)中搜索包位置,然后使用前缀 `https://unpkg.com/`。
24 | - [NPM MIRROR](https://npmmirror.com/):NPM 项目的国内镜像镜像,不能做静态托管用途。`https://registry.npmmirror.com/项目名/版本号` 可以看见项目的各种信息,但看不了里面的文件。
25 | - UNPKG 镜像:有资源可以用服务器自建服务,反向代理 unpkg。
26 | - ~~饿了么 CDN(已关):国内唯一能用的 npm 镜像,2022.07.13 发现外部访问被拒绝。之前饿了么并没说支持对外,可能已经彻底取消了。使用饿了么 CDN 时,注意 `https://npm.elemecdn.com/react@latest/` 需要时间更新,具体频率未知,可固定大版本号来获取更新 `https://npm.elemecdn.com/react@^18/`。~~
27 | - GitHub:基于 GitHub 公共仓库的资源托管,资源不会失效,但有时需要根据 CDN 服务商而更换域名。
28 | - ~~[Statically](https://statically.io/):jsDeliver 的替代品,在中国大陆所有地区连接异常。~~
29 | - ~~jsDelivr(已墙):速度最快,原本是最稳的,但域名暴雷后,经常断开,2022.06.01 彻底打不开。配合 Github action,更新后自动访问 jsdelivr CDN 缓存刷新链接,保持页面常新。刷新命令参考 `curl https://purge.jsdelivr.net/gh/username/project/file`。~~
30 |
31 | 第三方托管过于不稳定,最终我转为自托管 oss.newzone.top。
32 |
33 | ### 部署平台
34 |
35 | - Cloudflare:Pages 和 Workers 两类部署方式。
36 | - [Workers](../deploy/Cloudflare.html#反向代理):复制镜像网站,可直接访问,但反向代理稳定性成疑。
37 | - Pages:部署简单,外网速度很快,但国内速度不稳,而且 page.dev 域名有时会被墙,可购买便宜的临时域名(一年)来解决该问题。
38 | - Netlify:国内速度慢点,图片容易卡死,但还算稳定。
39 | - Vercel:推荐使用 GitHub 账户登录,有可能需要绑定国外手机号(不支持 Voice)。2022.08.26,「\*.vercel.app」域名被 DNS 污染,需要绑定自定义域名。
40 | - AWS: 邮箱注册,不过需要信用卡认证。
41 | - 国内平台:Gitee、WuliHub、CODING,都需要实名认证。
42 |
43 | ### IPFS
44 |
45 | IPFS 无需服务器就可建立静态网站,号称永不失效,但**国内稳定性成疑问,实用性一般**。IPFS 托管在一个网关上,并不会自动复制到所有网关。
46 |
47 | [pinata](https://pinata.cloud/) 上传网站构建的目录文件夹,上传后,即可通过 IPFS Hash 访问。网站目录中必须有 index.html,否则网页中将显示网站目录。即使有 index.html,其他人在拥有 CID 后,可以通过 IPFS Desktop 来获取网站的完整目录。为确保私密性,建议只上传单文件。使用单文件 CID 视为单一网站,不可调用原目录中的文件。^[[How to Easily Host a Website on IPFS](https://medium.com/pinata/how-to-easily-host-a-website-on-ipfs-9d842b5d6a01)]
48 |
49 | 上传 ipfs 到 pinata 之后,cloudflare 等其他网关不一定会完全复制文件,php 无法抓取加载,所以不建议使用 cloudflare 网关。
50 |
51 | cloudflare 接管 pinata 后,ipfs 域名需通过「pinata 托管」>「cloudflare DNS」>「cloudflare SSL」。如果中途将 DNS 指向 `http://gateway.pinata.cloud` 等非 cloudflare ipfs 网关域名,cloudflare SSL 证书将失效。即便把链接改为非加密的 http,pinata 依然会视之为无效链接而拒绝访问。
52 |
53 | 对于文件较少且链接有效的域名,可按 [Cloudflare IPFS](https://www.cloudflare.com/zh-cn/distributed-web-gateway/) 页面说明来设置 DNS,提交 IPFS 域名 30 分钟后,即可获取 SSL 证书。
54 |
55 | 1. 添加 CNAME 记录,将你的 IPFS 域名 (xxx.example.com) 指向 `cloudflare-ipfs.com`。
56 | 2. `_dnslink.xxx.example.com` 设置为 `dnslink=/ipfs/`。
57 |
58 | ## GitHub 同步到 VPS
59 |
60 | 代码、文章推送到 GitHub 后,会自动生成可访问的网页,但国内访问 GitHub Pages 的速度极不稳定,为了确保网站能被正常访问,必须增加国内的访问节点。
61 |
62 | 很多人选择 Gitee Pages 作为国内节点,GitHub Actions 将新文档同步到 Gitee,生成位于国内的静态页面 Gitee Pages。但是,Gitee Pages 的限制非常多,免费版无法自定义域名,必须实名验证,更别提近期的下架风波。因此,我没选 Gitee,而是把文档同步到国内服务器(域名需备案)。
63 |
64 | !> 注意:文件夹不要有大写字母,否则同步时容易出错。
65 |
66 | ### 同步到 FTP
67 |
68 | 如果你有 FTP 服务器,可使用 [FTP-Deploy-Action](https://github.com/SamKirkland/FTP-Deploy-Action) 将 github 代码推送到服务器上。Actions 步骤参考 [GitHub 说明](../deploy/GitHub.html)。
69 |
70 | ```shell
71 | on: push
72 | name: 🚀 Deploy website on push
73 | jobs:
74 | web-deploy:
75 | name: 🎉 Deploy
76 | runs-on: ubuntu-latest
77 | steps:
78 | - name: 🚚 Get latest code
79 | uses: actions/checkout@v3
80 |
81 | - name: 📂 Sync files
82 | uses: SamKirkland/FTP-Deploy-Action@4.3.0
83 | with:
84 | server: ${{ secrets.ftp_host }}
85 | username: ${{ secrets.ftp_username }}
86 | password: ${{ secrets.ftp_password }}
87 | port: ${{ secrets.ftp_port }} # 建议更改默认的 21 端口
88 | ```
89 |
90 | 新建 FTP 时,需在云服务商的安全组和服务器上开放 FTP 端口,并临时暂停宝塔系统加固等安全插件(新建 FTP 容易与安全插件冲突)。
91 |
92 | 如果出现 `FTPError: 530 Login authentication failed`,则说明 FTP 密码错误或账号不存在,需用 FileZilla 测试 FTP 的有效性。确认 FTP 无效后,检查 FTP 密码是否填写正确,是否只有大小写字母和数字。如果密码错误,则在 github secrets 重新 update 密钥。如果密码正确,则进入 `/www/server/pure-ftpd/etc/pureftpd.passwd`,检查是否有该 FTP 账户。没有 FTP 账户的话,**暂停宝塔系统加固**等安全插件后,重新新建 FTP。
93 |
94 | 如果出现 `Error: Timeout (control socket)`,则说明同步服务器超时,可进入 Actions 页面点击右侧按钮「Re-run all jobs」,重新进行部署。如果错误连续出现,可以尝试关闭防火墙,测试是否 GitHub 服务器被拉黑了。
95 |
96 | ### SSH 同步
97 |
98 | 如果你拥有服务器所有权限,可以使用 [web-deploy](https://github.com/SamKirkland/web-deploy) 以 SSH 同步方式发布页面。但与 FTP 同步方式相比,是否安全性、速度、时间有区别,我还没测试过,仅做记录,
99 |
100 | ### 同步到 oss
101 |
102 | 如果没有服务器,可以把文件部署在云运营商的云存储上。比如用 [aliyun-oss-website-action](https://github.com/marketplace/actions/aliyun-oss-website-action),将 repo 文件 build 成网站文件,然后同步到阿里云 oss 并运行网站。
103 |
104 | ```shell
105 | name: deploy md to oss
106 | on:
107 | push:
108 | branches: [ "main" ]
109 | pull_request:
110 | branches: [ "main" ]
111 | jobs:
112 | build:
113 | runs-on: ubuntu-latest
114 | steps:
115 | # load repo to /github/workspace
116 | - uses: actions/checkout@v3
117 | - name: Use Node.js
118 | uses: actions/setup-node@v3
119 | with:
120 | node-version: '14.x'
121 | # 打包文档命令
122 | # - run: npm install yarn@1.22.4 -g
123 | # - run: yarn install
124 | # - run: yarn docs:build #需要配合 yarn 的 package.json
125 | - name: aliyun-oss-website-action
126 | uses: fangbinwei/aliyun-oss-website-action@v1.3.0
127 | with:
128 | accessKeyId: ${{ secrets.ACCESS_KEY_ID }}
129 | accessKeySecret: ${{ secrets.ACCESS_KEY_SECRET }}
130 | bucket: learndata-notes
131 | # use your own endpoint
132 | endpoint: oss-cn-shanghai.aliyuncs.com
133 | # 全目录上传
134 | folder: .
135 | # 不上传的文件
136 | exclude: |
137 | .github/
138 | .gitattributes
139 | ```
140 |
--------------------------------------------------------------------------------
/docs/deploy/VPS.md:
--------------------------------------------------------------------------------
1 | ---
2 | article: false
3 | title: 服务器 VPS
4 | icon: IO
5 | order: 2
6 | ---
7 |
8 | ## 环境部署
9 |
10 | 部署应用前,为服务器配置好包管理工具,以便节省部署时间。主流的前端包管理工具有 npm、yarn、pnpm、以及国内的镜像 cnpm、tyarn 等,这些包管理器都是基于 nodejs。
11 |
12 | ### 包管理安装
13 |
14 | 通过集成了 npm 的 [Node.js](https://nodejs.org/en/download/) 来安装 npm,然后执行 npm i 命令安装其他。
15 |
16 | 全局安装 yarn 是 `npm i yarn -g`,pnpm 是 `npm i pnpm -g`。如果不想全局安装,则去除 `-g`。
17 |
18 | ### 包管理源
19 |
20 | 包管理源的修改命令类似,将下方的 npm 替换 yarn 或 pnpm 即可修改包管理源。
21 |
22 | ```shell
23 | #查看源
24 | npm config get registry
25 | #更换国内源
26 | npm config set registry https://registry.npmmirror.com/
27 | #换回默认源
28 | npm config set registry https://registry.npmjs.org/
29 | ```
30 |
31 | ### 部署包
32 |
33 | npm、yarn 和 pnpm 的包安装及管理命令。
34 |
35 | ```shell
36 | #全局安装
37 | npm i 包 -g
38 | yarn global add 包
39 | pnpm add 包 -g
40 |
41 | #移除全局包
42 | pnpm remove 包 --global
43 | #更新全局包
44 | pnpm upgrade 包 --global
45 |
46 | #升级当前目录的依赖以确保你的项目只包含单个版本的相关包
47 | #本方法能解决大部分的部署报错
48 | npm i && npm update
49 | yarn && yarn upgrade
50 | pnpm i && pnpm up
51 | ```
52 |
53 | ### 本地测试
54 |
55 | 有些静态文件不支持直接打开,需要架构本地服务器来进行测试。
56 |
57 | ```shell
58 | # 安装静态服务 anywhere
59 | npm install anywhere -g
60 | # 进入静态页面存放目录,执行 anywhere
61 | anywhere -p 8081
62 | ```
63 |
64 | ## 网站字体
65 |
66 | 网站为了提高访问速度并保持设计的一致性,通常会选默认字体。这导致网站设计难以突出重点。针对这点,我通常会修改网站的导航栏字体,将其从默认字体改为 `思源黑体 - 粗`。
67 |
68 | 1. 进入 [iconfont‑webfont](https://www.iconfont.cn/webfont),输入导航栏内所有文字,并设置所需字体。
69 | 2. 点击「生成字体」后,在选中字体的下方,点击「本地下载」。
70 | 3. 将字体包上传到服务器,修改新字体的位置参数。
71 | 4. 在导航栏的 `class` 属性中添加 `web-font`。
72 |
73 | ## 米拓
74 |
75 | - 后台忘记密码,使用 [Metinfo 米拓重置工具](https://www.metinfo.cn/download/54.html)。
76 | - metinfo 新版静态页会删除 index.html,后续都改用 index.php。
77 |
78 | ## 服务器 ECS
79 |
80 | 服务器系统为 Debian 11。
81 |
82 | ```shell
83 | apt-get update # 从数据源更新软件包的列表,运行产生软件包数据库
84 | apt-get install wget && apt-get install sudo # 安装 wget 和 sudo
85 |
86 | # 大版本升级必须先建立快照
87 | apt-get upgrade # 更新所有软件包(慎用,不要用!)之前 CentOS 系统错误就是使用了 upgrade 命令。
88 |
89 | # 新建用户,非 root 权限
90 | adduser xxx
91 | # 为新用户设置密码
92 | passwd xxx
93 | ```
94 |
95 | ### 网站重定向
96 |
97 | 更改 nginx 配置后,nginx 重载配置后实现网站重定向。`$1` 表示第一个 `()` 内的正则匹配内容,`$2` 为第二个。^[[Nginx rewrite 设置](https://www.w3cschool.cn/nginxsysc/nginxsysc-rewrite.html)]
98 |
99 | [网站重定向](https://www.jb51.net/article/146957.htm)
100 |
101 | ```ini
102 | #隐性链接跳转
103 | location /xx1 {proxy_pass }
104 |
105 | #404 前,将旧文章链接格式转为新的,使用绝对路径
106 | location ^~ /p{
107 | rewrite ^/p/(.*)$ https://newzone.top/posts/$1.html;
108 | }
109 |
110 | # huginn 设置中 location 添加 301 定向,兼容老路径链接
111 | if ( $request_uri = "/users/1/web_requests/21/guoke.xml" ) {
112 | rewrite ^ http://xxx.com/users/1/web_requests/19/guoke.xml permanent;
113 | }
114 |
115 | #只匹配主页,将主页跳转为其中一个子页面
116 | location = / {
117 | rewrite https://xxx.com/ permanent;
118 | }
119 | ```
120 |
121 | ### 全新安装服务器
122 |
123 | 1. 安装[宝塔面板](https://www.bt.cn/bbs/thread-19376-1-1.html)。
124 | 2. 删除阿里云主机监控。
125 |
126 | ```shell
127 | service aegis stop #停止服务
128 | chkconfig --del aegis # 删除服务
129 | ```
130 |
131 | 3. 配置[阿里云端口开放](https://www.bt.cn/bbs/thread-2897-1-1.html),导入安全规则。
132 | 4. 宝塔上修改默认账号密码,并修改登录 22 的默认 SSH 端口。如果开通了 FTP,修改 FTP 端口。
133 | 5. 选择「网站」>「添加站点」,将站点根目录放在 /www/wwwroot/xxx,同时新建数据库。
134 | 6. 上传全站文件并解压,然后按照安装提示重新安装一次,最后导入备份数据库。
135 | 7. 404.html 起效,宝塔网站配置文件中,删除 `error_page 404 /404.html;` 中的 `#`。
136 | 8. SSL 证书设置,开启强制 HTTPS;PHP 版本;301 重定向;添加伪静态设置(metinfo 或其他网站后台有代码)。如果 301 设置失败,直接在「伪静态」配置中,放入跳转代码。
137 | 9. 服务器设置参考 [NginxConfig](https://www.digitalocean.com/community/tools/nginx?global.app.lang=zhCN) 适合新手配置高性能、安全、稳定的 NGINX 服务器的最简单方法。
138 | 10. [ECS 宝塔设置优化](https://www.bt.cn/bbs/forum.php?mod=viewthread&tid=3117):
139 |
140 | - 添加计划任务,定期释放内存,建议设置每天释放一次,执行时机为半夜,如:04:00。
141 | - 打开 Linux 工具箱添加 Swap。Swap 推荐与物理内存相同。
142 | - 安装 PHP 缓存扩展,尽量使用更高的 PHP 版本,另外安装 opcache(脚本缓存)、redis(内容缓存)、imagemagick、fileinfo、exif。
143 | - Redis 优化,在/etc/sysctl.conf 中添加 `net.core.somaxconn = 2048`,然后终端运行 `sysctl -p`。
144 |
145 | 11. 防火墙白名单(自定义),如:添加 url 规则 `^/rss.php` 到防火墙 URL 白名单,防止 rss 服务被屏蔽。
146 |
147 | ### 服务器迁移
148 |
149 | 1. 购买按量付费服务器。
150 | 2. 用[服务器迁移中心 SMC](https://smc.console.aliyun.com/overview) 将旧服务器同步到临时服务器。
151 | 3. 将域名解析到临时系统,确定服务基本正常。
152 | 4. 对旧服务器先建立云盘快照,然后更换操作系统,进行全新部署。
153 | 5. 对比新旧服务器,确认配置正常。
154 |
155 | ## 常见问题
156 |
157 | ### CPU 100%
158 |
159 | 当服务器 CPU 或内存突然飙升 100% 时,依次排除当前运行进程,检查是否安装更新了插件、应用或服务。
160 |
161 | 如果找不到原因,可以临时设置定期任务。每隔 3 小时重启一次 nginx/apache。有时重启不正常,因此重启命令后 10 秒,再启动一次 nginx/apache。
162 |
163 | ```shell
164 | /etc/init.d/nginx restart
165 | sleep 10s
166 | /etc/init.d/nginx start
167 | ```
168 |
169 | ### SSL 证书
170 |
171 | 如果 SSL 证书部署报错,可以按自动生成来部署。
172 |
173 | ```shell
174 | #证书设置修改 /www/server/panel/vhost/nginx
175 | if ($server_port !~ 443){
176 | rewrite ^(.*) permanent;
177 | }
178 | #证书修改
179 | /www/server/panel/vhost/cert/
180 | #证书位置
181 | /www/server/panel/vhost/ssl
182 | ```
183 |
184 | ### CORS 跨域
185 |
186 | POST 表单等操作需要涉及第三方 API,需要添加扩域域名,避免 CORS 报错。
187 |
188 | ```bash
189 | add_header Access-Control-Allow-Origin "*";
190 | add_header Access-Control-Allow-Credentials "true";
191 | add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
192 | add_header Access-Control-Allow-Headers "DNT,web-token,app-token,Authorization,Accept,Origin,Keep-Alive,User-Agent,X-Mx-ReqToken,X-Data-Type,X-Auth-Token,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range";
193 | add_header Access-Control-Expose-Headers "Content-Length,Content-Range";
194 | ```
195 |
196 | ### 数据库出错解决
197 |
198 | 1. mysql 配置中 `mysqld` 在一行添加 `innodb_force_recovery=4`,数值可以 0-6,数值越大对数据库损害越大。正常启动 mysql 后,备份所有数据库和管理密码,并下载到本地。
199 | 2. 在宝塔的「数据库」中删除所有数据库,卸载并重装 mysql。
200 | 3. 重新导入数据库。
201 |
202 | ### piwik 手动升级
203 |
204 | Matomo/Piwik 是免费的统计服务。有时无法使用自动安装包,需要手动升级。
205 |
206 | 1. 下载最新版应用,并解压到服务器。
207 | 2. 将原目录中的 config/config.ini.php 粘贴到新版中,然后就可以更新数据库进行升级了。
208 | 3. 选择「设置」>「系统」>「地理位置」,拖到页面底部,按页面要求下载 DBIP 包,并重命名保存为 `/www/wwwroot/piwik/misc/DBIP-City.mmdb`。
209 |
--------------------------------------------------------------------------------
/docs/front_end/css_advanced/scss/02.md:
--------------------------------------------------------------------------------
1 | # 02 【Sass语法介绍-变量】
2 |
3 | sass有两种语法格式Sass(早期的缩进格式:Indented Sass)和SCSS(Sassy CSS)
4 |
5 | 目前最常用的是SCSS,任何css文件将后缀改为scss,都可以直接使用`Sassy CSS`语法编写。
6 |
7 | **所有有效的 CSS 也同样都是有效的 SCSS。**
8 |
9 | # Sass语法介绍-变量
10 |
11 | ## 1.前言
12 |
13 | Sass 为 CSS 引入了变量这一功能,在实际项目中使用最普遍的除了 Sass 嵌套 就是 Sass 变量了,你可以把 CSS 的某个**属性值**定义为变量,然后在项目中任何需要它的地方来使用它。本节主要讲解 Sass 变量的主要语法:变量的声明、引用、作用域等,同时还会讲解在实际项目中一般是如何来维护 Sass 变量的。
14 |
15 | ## 2.什么是 Sass 变量 ?
16 |
17 | Sass 简介中提到 Sass是 CSS的扩展语言,变量是 CSS的扩展功能。
18 | 举个例子,假如我们项目中很多地方要设置一个字体颜色为红色,那么我们完全可以把这个颜色抽出来作为一个**变量**,然后在需要设置字体颜色的地方引用这个变量。这样有一个好处就是,假如产品大大说要修改所有字体颜色的时候,我们就不需要每处都去修改了,直接更改变量的值就 OK 了,我们用 Sass 代码来直观的感受下:
19 |
20 | ```scss
21 | $variable: red;
22 |
23 | .title {
24 | color: $variable;
25 | }
26 | h1 {
27 | color: $variable;
28 | }
29 | ```
30 |
31 | 可以看到上面的代码,我们定义了 $variable 这个变量,然后在多个元素的样式中使用它,那么变量的值都可以是什么呢?这个一定要记住,变量的值可以是:
32 |
33 | - 字符串
34 | - 数字
35 | - 颜色值
36 | - 布尔值
37 | - 列表
38 | - Null 值
39 |
40 | 下面我们将详细的讲解 Sass 变量的语法。
41 |
42 | ## 3.使用变量
43 |
44 | sass使用`$`符号来标识变量。
45 |
46 | 变量的作用就是,让你在整个样式表中保存并重用一些信息或数据。
47 |
48 | 比如存储颜色(color)、字体集,或任何你想重用的CSS值。
49 |
50 | ### 3.1 变量声明
51 |
52 | 和css属性的声明(`property declaration`)很像!
53 |
54 | 如,声明值为 `#F90` 的变量 `$highlight-color`,字体集变量:
55 |
56 | ```scss
57 | $highlight-color: #F90;
58 | $font-stack: Helvetica, sans-serif;
59 |
60 | body {
61 | font: 100% $font-stack;
62 | color: $highlight-color;
63 | }
64 | ```
65 |
66 | 输出结果为:
67 |
68 | ```css
69 | body {
70 | font: 100% Helvetica, sans-serif;
71 | color: #F90;
72 | }
73 | ```
74 |
75 | **变量有作用域,当变量定义在css规则块内,则该变量只能在此规则块内使用。**
76 |
77 | ### 3.2 变量引用
78 |
79 | 凡是css属性的标准值(比如说1px或者bold)可存在的地方,就可以使用变量。
80 |
81 | css生成时,变量会被它们的值所替代。
82 |
83 | ```scss
84 | $color:#A34554;
85 |
86 | .box {
87 | width: 300px;
88 | height: 400px;
89 | &-left{
90 | width: 30%;
91 | color: $color;
92 | }
93 | }
94 | ```
95 |
96 | 生成css为:
97 |
98 | ```css
99 | .box {
100 | width: 300px;
101 | height: 400px;
102 | }
103 | .box-left{
104 | width: 30%;
105 | color: #A34554;
106 | }
107 | ```
108 |
109 | 声明变量时,变量的值也可以引用其他变量,如下 `$highlight-border` 变量中使用了 `$highlight-color` 变量:
110 |
111 | ```scss
112 | $highlight-color: #F90;
113 | $highlight-border: 1px solid $highlight-color;
114 | .selected {
115 | border: $highlight-border;
116 | }
117 |
118 | //编译后
119 |
120 | .selected {
121 | border: 1px solid #F90;
122 | }
123 | ```
124 |
125 | ### 3.3 变量名中的中横线(`hyphen`)和下划线(`underscore`)
126 |
127 | sass的变量名可以使用中划线和下划线,用中划线声明的变量可以使用下划线的方式引用,反之亦然。
128 |
129 | 也就是,变量名中的中横线和下划线没有区别,两者互通。
130 |
131 | 比如下面的示例,中横线的`$link-color`,可以通过下划线的`$link_color`引用。
132 |
133 | ```scss
134 | $link-color: blue;
135 | a {
136 | color: $link_color;
137 | }
138 |
139 | //编译后
140 |
141 | a {
142 | color: blue;
143 | }
144 | ```
145 |
146 | > 相对,使用中横线更普遍些!
147 |
148 | ## 4.变量的作用域
149 |
150 | 从 Sass 3.4.x 版本开始,Sass 中开始有作用域的概念。和 javascript 中的变量类似,Sass 的变量也是有作用域这个概念的,也有全局作用域和局部作用域之分,我们举个例子来看下:
151 |
152 | ```scss
153 | $main-color: red;
154 | h1 {
155 | $main-color: green; // 局部变量
156 | color:$main-color;
157 | }
158 | h2 {
159 | color:$main-color;
160 | }
161 | ```
162 |
163 | 我们看到在第一行代码我们声明了一个全局变量 $main-color ,在 h1 的样式中我们又声明了一个和全局变量同名的 $main-color ,在 h1 样式中声明的这个 $main-color 就是局部变量,在 h1 的样式中会引用局部变量而不是全局变量,最终转换为 CSS 的代码如下:
164 |
165 | ```css
166 | h1 {
167 | color: green;
168 | }
169 |
170 | h2 {
171 | color: red;
172 | }
173 | ```
174 |
175 | ### 4.1 !global 标识符
176 |
177 | 上面我们讲解了局部变量和全局变量,那么如果我想用局部变量去改变全局变量呢? Sass 允许使用 **!global** 标识符来设置局部变量为全局,以此来改变局部变量的作用范围,我们还是用上面的代码,来改变局部变量的作用域为全局:
178 |
179 | ```scss
180 | $main-color: red;
181 | h1 {
182 | $main-color: green!global;
183 | color:$main-color;
184 | }
185 | h2 {
186 | color:$main-color;
187 | }
188 | ```
189 |
190 | 我们来看下,上面这段转换为 CSS 是这样的:
191 |
192 | ```css
193 | h1 {
194 | color: green;
195 | }
196 |
197 | h2 {
198 | color: green;
199 | }
200 | ```
201 |
202 | 可以看到我们覆盖掉了全局变量 $main-color 的值 red ,不过请你记住,在大型项目中尽量不要使用这种方式去改变全局变量,这可能会影响到其他页面的样式改变!
203 |
204 | ### 4.2 !default标识符
205 |
206 | 一般来说我们反复的声明一个重名变量,那么最后一个声明的变量值会覆盖上面所有的,比如像下面这样:
207 |
208 | ```scss
209 | $main-color: red;
210 | $main-color: green;
211 | h1 {
212 | color:$main-color;
213 | }
214 | ```
215 |
216 | 那么最后编译的时候会使用最后一次声明的变量值,也就是 green ,我们看下编译后的代码:
217 |
218 | ```css
219 | h1 {
220 | color: green;
221 | }
222 | ```
223 |
224 | 这样就有一个问题,在实际的项目开发中,假如需要你来写一段公共的 Sass 代码给其他开发者使用,那么如果你的代码中声明了 $main-color 这个变量,那么其他开发者在自己页面也声明了 $main-color 这个变量,并且他是在导入你的这段代码之前声明的,那么他的就会被覆盖掉,这是不行的!
225 |
226 | 所以这里你需要使用 **!default** 标识符,顾名思义,就是默认值,如果这个变量被声明并赋值了,那么就使用声明的值,否则就使用默认值。我们还是用上面的例子来看下:
227 |
228 | ```scss
229 | $main-color: red; // 假如这个是其他开发者自己声明的
230 | $main-color: green!default; // 假如这个是你的代码片段声明的
231 | h1 {
232 | color:$main-color;
233 | }
234 | ```
235 |
236 | 那么在最后编译的时候会使用 red 这个变量值,如果其他开发者没有声明这个变量,就会使用 green 这个变量值,我们来看下编译后的效果:
237 |
238 | ```css
239 | h1 {
240 | color: red;
241 | }
242 | ```
243 |
244 | 上面我们演示了 !default 标识符的作用,这个在你使用 Sass 开发一个独立的模块的时候,或者使用 Sass 开发一个库来供他人使用的时候,!default 标识符石非常有用的!
245 |
246 | ## 5.实战经验
247 |
248 | 上面我们已经讲解了 Sass 变量的语法和使用,那在企业的实际项目中是怎么应用 Sass 变量的呢?这里以一个使用 webpack 搭建的前端项目为例,一般我们都会抽离出 1~n 个文件来专门声明 Sass 变量(抽离出几个文件视项目大小而定),如下图所示:
249 |
250 | 
251 |
252 | 如上图所示,我们一般会在 styles 目录下新建一个 variables.scss 文件来管理声明的全局变量,我们接着来看下在这个文件中是怎么写的:
253 |
254 | 
255 |
256 | 我们可以看到,在这个文件中不但声明了很多变量,还对其做了注释,这样就很易于后期的管理,尤其是在多人开发的大型项目中,对整个项目的样式提取出一些全局变量是很有必要的!
257 |
258 | ## 6.小结
259 |
260 | Sass 变量的使用及语法,主要包括:
261 |
262 | - 变量的声明
263 | - 变量的引用
264 | - 变量的作用域
265 |
266 | 我们还是通过下图来回忆一下本节的内容:
267 |
268 | 
269 |
270 | 在实际的项目中,Sass 变量的使用频率也是非常高的,不亚于 Sass 嵌套,所以一定要好好掌握这一节的内容,变量的应用会让你更加顺手的去管理项目中的样式!
271 |
--------------------------------------------------------------------------------
/docs/front_end/css_advanced/scss/05.md:
--------------------------------------------------------------------------------
1 | # 05 【Sass语法介绍-插值】
2 |
3 | ## 1.前言
4 |
5 | 在很多编程器语言中都有插值这个概念,在 Sass 样式表的任何地方几乎都可以使用插值,你可以将这些包裹在 #{} 中来使用,所以记住在 Sass 中使用插值的方式是 **#{}** ,本节我们一起来看一下插值在 Sass 中的使用场景以及它的语法
6 |
7 | ## 2.什么是插值?
8 |
9 | 插值也就是可以在**特定的区域**插入一段表达式或者插入一个变量,以此来实现内容动态变换的需求。
10 |
11 | > 类似 es6 中的插值表达,插值几乎可以用在任何地方。
12 | >
13 | > Sass的插值写法为:`#{$variable_name}`。
14 |
15 | 应用于以下的一些场景:
16 |
17 | - 在选择器中使用
18 | - 在属性名中使用
19 | - 在属性值中使用
20 | - 在注释中使用
21 |
22 | 这里我们暂且详细讲解这五种使用场景,在 Sass 指令和在 Sass 函数中也是可以使用的,不过我们会在其对应的章节再去做讲解。下面我们先看下这四种使用场景。
23 |
24 | ## 3.在选择器中使用
25 |
26 | 我们一般在写页面的时候会为 DOM 元素定义一些 class 或 id ,当我们为其写样式的时候会用不同的选择器,那么在选择器中我们可以湿用插值来拼接一些类名等等,我们举个例子来看下:
27 |
28 | ```scss
29 | $name: item;
30 | .ul-#{$name} { // 使用插值
31 | width: 200px;
32 | .li-#{$name} { // 使用插值
33 | width: 100%;
34 | }
35 | }
36 | .box-#{$name} { // 使用插值
37 | height:100px;
38 | .#{$name} { // 使用插值
39 | height:100%;
40 | }
41 | }
42 | ```
43 |
44 | 可以看到上面的代码,我制定了一个 DOM 层级结构,这种结构也是很常见的,可能很多子元素的类名我们都带有 item ,那么我们就可以把它提取为一个变量然后通过在选择器中应用插值来拼接,这样就很方便我们维护,我们想改子元素类名的时候就不需要逐一的去更改了。上面这段 Sasd 代码转换为 CSS 如下:
45 |
46 | ```css
47 | .ul-item {
48 | width: 200px;
49 | }
50 | .ul-item .li-item {
51 | width: 100%;
52 | }
53 |
54 | .box-item {
55 | height: 100px;
56 | }
57 | .box-item .item {
58 | height: 100%;
59 | }
60 | ```
61 |
62 | ## 4.在属性名中使用
63 |
64 | 除了在选择器中使用,在 Sass 属性名上也是可以使用插值的,也就是说你在写 CSS 属性名的时候你也是可以使用插值来拼接的,我们举个例子来看下:
65 |
66 | ```scss
67 | $name: color;
68 | $position: top;
69 | body {
70 | background-#{$name}: red;
71 | border-#{$name}: blue;
72 | padding-#{$position}: 5px;
73 | margin-#{$position}: 10px;
74 | #{$position}: 20px;
75 | }
76 | ```
77 |
78 | 可以看到上面的代码中我对 CSS 的属性名使用了插值,可以用这种方式来拼接属性名,不过在实际项目中不是很常用,一般都是在指令里这么运用,就像在前面语法示例中举的例子一样。上面这段代码转换成 CSS 为:
79 |
80 | ```css
81 | body {
82 | background-color: red;
83 | border-color: blue;
84 | padding-top: 5px;
85 | margin-top: 10px;
86 | top: 20px;
87 | }
88 | ```
89 |
90 | ## 5.在属性值中使用
91 |
92 | 在属性值中使用插值应该算是比较常用的,插值使你在属性值中不仅可以插入值,还可以插入表达式来计算。除此之外我们在前面的运算章节中,不知道你是否还记得,我们对两个变量使用 / 标识符的时候,如果你不想对这两个变量进行除法运算而是进行分隔,那么就可以**使用插值避免运算**。
93 |
94 | 可以说插值在属性值中的应用很广泛也很实用,我们来举例看下:
95 |
96 | ```scss
97 | $one: 20px;
98 | $two: 2;
99 | $family: "UaTy";
100 | div {
101 | margin: $one / $two; // 除法运算
102 | margin: #{$one} / #{$two}; // 分隔
103 | font-family: "MyFo #{$family}"; // 带引号的字符串会转换为不带引号
104 | width: calc(100% - $one * 2 *$two); // calc函数中内容会被当作字符串处理
105 | width: calc(100% - #{$one * 2 *$two}); // calc函数中插值的内容会进行运算
106 | }
107 | ```
108 |
109 | 上面的代码中我对每一行都进行了标注,你要仔细看下,在属性值中你可以用这些方式来使用插值,上面的代码将会被转换为如下的 CSS 代码:
110 |
111 | ```css
112 | div {
113 | margin: 10px;
114 | margin: 20px/2;
115 | font-family: "MyFo UaTy";
116 | background-image: url(http://xxx.xxx.xxx/a.jpg);
117 | width: calc(100% - $one * 2 *$two);
118 | width: calc(100% - 80px);
119 | }
120 | ```
121 |
122 | 在属性值中应用插值的场景还蛮多的,你可以这么来使用以提高你的开发效率~
123 |
124 | ## 6.在注释中使用
125 |
126 | 在 Sass 中的注释里也是可以使用插值的,而且如果插值中的内容是一段表达式,将会返回表达式的结果,举个例子来看下:
127 |
128 | ```scss
129 | /* 在注释中使用插值:
130 | * 2 + 2 = #{2 + 2} */
131 | /* #{9 + 8 * 2} */
132 | ```
133 |
134 | 我们可以在注释中可以这么使用插值,具体什么时候需要使用看你的需求,你需要知道插值的这种使用方式,上面的代码将会被转换为如下的 CSS 代码:
135 |
136 | ```css
137 | /* 在注释中使用插值:
138 | * 2 + 2 = 4 */
139 | /* 25 */
140 | ```
141 |
142 | ## 7.实战经验
143 |
144 | 在我的实际项目中,在函数和指令中使用插值比较多,在后面函数和指令的章节你会看到插值的更多运用,这里我列出在属性值以及选择器中的使用。在我项目中专门维护变量的文件中,定义了如下的几个变量:
145 |
146 | ```scss
147 | $primary-dom-name: "box"; // 主要父级元素类名
148 | $primary-child-name: "item"; // 主要子元素类名
149 | $public-top: 10px;
150 | $public-bottom: 10px;
151 | $public-margin: 12px;
152 | $public-padding: 14px;
153 | ```
154 |
155 | 在我项目中的导航样式中我使用了上面的这些变量,代码如下:
156 |
157 | ```scss
158 | .menu-#{$primary-dom-name} {
159 | width: 200px;
160 | height: calc(100% - #{40px - $public-bottom});
161 | background: #cccccc;
162 | overflow-x:hidden;
163 | overflow-y: auto;
164 | padding: $public-padding;
165 | .li-#{$primary-child-name} {
166 | width:100%;
167 | height: 40px;
168 | margin-bottom: $public-margin;
169 | text-align:center;
170 | line-height:40px;
171 | color: blue;
172 | .txt-#{$primary-dom-name} {
173 | border-bottom: 2px solid #999999;
174 | }
175 | &:hover {
176 | background: #999999;
177 | }
178 | }
179 | .logo-#{$primary-dom-name} {
180 | width: 50px;
181 | }
182 | }
183 | ```
184 |
185 | 可以看到,当有一天我们因为业务或者什么其他的需要,我们需要**更换类名或者调整间距**的时候,我们直接更改变量值就 ok 了,这样维护起来方便的多!不过一般在公司的项目中,这种公共的样式代码维护一般是由架构组或者专门的人来维护的,如果你不负责维护这些,你一定不要轻易去改动这些代码!
186 |
187 | ## 8.小结
188 |
189 | 本节内容我们讲解了 Sass 中的插值以及它的使用场景,一般我们会在如下的场景使用:
190 |
191 | - 在函数和指令中使用
192 | - 在选择器中使用
193 | - 在属性名中使用
194 | - 在属性值中使用
195 | - 在注释中使用
196 |
197 | 我们通过下图来更深地回忆下本节插值的使用场景:
198 |
199 | 
200 |
201 | 总体来说插值在 Sass 中用的还是比较多的,使用也比较简单不是那么复杂,后面在函数或指令中、在你项目的 Sass 中看见 **#{}** 要知道这是 Sass 的插值!
--------------------------------------------------------------------------------
/docs/front_end/css_advanced/scss/06.md:
--------------------------------------------------------------------------------
1 | # 06 【Sass语法介绍-函数】
2 |
3 | > 这篇文章只更新了颜色函数,由于Sass使用时间过短,其它函数暂时不太会用
4 |
5 | ## 1.前言
6 |
7 | Sass 中的函数,这在 Sass 中是比较强大的一个功能,同时使用场景和语法也比较多,所以本节内容篇幅较长,但你一定要好好学习, Sass 函数很重要!在 Sass 中函数中几乎可以用到前面你学的所有章节的内容,所以说函数包括万象同时功能也非常强大,本节我们将详细讲解 Sass 中各种函数的功能和用法。
8 |
9 | ## 2.什么是函数?
10 |
11 | 函数是一段可以被另外的程序或代码调用的“子程序”,一个函数由称为函数体的一系列代码语句组成,并且函数也可以接收值,在大多数语言中函数都是这样的,Sass 中的函数也是一样。
12 |
13 | ## 3.Sass 函数简介
14 |
15 | Sass 为我们提供了很多内置模块,其中就包含了很多函数(包括一些指令),我们可以通过 @use 去加载它们,然后我们就可以调用了,当然还有一些函数可以直接在 CSS 语句中调用,在 Sass 中常用的函数有:
16 |
17 | - 字符串函数
18 | - 数字函数
19 | - 列表函数
20 | - Introspection函数
21 | - 条件函数
22 | - Map 函数
23 | - 颜色函数
24 |
25 | 上面这些函数为我们提供了强大而丰富的功能来更高效地编写样式,下面我们来详细讲解 Sass 函数。
26 |
27 | ## 4.颜色函数
28 |
29 | Sass 中提供了非常非常多的颜色函数用来处理颜色值,它们很多需要你具有专业的调色及配色知识才能发挥出作用,所以本节我们不讲的那么复杂,本节内容中我们只讲几种常见的、比较简单的颜色函数,其他特别复杂的用于调色的函数在以后你可以再慢慢研究。
30 |
31 | ### 4.1 用于获取通道色值的函数
32 |
33 | Sass 提供了可以获取一个色值中红色通道、绿色通道和蓝色通道色值的函数,它们分别是 red($color) 、green($color) 和 blue($color)。你可能还不太了解这三种通道是什么,不要紧,只要知道这三种函数和它的使用就可以。我们举例看下:
34 |
35 | ```scss
36 | blue(#BA55D3) //=> 211
37 | red(#BA55D3) //=> 186
38 | green(#BA55D3) //=> 85
39 | ```
40 |
41 | ### 4.2 saturate($color, $amount)
42 |
43 | saturate($color, $amount) 函数用于调整 $color 的饱和度,第 1 个参数 $color 是一个颜色值,第 2 个参数是 0% ~ 100% 之间的百分数,其返回值也是一个颜色值。
44 |
45 | ```scss
46 | saturate(#BA55D3, 20%) //=> #c740e8
47 | ```
48 |
49 | ### 4.3 scale-color(…)
50 |
51 | 这是一个非常强大的颜色函数,它**接收很多个参数**,可以**调整一个色值的很多属性**,包括这个颜色的红、绿、蓝通道,以及亮度等等,我们只能举例来直观的看下:
52 |
53 | ```scss
54 | scale-color(#BA55D3, $red: 15%) //=> #c455d3 调整红色通道
55 | scale-color(#BA55D3, $blue: 15%) //=> #ba55da 调整蓝色通道
56 | scale-color(#BA55D3, $lightness: -10%, $saturation: 10%) //=> #b338d2 调整亮度和饱和度
57 | scale-color(#BA55D3, $alpha: -30%) //=> rgba(186, 85, 211, 0.7) 调整不透明度
58 | ```
59 |
60 | 通过上面的例子可以看到颜色函数提供了非常强大的用于调色的函数,驾驭它的前提是你要有非常丰富的调色知识以及一定的美术基础。在实际的项目中我们非常少的用到颜色函数,因为一般都是由公司的 UI 设计师来进行调色,所以作为入门教程,你只需要了解 Sass 中的颜色函数就好。
61 |
62 | ## 5. 小结
63 |
64 | 本节内容我们讲了 Sass 提供的各种各样的函数,基本覆盖到了比较常用的、常见的函数,它们分别是:
65 |
66 | - 字符串函数
67 | - 数字函数
68 | - 列表函数
69 | - Introspection函数
70 | - 条件函数
71 | - Map 函数
72 | - 颜色函数
--------------------------------------------------------------------------------
/docs/front_end/css_advanced/scss/09.md:
--------------------------------------------------------------------------------
1 | # 09 【Sass语法介绍-函数指令】
2 |
3 | ## 1.前言
4 |
5 | 在之前的章节我们学习过 Sass 提供的各种各样的函数,那么如果我们需要自定定义函数来使用就需要用到**函数指令 @function**了。本节内容我们来学习 Sass 函数指令的语法和使用,在 Sass 中自定义函数是必须要掌握的!
6 |
7 | ## 2.什么是 Sass 函数指令
8 |
9 | 函数指令也叫自定义函数让你可以容易的处理各种逻辑和定义复杂的操作,而且你可以在任何需要的地方复用函数,这使得我们可以抽离出来一些常见的公式或者逻辑,我们先来看下它长什么样,代码如下:
10 |
11 | ```scss
12 | // 定义函数
13 | @function a() {
14 | @return "a"
15 | }
16 | // 使用函数
17 | .p {
18 | font: a();
19 | }
20 | ```
21 |
22 | 回忆一下,上面的代码在之前的章节中也出现过,这就是函数指令,定义好一个函数后我们就可以使用了,下面我们开始详细讲解函数指令。
23 |
24 | 函数指令是**通过 @function 来定义**,它的写法是 @function name(arguments…){},@function 后面跟函数名,然后是一个 () ,() 里面是这个函数接收的参数,可以接收也可以不接收,最后是 {} 中放的是你的逻辑代码。函数名**将连字符和下划线视为相同**,也就是说 a_b 和 a-b 是同一个函数。我们举例看下:
25 |
26 | ```scss
27 | @function fun-name() {
28 | // 在这里编写逻辑代码
29 | }
30 | ```
31 |
32 | ## 3.函数的参数
33 |
34 | 函数指令的参数和之前我们讲的混合指令的参数很像,函数如果接收参数那么使用的时候就**必须传入这些参数**,但是你**可以定义默认值使参数成为可选的**,我们举例来看下:
35 |
36 | ```scss
37 | // 有默认值的参数
38 | @function a($arg: 1) {
39 | @return $arg;
40 | }
41 | // 无默认值的参数
42 | @function b($arg) {
43 | @return $arg;
44 | }
45 | .p {
46 | font: a();
47 | font: b(4);
48 | }
49 | ```
50 |
51 | 上面的代码转换为 CSS 如下:
52 |
53 | ```css
54 | .p {
55 | font: 1;
56 | font: 4;
57 | }
58 | ```
59 |
60 | 要注意的是,为参数设置的默认值,也可以引用前面的参数或者是任何表达式。
61 |
62 | ## 4.接收任意数量的参数
63 |
64 | 和前面章节讲的 @mixin 类似,函数指令也**可以接收任意数量的参数**,同样是将最后一个参数以 … 结尾,我们来举例看下:
65 |
66 | ```scss
67 | @function fonts($familys...) {
68 | @return $familys;
69 | }
70 | .p {
71 | font: fonts("one", "two", "three")
72 | }
73 | ```
74 |
75 | 上面这段代码转换为 CSS 如下:
76 |
77 | ```css
78 | .p {
79 | font: "one", "two", "three";
80 | }
81 | ```
82 |
83 | 同样的函数的参数也可以接收任意的参数列表,就像之前在混合指令章节讲的一样,可以用过 meta.keywords() 来获取和使用这些参数,不过这个我们一般不是很常用。
84 |
85 | ## 5.@return
86 |
87 | 在前面的代码中,可以看到很多次我们在函数指令中使用了 @return。@return 指令表示作为函数调用结果的值,说的简单点就是这个函数的返回值,这和在 javascript 的函数中使用 return 很类似。
88 |
89 | 在 Sass 中 **@return 指令只能在 @function** 中使用,并且**每个 @function 都必须以 @return 结尾!** 在 @function 的逻辑代码中,如遇到 @return 会立即结束函数并返回其结果,这在一些 @if 判断的情况下很有用。我们举例看下:
90 |
91 | ```scss
92 | @function a($str: "a") {
93 | @if $str == "a" {
94 | @return 10px;
95 | } @else if $str == "b" {
96 | @return 20px;
97 | } @else if $str == "c" {
98 | @return 30px;
99 | } @else {
100 | @return 40px;
101 | }
102 | }
103 |
104 | p {
105 | padding: a();
106 | width: a("f");
107 | height: a("c");
108 | margin: a("b");
109 | }
110 | ```
111 |
112 | 从上面的代码中我们可以可看到,在函数 a 中,我们根据不同的参数返回不同的结果,然后在 p 的样式中通过传入不同的参数来获取不同的结果。上面这段代码会转换为如下的 CSS 代码:
113 |
114 | ```css
115 | p {
116 | padding: 10px;
117 | width: 40px;
118 | height: 30px;
119 | margin: 20px;
120 | }
121 | ```
122 |
123 | ## 6.实战经验
124 |
125 | 在实际的项目中使用函数指令是必不可少的,我们会定义很多函数来帮助我们解决逻辑问题,一般我们会独立抽出来一个 function.scss 文件来管理整个项目中的函数指令,一般这些函数都是根据你的项目特性以及样式需要封装出来的。
126 |
127 | 由于函数一般是和你的业务强相关的,一般就是为自己的项目定义一些工具和方法,这里我就不贴出代码示例了。在实际的应用中,这个函数指令就是需要你“随机应变”,按需封装和使用!
128 |
129 | ## 7.小结
130 |
131 | 本节内容我们讲了 Sass 函数指令 @function ,还有函数指令的用法和参数。我们可以使用函数来编写各种各样我们自己的函数。函数指令和前面的混合指令很类似,我们通过下图来回一下函数指令的用法:
132 |
133 | 
134 |
135 | 除此之外 Sass 提供了大量的内置函数,这些我们在前面的章节 Sass 函数中都做了讲解,你可以借用这些函数再配合你自己定义的函数指令,来实现各种复杂的逻辑和强大的效果。
--------------------------------------------------------------------------------
/docs/front_end/css_advanced/scss/10.md:
--------------------------------------------------------------------------------
1 | # 10 【Sass语法介绍-继承】
2 |
3 | ## 1.前言
4 |
5 | 在我们编写样式的时候,很多情况下我们几个不同的类会有相同的样式代码,同时这几个类又有其自己的样式代码,这使我们就可以通过 Sass 提供的**继承** @extend 来实现。本节内容我们将讲解 Sass 继承的语法以及继承的多重延伸等等,在 Sass 中继承也是非常好用的功能之一,所以你要重点熟悉 @extend 的用法,下面我们一起来学习它。
6 |
7 | ## 2.什么是 Sass 继承
8 |
9 | 继承,我们也叫做代码重用,在 Sass 中支持对样式进行继承。
10 |
11 | 首先我们看一段代码,看看在 Sass 中的继承是长什么样子的:
12 |
13 | ```scss
14 | .a {
15 | width: 10px;
16 | }
17 |
18 | .b {
19 | @extend .a;
20 | height: 10px;
21 | color: red;
22 | }
23 | ```
24 |
25 | 从上面的代码中可以看见,我在 .b 的样式中使用 @extend 继承了 .a 的样式,那么这段代码转换为 CSS 如下:
26 |
27 | ```css
28 | .a, .b {
29 | width: 10px;
30 | }
31 |
32 | .b {
33 | height: 10px;
34 | color: red;
35 | }
36 | ```
37 |
38 | 上面的代码中我们看到了 Sass 中继承的样子,它的写法是 @extend selector 也就是**在 @extend 后面跟一个选择器**,表示**继承这个选择器的样式**,下面我们详细讲解下它的语法。
39 |
40 | @extend 会包含包含扩展的样式规则,同时在 Sass 中它会**确保复杂的选择器是交错的**,这样无论你的 DOM 元素是如何嵌套的它都能保证正常工作。它还可以**根据实际情况将选择器组合在一起**,可以**更智能的处理选择器以及包含伪类的选择器**。我们举个稍复杂点的例子来看下:
41 |
42 | ```scss
43 | .a {
44 | width: 100px;
45 | height: 200px;
46 | background-color: orange;
47 | &:hover {
48 | background-color: green;
49 | }
50 | .link {
51 | width: 50%;
52 | height: 50%;
53 | color: red;
54 | &:active {
55 | color: blue;
56 | }
57 | i {
58 | font-size: 18px;
59 | font-weight: 600;
60 | }
61 | }
62 | }
63 |
64 | .b {
65 | @extend .a;
66 | width: 400px;
67 | height: 200px;
68 | }
69 | ```
70 |
71 | 我们仔细解读上面的代码,我为 .a 写了一大堆的样式,包括它的子元素以及它的伪类;而 .b 下面有同样的子元素,同样的伪类别,只是宽高不同,那么我直接在 .b 中继承 .a 的样式,它会转换为什么样子的代码呢?它转换为 CSS 的代码如下:
72 |
73 | ```css
74 | .a, .b {
75 | width: 100px;
76 | height: 200px;
77 | background-color: orange;
78 | }
79 | .a:hover, .b:hover {
80 | background-color: green;
81 | }
82 | .a .link, .b .link {
83 | width: 50%;
84 | height: 50%;
85 | color: red;
86 | }
87 | .a .link:active, .b .link:active {
88 | color: blue;
89 | }
90 | .a .link i, .b .link i {
91 | font-size: 18px;
92 | font-weight: 600;
93 | }
94 |
95 | .b {
96 | width: 400px;
97 | height: 200px;
98 | }
99 | ```
100 |
101 | 从上面转换成 CSS 的代码我们可以看出,引用相同样式的部分都以逗号做了分隔,在 CSS 中使用逗号的含义你应该很了解,继承 @extend 就可以为你自动创建这些组合,提取相同的样式,所以如果有选择器使用了相同的样式,请使用继承的方式来实现!
102 |
103 | ## 3.占位符选择器
104 |
105 | 在 Sass 中有一种特殊的选择器叫占位符选择器,它的写法像我们写的 id 或 class 选择器一样,只不过**占位符选择器是以 % 开头的**。在 Sass 中你单独使用这种选择器是不会转换为 CSS 的,只能是**通过 @extend 来使用**。
106 |
107 | 比如说有时候你想编写一个可扩展的样式,然后在各处继承它,你就可以使用占位符选择器,我们结合实际的例子来看下:
108 |
109 | ```scss
110 | %placeholder {
111 | box-sizing: border-box;
112 | border-top: 1px #666666 solid;
113 | width: 100%;
114 |
115 | &:hover { border: 2px #999999 solid; }
116 | &:active {color: blue;}
117 | }
118 |
119 | .buttons {
120 | @extend %placeholder;
121 | color: #4285f4;
122 | }
123 | .btn {
124 | @extend %placeholder;
125 | }
126 | ```
127 |
128 | 从上面的代码中看到,我通过占位符选择器 %placeholder 定义了一堆样式,然后在其他的样式表中继承它,这个告诉你一个简单的理解方式,占位符选择器你就理解为一个虚拟的选择器,这个名是不会编译到 CSS 中的,最终编译出的选择器名是根据你使用继承的选择器名来定的。上面这段代码会转化为如下的 CSS 代码:
129 |
130 | ```css
131 | .btn, .buttons {
132 | box-sizing: border-box;
133 | border-top: 1px #666666 solid;
134 | width: 100%;
135 | }
136 | .btn:hover, .buttons:hover {
137 | border: 2px solid;
138 | }
139 | .btn:active, .buttons:active {
140 | color: blue;
141 | }
142 |
143 | .buttons {
144 | color: #4285f4;
145 | }
146 | ```
147 |
148 | 从上面的代码中可以看到,编译成 CSS 后 %placeholder 这个选择器不见了,但它的样式被继承了,这就是**占位符选择器结合继承 @extend 的用法**。
149 |
150 | ## 4.在 @media 中使用 @extend
151 |
152 | 如果你需要在 @media 中使用继承,一定要注意使用方式!如果你**在外部定义样式**,然后**在 @media 内部继承外部的样式**,Sass 是**会报错**的。我们首先举个**错误的例子**看下:
153 |
154 | ```scss
155 | .error {
156 | border: 1px red solid;
157 | background-color: red;
158 | }
159 |
160 | @media screen and (max-width: 600px) {
161 | .btn-error {
162 | @extend .error;
163 | }
164 | }
165 | ```
166 |
167 | 如上面的代码所示,这样的写法在 Sass 中是会报错的,也不会编译成功。 Sass 规定继承只能在给定的媒体上下文中使用,所以**正确的写法**如下:
168 |
169 | ```scss
170 | @media screen and (max-width: 600px) {
171 | .error {
172 | border: 1px red solid;
173 | background-color: red;
174 | }
175 | .btn-error {
176 | @extend .error;
177 | }
178 | }
179 | ```
180 |
181 | 上面这个正确的写法将会被编译为如下的 CSS 代码:
182 |
183 | ```css
184 | @media screen and (max-width: 600px) {
185 | .error, .btn-error {
186 | border: 1px red solid;
187 | background-color: red;
188 | }
189 | }
190 | ```
191 |
192 | > 在 @media 中使用继承,一定要注意写法!
193 |
194 | ## 5.实战经验
195 |
196 | 在实际的项目中,继承是非常好用的一个功能,不过这个就需要你自己根据需求来判断是否使用,因地制宜,而且尽量把公共的样式提取到一个单独的文件来维护。
197 |
198 | 还有一个需要注意的是除了继承 @mixin 也是可以封装和复用样式的,那么什么时候使用 @mixin 什么时候使用 @extend 呢?假如你需要使用参数来配置样式的时候,也就是**需要传参数**的时候毫无疑问**使用 @mixin** 。但如果你只是需要复用一部分样式那么还是使用继承会更方便些。
199 |
200 | ## 6.小结
201 |
202 | 
203 |
204 | 本节内容我们讲解了 Sass 中的继承 @extend 。我们可以使用继承很方便的**复用样式代码**,同时我们也可以使用**占位选择器**配合 @extend 来扩展和复用样式代码,还有一定要**注意在 @media 中使用继承的方式**。记住 Sass 中的 @extend ,它可以让你的样式代码写起来更高效!
--------------------------------------------------------------------------------
/docs/front_end/css_advanced/scss/11.md:
--------------------------------------------------------------------------------
1 | # 11【Sass语法介绍-导入】
2 |
3 | ## 1.前言
4 |
5 | 在 CSS 中我们可以通过 @import 来导入一个样式文件,Sass 扩展了 CSS 的 @import 规则,使得可以导入 CSS 后缀的样式文件和 Scss 后缀的样式文件,并且提供了对 mixin 、函数和变量的访问。
6 |
7 | 与 CSS 的 @import 不同的是, CSS 使用 @import 导入文件是在页面渲染的时候发起多个 http 请求来获取文件内容,而 Sass 的导入 @import 是在编译时获取文件内容导入的。
8 |
9 | ## 2.语法详情
10 |
11 | Sass 的导入和 CSS 中的导入语法类似,只不过在 Sass 中**可以导入用逗号分隔的多个文件**, 我们举个例子看下:
12 |
13 | ```scss
14 | @import 'a.scss', 'b.scss';
15 | ```
16 |
17 | 上面的代码意思是导入 a.scss 和 b.scss 文件,那么导入后 a 和 b 中的任何mixin 、函数和变量都是可以使用的。
18 |
19 | 我们知道在 CSS 中也有 @import 语句,在以下几种情况 Sass 会认为 @import 是 CSS 语句:
20 |
21 | - 使用 url()
22 | - 文件的扩展名是 .css
23 | - @import 包含 media queries
24 | - 文件名以 http:// 开头
25 |
26 | 在使用的时候要注意上面的几种情况,如果导入的扩展名是 .scss 或 .sass 那么肯定用的是 Sass 提供的 @import 。如果**导入文件没有指定文件扩展名,那么 Sass 会尝试寻找文件名相同的扩展名为 .sass 或 .scss 的文件**。
27 |
28 | ## 3.加载路径
29 |
30 | Sass 允许我们自行提供文件的加载路径,在我们导入文件的时候,Sass 总是会相对于当前文件进行解析,如果没有加载到则会使用**加载路径**。假如我们将加载路径设置为 node_modules/public/sass ,那么我们使用如下的导入方式:
31 |
32 | ```scss
33 | @import 'a';
34 | ```
35 |
36 | 假如当前目录下没有 a.scss 文件,那么 Sass 就会去加载 node_modules/public/sass/a.scss ,这就是使用了加载路径,不过这种方式我们在项目中**极少应用**,你只需要了解即可。
37 |
38 | ## 4.部分导入
39 |
40 | 什么是部分导入呢? 我的理解是**局部的使用导入**,也就是说可以**仅导入 Sass 或 Scss 文件,而不将它们编译为 CSS,** 那么应该怎么做呢?假如我要导入一个 my.scss 文件,我不希望将它编译为 CSS ,那么需要**使用下划线开头的文件名**,也就是说需要改名为 _my.scss ,然后使用如下导入代码:
41 |
42 | ```scss
43 | @import 'my';
44 | ```
45 |
46 | 上面的代码导入的就是 _my.scss 文件,并且不会将它编译为 CSS 。另外需要注意的是:**不可以同时存在带有下划线和不带下划线的同名文件!**
47 |
48 | ## 5.索引文件
49 |
50 | 在 Sass 中什么是索引文件呢?_index.scss 文件,那它有什么用呢?假如我有一个 my 目录,这个目录下有两个文件,一个是 a.scss 一个是 _index.scss ,那么我使用如下文件导入代码:
51 |
52 | ```scss
53 | @import 'my';
54 | ```
55 |
56 | 那么上面的代码导入的就是 _index.scss 文件,也就是说 _index.scss 是这个目录下的**默认文件**,这就想你在写 vue 或者 html 中目录下的 index 文件类似。
57 |
58 | ## 6.使用 @use 替代 @import
59 |
60 | Sass 官方团队不鼓励使用 @import 导入,并且在未来几年将逐步淘汰它,并最终将 @import 从 Sass 中完全删除。所以使用 @use 是官方团队更推荐的方式,下面我们开始讲解使用 @use 导入。
61 |
62 | @use 与 @import 的语法基本相同,我们先看一个简单的使用 @use 导入的例子:
63 |
64 | ```scss
65 | @use 'my/a.scss';
66 | @use 'my/b';
67 | ```
68 |
69 | 从上面的代码中可以看到其使用方式与 @import 是相同的,那么为什么还要替换掉 @import 呢? 主要是以下几个原因你需要了解下:
70 |
71 | - @import 会使得所有变量、mixin 和函数都可以全局访问,这使开发者很难去维护这些定义的东西。
72 | - 因为所有的都是全局的,那么 Sass 必须为所有的成员添加前缀,以避免命名冲突。
73 | - @extend 也是全局的,这样将很难预测哪些样式将被扩展。
74 | - 每次使用 @import 时,每个样式表都会被执行,这会增加编译时间
75 | - 无法定义下游样式表无法访问的私有成员。
76 |
77 | 基于上述的这些原因,Sass 官方团队将会逐渐淘汰 @import,可以使用 @use 替代,语法是相同的,所以我们在 **v4.x.x 及以上的版本**中尽量使用 @use 来导入。
78 |
79 | ## 7.实战经验
80 |
81 | 其实在实际的项目中我们一般就是用 @import 来简单的导入文件,更多的时候是用它来方便整个项目中的 Sass 样式管理,如下图所示:
82 |
83 | 
84 |
85 | 图中所演示的是我的项目中的一个使用方式。每个项目的样式管理方式都不同,你的公司中的项目中肯定也会使用 @import 或 @use 来管理样式文件,不过目前应该是使用 @import 的居多,这个功能其实很简单也没有太多的说法,在你的项目中需要你灵活的使用它,当然,慢慢的使用 @use 去替换掉它也是非常重要的!
86 |
87 | ## 8.小结
88 |
89 | 
90 |
91 | 本节内容我们讲解了 Sass 中的导入 @import,这在 CSS 中也是有这个功能的,这个功能我们可以理解就是导入文件中的内容的,一般在项目中我们也是用它来操作文件而已。
92 |
93 | 还有需要注意的是,Sass 官方推荐使用 @use 来替代 @import 使用,所以我们在导入的时候尽量使用 @use,如果你的项目中已经大量的使用了 @import (这是目前很常见的现状),可以找个时机替换掉,不过一定要确保 Sass 的**版本是 v4.x.x 及以上!**
--------------------------------------------------------------------------------
/docs/front_end/css_advanced/tailwind/01.md:
--------------------------------------------------------------------------------
1 | # 01 【Tailwind CSS 安装使用】
2 |
3 | > **简介:**Tailwind CSS 是一个功能类优先的 CSS 框架,它集成了诸如 flex, pt-4, text-center 和 rotate-90 这样的的类,它们能直接在脚本标记语言中组合起来,构建出任何设计。
4 |
5 | ## 1.使用 CDN 快速体验 Tailwind CSS
6 |
7 | > 使用 Play CDN 直接在浏览器中试用 Tailwind,无需任何构建步骤。Play CDN 仅用于开发目的,不是生产的最佳选择。
8 |
9 | 将 Play CDN 脚本标记添加到 HTML 文件的 ,然后开始使用 Tailwind 的实用工具类来设置内容的样式。``
10 |
11 | ```html
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
1
22 |
2
23 |
3
24 |
25 |
26 |
27 | ```
28 |
29 | ## 2.使用 npm 安装 Tailwind CSS
30 |
31 | **第一步:安装 Tailwind CSS**
32 |
33 | 安装 `Tailwind CSS` 并创建 `tailwind.config.js` 配置文件
34 |
35 | ```shell
36 | mkdir demo
37 | cd demo
38 |
39 | # 安装 tailwindcss
40 | npm install -D tailwindcss
41 | # 初始化会生成 tailwind.config.js 配置文件
42 | npx tailwindcss init
43 | ```
44 |
45 | > 1)npm install -D tailwindcss 会生成文件及目录
46 | >
47 | > node_modules package-lock.json package.json
48 | >
49 | >
50 | >
51 | > 2)npx tailwindcss init 生成如下配置文件
52 | >
53 | > tailwind.config.js
54 |
55 | **第二步:编辑 tailwind.config.js 配置文件**
56 |
57 | 添加文件到配置文件中
58 |
59 | ```js
60 | module.exports = {
61 | content: ["./src/**/*.{html,js}"],
62 | theme: {
63 | extend: {},
64 | },
65 | plugins: [],
66 | }
67 | ```
68 |
69 | **第三步:添加 Tailwind 样式指令到 CSS文件中**
70 |
71 | ```
72 | @tailwind base;
73 | @tailwind components;
74 | @tailwind utilities;
75 | ```
76 |
77 | > 有警告的在vscode中安装`PostCSS Language Support`插件
78 |
79 | **第四步:使用 Tailwind Cli 构建 CSS样式**
80 |
81 | ```shell
82 | npx tailwindcss -i ./src/style.css -o ./dist/mystyle.css --watch
83 | ```
84 |
85 | 该命令会将 `src/style.css` 中 `Tailwind CSS` 编译到 `demo/dist/mystyle.css` 文件中,`mystyle.css` 就是编译后样式,项目中引入的就是它。
86 |
87 | 现在打开 `package.json` 文件,添加以下运行脚本:
88 |
89 | ```json
90 | "scripts": {
91 | "build": "tailwindcss -i ./src/style.css -o ./dist/output.css --watch"
92 | }
93 | ```
94 |
95 | 这时候只要运行`npm run build`就可以自动监听你的页面改动并且实时编译了。
96 |
97 | **第五步:小试牛刀**
98 |
99 | 经过上面 4 个小步骤,`Tailwind CSS` 就已经安装好,下面就来瞅瞅。
100 |
101 | ```html
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 | Hello world!
112 |
113 |
114 |
115 | ```
116 |
117 | > ### 自动刷新HTML文件
118 | >
119 | > 这是个题外话,不属于Tailwind CSS的范畴,如果你在写静态页面的时候,需要每次修改html页面,浏览器就自动刷新这个页面,那么只需要在vscode内搜索`Live Preview`并且安装,之后在你需要预览的页面,右键,选择`Live Preview:Show Preview`即可。
--------------------------------------------------------------------------------
/docs/front_end/css_advanced/tailwind/02.md:
--------------------------------------------------------------------------------
1 | # 02 【TailWind CSS 初体验】
2 |
3 | 经过上一篇 `Tailwind CSS` 的学习,现在已经安装好了,万事俱备,只欠东风。这篇文章不往后学习,先来找找**成就感!**,体验一把 `Tailwind CSS` 的案例。
4 |
5 | ```html
6 |
7 |
8 |
9 |
10 |
11 |
12 | Document
13 |
14 |
15 |
16 |
17 |
20 |
21 | Hello TailWind CSS
22 |
23 |
31 |
32 |
35 |
36 |
37 |
38 | ```
39 |
40 | 
41 |
42 | ```html
43 |
44 |
45 |
46 |
47 |
48 |
49 | Document
50 |
51 |
52 |
53 | TailWind CSS
54 |
57 |
hello tailwind css
58 |
59 |
60 |
61 |
Laravel
62 |
Tailwind CSS
63 |
Livewire
64 |
65 |
66 |
67 | ```
68 |
69 | 
70 |
71 |
--------------------------------------------------------------------------------
/docs/front_end/front_end_base/html_css/05.md:
--------------------------------------------------------------------------------
1 | # 05 【CSS引入方式 CSS的元素显示模式】
2 |
3 | ## 1.CSS的引入方式
4 |
5 | ### 1.1 CSS的三种引入方式
6 |
7 | 按照 CSS 样式书写的位置(或者引入的方式),CSS 样式表可以分为三大类:
8 |
9 | - 行内样式表(行内式)
10 | - 内部样式表(嵌入式)
11 | - 外部样式表(外链式)
12 |
13 | ### 1.2 行内样式表
14 |
15 | 行内样式表(内联样式表)是在元素标签内部的 style 属性中设定 CSS 样式,适合于修改简单样式。
16 |
17 | ```html
18 |
19 | 青春不常在,抓紧谈恋爱
20 |
21 | ```
22 |
23 | - `style` 其实就是标签的属性
24 | - 在双引号中间,写法要符合 CSS 规范
25 | - 可以控制当前的标签设置样式
26 | - 由于书写繁琐,并且没有体现出结构与样式相分离的思想,所以不推荐大量使用,只有对当前元素添加简单样式的时候,可以考虑使用
27 | - 使用行内样式表设定 CSS,通常也被称为 `行内式引入`
28 |
29 | > 问题:使用内联样式,样式只能对一个标签生效。如果希望影响到多个元素,必须在每一个元素中都复制一遍;并且当样式发生变化时,我们必须要一个一个的修改,非常的不方便。(注意:开发时绝对不要使用内联样式)
30 |
31 | ### 1.3 内部样式表
32 |
33 | 将样式编写到`head`中的`style`标签里然后通过css的选择器来选中元素并为其设置各种样式可以同时为多个标签设置样式,并且修改时只需要修改一处即可。内部样式表更加方便对样式进行复用
34 |
35 | ```html
36 |
42 | ```
43 |
44 | - `
23 |
24 |
25 | 0
26 |
46 | ```
47 |
48 | **节流小案例-页面打开,可以记录上一次的视频播放位置**
49 |
50 | ```html
51 |
67 | ```
68 |
69 | ## 2.防抖(debounce)
70 |
71 | **所谓防抖,就是指触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了事件,则会重新计算函数执行时间**
72 |
73 | ```tex
74 | 开发使用场景- 搜索框防抖
75 | 假设输入就可以发送请求,但是不能每次输入都去发送请求,输入比较快发送请求会比较多
76 | 我们设定一个时间,假如300ms, 当输入第一个字符时候,300ms后发送请求,但是在200ms的时候又输入了一个字符,则需要再等300ms 后发送请求
77 | ```
78 |
79 | ```html
80 |
90 |
91 |
92 | 0
93 |
110 | ```
111 |
112 | ```tex
113 | 节流和防抖的使用场景是?
114 | 节流: 鼠标移动,页面尺寸发生变化,滚动条滚动等开销比较大的情况下
115 | 防抖: 搜索框输入,设定每次输入完毕n秒后发送请求,如果期间还有输入,则从新计算时间
116 | ```
117 |
--------------------------------------------------------------------------------
/docs/front_end/front_end_framework/react/08.md:
--------------------------------------------------------------------------------
1 | # 08 【状态提升】
2 |
3 | ## 1.介绍
4 |
5 | 所谓 **状态提升** 就是将各个子组件的 公共state 提升到它们的父组件进行统一存储、处理(这就是所谓的”单一数据源“),负责`setState`的函数传到下边的子级组件,然后再将父组件处理后的数据或函数props到各子组件中。
6 |
7 | 那么如果子组件 要 修改父组件的state该怎么办呢?我们的做法就是 将父组件中负责setState的函数,以props的形式传给子组件,然后子组件在需要改变state时调用即可。
8 |
9 | **实现方式**
10 |
11 | 实现方式是 利用最近的共同的父级组件中,用props的方式传过去到两个子组件,props中传的是一个setState的方法,通过子组件触发props传过去的方法,进而调用父级组件的setState的方法,改变了父级组件的state,调用父级组件的render方法,进而同时改变了两个子级组件的render。
12 |
13 | 这是 两个有关连的同级组件的传值,因为react的单项数据流,所以不在两个组件中进行传值,而是提升到 最近的共同的父级组件中,改变父级的state,进而影响了两个子级组件的render。
14 |
15 | > 官网介绍
16 | >
17 | > 通常,多个组件需要反映相同的变化数据,这时我们建议将共享状态提升到最近的共同父组件中去。
18 |
19 | ## 2.案例
20 |
21 | 先写一个温度输入组件:
22 |
23 | ```js
24 | class TemperatureInput extends React.Component {
25 | state = {
26 | temperature: ''
27 | };
28 | handleChange = (e) => {
29 | this.setState({
30 | temperature : e.target.value
31 | })
32 | };
33 | render() {
34 | return (
35 |