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-chalk
The 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.scss
In 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