jsbay Knowledge Base
website·Indexed 30 days ago
https://jsbay.github.io/vuepress/A personal technical knowledge base featuring guides and notes on Vue 2, including dynamic components, router lazy loading, and provide/inject. It also covers web development topics like CSS BEM, axios interceptors, webpack configuration, and oAuth 2.0, as well as system administration for Linux, Windows, and Mac, Docker usage for Oracle servers, and Git workflow constraints.
What's inside jsbay Knowledge Base
- Vue is defined as a progressive framework for building user interfaces, meaning it is designed to be adopted incrementally from the bottom up. Unlike monolithic frameworks, Vue's core library focuses exclusively on the view layer, making it easy to integrate with third-party libraries or existing projects. In a progressive design, the architecture is layered; each layer is optional, allowing developers to flexibly swap specific layers with alternative solutions or architectural patterns.
Implement CDN for external dependencies in Vue 2
To reduce bundle size and server bandwidth, you can exclude large, stable libraries (like Vue, Vuex, or Element-UI) from the Webpack bundle using
externalsand inject them via CDN links in the HTML template.- Define the external mapping in
vue.config.jsusingexternals. - Pass the CDN URLs to the HTML plugin via
chainWebpack. - Update
public/index.htmlto iterate over the CDN arrays and inject the<link>and<script>tags.
// vue.config.js const cdn = { css: [ "https://unpkg.com/element-ui/lib/theme-chalk/index.css", ], js: [ "https://unpkg.com/vue/2.5.22/vue.min.js", "https://unpkg.com/element-ui/lib/index.js", "https://unpkg.com/vuex/3.1.0/vuex.min.js", ], }; module.exports = { externals: { vue: "Vue", "element-ui": "ELEMENT", vuex: "Vuex", }, chainWebpack: (config) => { config.plugin("html").tap((args) => { args[0].cdn = cdn; return args; }); }, };<!-- /public/index.html --> <head> <% if (process.env.NODE_ENV === 'production') { %> <!-- Inject CSS from CDN --> <% for(var css of htmlWebpackPlugin.options.cdn.css) { %> <link rel="stylesheet" href="<%=css%>" /> <% } %> <!-- Inject JS from CDN --> <% for(var js of htmlWebpackPlugin.options.cdn.js) { %> <script src="<%=js%>"></script> <% } %> <% } %> </head>- Define the external mapping in
Set up a Mock server for Vue.js using Mockjs
To implement a mock server that supports both frontend interception and a backend dev-server proxy with hot-reloading, create a
mockdirectory with the following structure:mock/index.js: Main entry point for mock definitions and frontend XHR interception.mock/mock-server.js: Express middleware for the dev server that handles requests and supports hot-reloading viachokidar.mock/utils.js: Utility functions for parsing URL parameters.mock/modules/*.js: Individual mock data modules (e.g.,sys.js) defining endpoints, HTTP methods, and response logic.
package.json mock |---modules |---sys.js |---mock-server.js |---index.js |---utils.jsCache dynamic components using keep-alive
Wrap the<component>element in a<keep-alive>tag to preserve the state of components when they are switched out. This prevents the component from being destroyed and re-created, improving performance and maintaining user input or scroll positions.<keep-alive> <component :is="currentTabComponent"></component> </keep-alive>Implement cross-component communication using provide and inject in Vue 2
Theprovideandinjectoptions allow an ancestor component to inject a dependency into all its descendants, regardless of the component hierarchy depth. This acts as a wide-scope alternative to props, enabling one-way data flow from an ancestor to any child, grandchild, or deeper descendant component.// Ancestor component providing data export default { name: "father", provide: { test: "wawawa", age: "20", }, data() {}, }; // Descendant component (child, grandchild, etc.) injecting data export default { name: 'children', // Inject the keys provided by the ancestor inject: ['test', 'age'], created() { console.log(this.test); // "wawawa" console.log(this.age); // "20" }, }Install dependencies for Mock server
The mock server implementation requiresmockjsfor data generation andchalkfor formatted console logging. If using the server-side mock,chokidar(for file watching) andbody-parser(for request parsing) are also needed.{ "devDependencies": { "chalk": "2.4.2", "mockjs": "1.0.1-beta3" } }Register Nginx as a Windows system service using WinSW
To run Nginx as a background service on Windows, use WinSW (Windows Service Wrapper). This allows Nginx to start automatically on boot and be managed via the Windows Services manager (
services.msc).Steps:
- Download Nginx from the official site and extract it to a directory (e.g.,
Directory A). - Download the WinSW binary from the Jenkins repository.
- Rename the WinSW executable (e.g.,
winsw-xxx-bin.exe) tonginx-service.exeand place it inDirectory A. - Create a configuration file named
nginx-service.xmlinDirectory Ato define the service parameters. - Open a Command Prompt as Administrator, navigate to
Directory A, and runnginx-service.exe installto register the service. - Start the service via
services.mscor the command line.
# Install the service nginx-service.exe install # Uninstall the service nginx-service.exe uninstall- Download Nginx from the official site and extract it to a directory (e.g.,
Implement two-way data binding with the .sync modifier in Vue 2
The.syncmodifier in Vue 2 provides a shorthand for syncing a prop from a parent component to a child component. To implement this, the child component must emit an event namedupdate:propNamewhenever the value changes. In the provided example, the child component uses a local copy of the prop and a watcher to emit the update event back to the parent, ensuring the parent's state remains synchronized with the child's internal state.<!-- Parent Component --> <template> <div> <button @click="localModal = true">show</button> <!-- The .sync modifier tells Vue to listen for 'update:modal' events --> <item :modal.sync="localModal"></item> </div> </template> <!-- Child Component (item) --> <script> export default { name: "item", props: ["modal"], data() { return { // Initialize local state with the prop value localModal: this.modal, }; }, watch: { // Sync prop changes from parent to child modal(val) { this.localModal = val; }, // Sync local changes from child back to parent localModal(val) { this.$emit("update:modal", val); }, }, }; </script>Implement dynamic component switching in Vue 2
Use the<component>element with the:isattribute to dynamically switch between different components at a single mount point. The:isattribute can accept a component name (string) or a component definition object.<template> <div class="home"> <!-- The :is attribute determines which component to render --> <component :is="currentComponent"></component> </div> </template> <script> import Tab0 from "@/components/Tab0.vue"; import Tab1 from "@/components/Tab1.vue"; export default { data: () => { return { currentIndex: 0 } }, components: { "tab-0": Tab0, "tab-1": Tab1 }, computed: { currentComponent() { return `tab-${this.currentIndex}`; // Returns "tab-0" or "tab-1" } } } </script>Modify jbot monitoring activity in Qinglong
jbot monitoring activity can be modified either via the Qinglong Web UI or directly through the container filesystem.# Manual modification via CLI docker exec -it qinglong /bin/bash cd /ql/data/jbot/conf # Remove and recreate jk.json rm jk.json && touch jk.json && vi jk.jsonImplement BEM CSS naming convention
BEM (Block, Element, Modifier) is a component-based naming convention used to divide a user interface into independent blocks, enabling code reuse and simplifying the development of complex UIs.
Core Concepts:
- Block: A reusable, functionally independent page component (e.g.,
.search-form). - Element: A part of a block that cannot be used independently. It is denoted by two underscores (e.g.,
.search-form__input). - Modifier: Defines the appearance, state, or behavior of a block or element. It is denoted by a single underscore (e.g.,
.search-form_theme_islands).
Naming Rules:
- No Element Nesting: Elements should not be nested within other elements in the class name. Avoid patterns like
block__elem1__elem2. Instead, useblock__elem2orblock__elem1-elem2. - Modifier Placement: Modifiers can be applied directly to a block (
block-name_modifier-name) or to an element (block-name__element-name_modifier-name). - Key-Value Modifiers: Modifiers can follow a key-value pair format for more specificity:
block-name_modifier-name_modifier-value.
<!-- Correct BEM implementation --> <form class="search-form search-form_theme_islands"> <!-- Element of the block --> <input class="search-form__input" /> <!-- Element with a size modifier (key: size, value: m) --> <button class="search-form__button search-form__button_size_m">Search</button> </form> <!-- INCORRECT: Avoid nesting elements in the name --> <div class="search-form__content"> <input class="search-form__content__input" /> <!-- Wrong --> </div>- Block: A reusable, functionally independent page component (e.g.,
Use Grouping and Backreferences for complex patterns
Grouping allows you to treat multiple characters as a single unit and reuse them:
(...): Captures a group for quantification or backreferencing.(?:...): Non-capturing group; matches the pattern but does not save the result for backreferencing.\1,\2, etc.: Backreferences that match the exact text captured by a previous group. This is used to ensure consistency, such as matching a closing HTML tag that matches the opening tag (e.g.,<(\w+)>.*<\/\1>).