Component structures,

Then chapter 1 begins the component section

First create three directory folders under Packages with the following directory structure:

+ uses-components # theme-chalk # style - utils # public methodCopy the code

PNPM init -y generates three packages and changes package.json. The three contents are similar

# select * from components;"name": "@w-plus/components"."version": "1.0.0"."main": "index.ts"."scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "WQ"."license": "ISC"
}
Copy the code

We now have a package.json file in each directory, and now we want each package to reference each other, so install it in the root directory or distribute it separately

PNPM install @w-plus/components -w install the package in the root directory. -wor –workspace will allow you to install the package in the root directory

To write an icon component, create an icon directory under the Components directory as follows:

+ components + icon + SRC # props and public methods for components.component.vueCopy the code

Define props under Icon. ts

// Here are the props and public methods for the component
import type { ExtractPropTypes } from "vue" 
// as const, which makes each property of the object readonly
export const iconProps = {
    size: {type:Number
    },
    color: {type:String}}as const

export type IconProps = ExtractPropTypes<typeof iconProps>
Copy the code

Write component code in icon.vue

<template>
  <i class="w-icon" :style="style">
      <slot></slot>
  </i>
</template>

<script lang="ts">
import { computed, defineComponent } from "vue";
import { iconProps } from "./icon";

export default defineComponent({
  name: "WIcon".props: iconProps,
  setup(props) {
      const style = computed(() = > {
          if(! props.size && ! props.color){return{}}return {
              ...(props.size ? { 'font-size':props.size + 'px'}, {}),... (props.color ? {'color':props.color} : {}),
          }
      })

      return { style }
  },
});
</script>
Copy the code

Export the component, index.ts, in the component entry

import { withInstall } from "@w-plus/utils/with-install"
import Icon from "./src/icon.vue";

const WIcon = withInstall(Icon);

export{
    WIcon
}
export default WIcon;
Copy the code

Finally, introduce the component test in main.ts under Play, add the following code:

import { WIcon } from "@ w - plus/components/icon" app. Use (WIcon)Copy the code

The use(WIcon) error was reported in Plugin_2

So we need to deal with this problem. In the index.ts under the Icon component, change the code to:

import { withInstall } from "@w-plus/utils/with-install"
import Icon from "./src/icon.vue";

const WIcon = withInstall(Icon);
export default WIcon;
Copy the code

Since this is handled in every component, we wrap a withInstall method and create a new with-install.ts file under utils as follows:

import type { App, Plugin } from "vue"; // The import type is not the value of the import App

/** * Install is executed when external components use, and then the component is registered as global */

// The type must be exported or the.d.ts file will not be generated
export type SFCWithInstall<T> = T & Plugin;

 /** * Define a withInstall method to handle the following component type problems *@param comp 
  */
export const withInstall = <T>(comp: T) = > {
   Comp. Install = function(){/** ** Plugin = T&Plugin */
   (comp as SFCWithInstall<T>).install = function (app: App) {
     app.component((comp as any).name, comp);
   };
   return comp as SFCWithInstall<T>;
 };
 
Copy the code

Type alias

A type alias can be used to receive the extracted inline type for reuse, and a type alias can be defined in the format “Type alias name = type definition” as shown below

/** Type alias */
{
  type LanguageType = {
    /** The following are the interface attributes */
    /** Language name */
    name: string;
    /** Service life */
    age: () = > number; }}// For scenarios that cannot be covered by the interface type, such as composite types and cross types, we can only receive them using type aliases
{
  /** 联合 */
  type MixedType = string | number;
  Cross / * * * /
  type IntersectionType = { id: number; name: string; } and {age: number; name: string };
  /** Extract the interface attribute type */
  type AgeType = ProgramLanguage['age']; } type alias, that is, we just give the type a new name, not create a new type.Copy the code

We use the Icon component in the app.vue file under Play, and then NPM run dev can see that the component has taken effect

<template>test<w-icon color="blue" :size="20">Hello Icon</w-icon>
</template>
Copy the code

The Icon component needs to have an Icon. Here, use iconfont. Create a new project in iconfont named W-plus, and then add the Icon you want to add to the Icon library, open the project Settings, and change the Icon prefix.

Once set up, download the project locally

Then we need to write a style file in our style directorytheme-chalkThe directory structure is as follows:

+ theme-chalk + SRC + fonts # -iconfont. TTF -iconfont. Woff -iconfont. Woff2 + mixins-config. SCSS # Icon. SCSS # icon file - index. SCSS # entryCopy the code

Config. SCSS code is as follows (sASS syntax) :

$namespace:'w'/** * BEM <div class="z-cell">
    <div class="z-cell__label"></div>
    <div class="z-cell__value is_check"></div>
</div>

*/
Copy the code

The code for mixins.scSS is as follows:

// Declare a public sass method

/* * import config */
@use 'config' as *;

/* * exposes config globally using */
@forward 'config';
Copy the code

Icon. SCSS copy the content of the CSS file you just downloaded into it and modify it as follows:

index.scssIn the importicon.scss, the code is as follows:

@use 'icon.scss';
Copy the code

Modify the play/app.vue file (class = icon.scss) :

<template>test<w-icon color="blue" :size="30" class="w-icon-delete">Hello Icon</w-icon>
</template>
Copy the code

NPM run dev starts the service and tests it.

At this point, the Icon component is almost complete and ready to use


See the next section: Toolkit packaging