当前位置: 首页 > 科技观察

基于Strview.js项目的脚手架StrviewApp是如何搭建的?

时间:2023-03-15 13:48:17 科技观察

前言前几天因为看源码的热情,搞了个玩具Js库Strview.js。为什么会有这样的玩具图书馆?其实也不全是因为晚上没事做,主要是想通过实际操作来锻炼自己的开发能力。之前我也写过一篇文章,那篇文章只是大概的介绍,没有细说。之前,你可能认为它类似于Vue.js。不错,是参考了Vue.js的思路,但还是有一些差异(个人看法)。那么,今天,本文就来介绍一下基于Strview.js的项目脚手架工具StrviewApp。如果您觉得对您有用,可以继续阅读。如果你认为这篇文章绝对是一篇垃圾邮件,你也可以避开它。好的,让我们现在开始谈正事。你准备好了吗?跟我来!StrviewAPP快速上手你可以通过StrviewCLI快速初始化StrviewAPP项目,你可以这样做:全局安装。npmistrview-cli-g安装完成后,可以查看版本。strview-cli-v最后初始化项目,就是自定义项目的名字。strview-cliinit或者strview-clii这样就构建了一个StrviewAPP工程。StrviewAPP项目结构下图是StrviewAPP项目的组织结构。下面,我将描述每个文件和文件夹的作用。config这是webpack的配置文件夹,这里配置了所有关于webpack的配置。文件夹中有以下三个文件,分别为:-webpack.base.js//基础配置-webpack.dev.js//开发环境配置-webpack.pro.js//生产环境配置公共资源文件夹.-favicon.ico//网站logo-index.html//模板文件.gitignore哪些文件不需要加入版本管理。.prettierrcPrettier规则配置文件。package.json定义了本项目所需的各个模块,以及项目配置信息(如名称、版本、许可证等元数据)。src文件夹是StrviewAPP项目的主文件夹。让我们看看这个文件夹里有什么。-assets//存放静态文件-components//组件文件夹-data//publicstate文件夹-methods//方法文件夹-style//样式文件夹-template//模板文件夹-App.js//页面入口-main.js//项目入口文件src文件夹详解上面我们已经分析了项目结构,接下来我们将进一步分析src文件夹中的文件组成以及它们是如何相互配合的。1.main.js首先我们来看main.js文件,它是项目的入口文件。让我们看一下文件的内容。import{createView}from'strview';importdatafrom'./data';importAppfrom'./App';importmethodsfrom'./methods';createView({el:"#app",template:App,data});//该事件在createviewAPI方法()之后处理;我们首先引入了strview.js并引入了createViewAPI来创建视图。那么,让我们跳下去看看这个API是如何使用的。首先我们传入一个对象字面量,第一个属性是el属性,也就是挂载的DOM节点。第二个属性是template属性,就是用来展示视图的模板。第三个属性是data属性,传入的值就是显示的数据。最后我们看到有这么一行注释TheeventishandledafterthecreateviewAPI,也就是说事件方法必须在createViewAPI之后调用,也就是methods();这里。2.App.js上面说了App.js是使用模板来展示视图的,下面我们就来看看吧。importmyParagraphfrom'./components/myParagraph';importcardfrom'./components/card';importhelloTemplatefrom'./template/helloTemplate';import'./style/index.css';constApp=`${helloTemplate}点击{a},{b},(a和b都变了)

  • {age}
  • {name}
  • {msg}
  • {a},(a会变)

    {b},(b会变)

    {obj.a.b}

    {arr}

    {ob.name}

    ${myParagraph}${card}{b}`exportdefaultApp我们看到代码最后导出了一个模板字符串,就是常量App。我们可以看到模板字符串中有一些类似label语句的代码。是的,这就是Strview.js的症结所在,使用带有类似标签语句的模板字符串来构建视图。另外,我们看到除了最上面引入样式文件外,从components文件夹中导入了两个文件,从template文件夹中导入了一个文件。从前面的目录结构我们知道,components文件夹存放的是组件,template文件夹存放的是模板文件。如何在页面上渲染导入的模板和组件?然后您需要在模板字符串中使用${}占位符。您可能会在这里感到困惑,因为您在这些文件中看不到任何内容,但别担心,我们会慢慢来。你只需要记住它们发生在这里。这种标签你可能见过,你可能会说没见过!这只是一个自定义组件。具体为什么要这样写,我们到下面的组件时再分析。但是需要注意的是,如果我们需要在我们的组件中存储内容,我们需要在自定义组件之前使用一个占位符${},比如这里的${card},card是一个导入的组件。最后我们会在标签中找到类似{}的符号,用来挂载数据,也就是动态更新数据。我们稍后会详细讨论这些数据。3.Template上面说了这个文件夹是用来存放模板文件的,下面我们就来了解一下。-helloTemplate.csshelloTemplate.jshelloTemplate.css样式文件没什么好说的。.container{text-align:center;margin-top:100px;line-height:46px;}.container>img{margin-bottom:40px;}helloTemplate.js我们来看看这个js文件。importlogofrom'../assets/logo.png';import'./helloTemplate.css';exportdefault`

    HelloStrview.js

    `;在上面的代码中,我们可以看到我们在头部引入了一张图片和一个样式文件,然后在下面导出了一个模板字符串。导入的镜像呢!使用${}占位符绑定到img标签。简单介绍完template文件夹,我们再来看components文件夹。4.components文件夹用于存放组件。组件的概念大家可能不陌生,目前在Vue、React等前端框架中都在使用组件。我们先来看看这个文件夹的目录结构。-card.js-myParagraph.js可以看到,里面有两个js文件。首先查看文件myParagraph.js。customElements.define('my-paragraph',classextendsHTMLElement{constructor(){super();consttemplate=document.getElementById('my-paragraph');consttemplateContent=template.content;this.attachShadow({mode:'open'}).appendChild(templateContent.cloneNode(true));}});constmyParagraph=`

    Mydefaulttext

    让我们有一些不同的文本!
  • 让我们拥有一些不同的文本!
  • Inalist!
  • `exportdefaultmyParagraph先看前面的部分,customElements对象下有一个define方法。这是什么方法?实际上,这部分使用了WebComponents。它是什么?我们在MDN中是这样定义的。Web组件是一组不同的技术,允许您创建可重用的自定义元素(它们的功能封装在您的代码之外)并在您的Web应用程序中使用它们。WebComponents拆解起来其实还是挺复杂的,这里就不详细分析了。以下是MDNURL,您可以跟着几个示例一起操作。https://developer.mozilla.org/zh-CN/docs/Web/Web_Components这里要知道define方法第一个参数需要传入一个自定义标签名,第二个参数是传入一个类.需要自定义的地方就是getElementById()方法中第一个参数和第二个参数中的参数。建议使用相同的字符串。调用define方法后,需要先用template标签包裹模板字符串,可以理解为初始化。我们可以看到模板标签上有一个id选择器,和上面getElementById()方法中的参数是一样的。是的,这个地方必须一一对应。此外,我们看到紧接着下方有一个样式标签,它定义了组件样式。最后是组件的内容。这里定义了一个p标签,也就是一个slot,定义了一个name属性。而且这里有标签文字,默认显示。如果组件中没有内容,则默认显示该内容。

    Mydefaulttext

    我们看下面的代码,都是用.另外,标签里面是一个普通的标签语句。然而,一个区别是这些普通的标签语句有一个插槽属性,用作插槽的模板。让我们拥有一些不同的文字!
  • 让我们拥有一些不同的文字!
  • Inalist!
  • 分析完myParagraph.js文件,我们接着分析card.js文件。其实和myParagraph.js文件一样,只是它负责定义组件。在上面的App.js中,我们提到需要在自定义组件前使用一个占位符${},比如这里的${card},card就是导入的组件,引用它。customElements.define('my-card',classextendsHTMLElement{constructor(){super();consttemplate=document.getElementById('my-card');consttemplateContent=template.content;this.attachShadow({mode:'open'}).appendChild(templateContent.cloneNode(true));}});constcard=`
    `exportdefaultcard5.data这个文件夹负责存放数据状态文件,主要有这两个文件.-index.js-ob.js我们先来看看index.js文件。很简单,就是简单的导出一个对象,ob.js文件也是一样的。index.jsimportobfrom'./ob';exportdefault{a:"你好",b:18,name:"maomin",age:9,msg:'Strview',arr:['0'],obj:{a:{b:1}},ob}ob.jsexportdefault{name:'kk'}6.方法我们在main.js文件中提到了一点。importmethodsfrom'./methods';//在createviewAPImethods()之后处理的事件;就是调用这个方法。那么,让我们看一下下面的方法文件夹。我们知道这个文件夹的作用是提供事件处理方法。它的目录结构如下:-index.js-item.js首先看item.js文件。import{reactive,ref}from'strview'functionexecutes(){reactive().obj.a.b=3;ref().name='Strview.js';}functionuseItem(){ref().b=100;}export{executes,useItem}我们可以看到header中引入了两个方法reactive和ref。前者负责处理复杂类型的数据,如数组、嵌套对象等,后者负责处理简单类型的数据,如Singleobject、primitivevalue。可以看到在上面的代码中,我们通过调用reactive()和ref()这两个方法来实现数据的响应式,然后导出executes()和useItem()这两个方法。接下来,让我们看一下index.js文件。import{eventListener}from'strview';import{executes,useItem}from'./item';consteventList=[['.color-red','click',executes],['.list>li:nth-child(2)','click',useItem]]functionmethods(){for(letindex=0;index