基于nodejs服务端web组件化开发(二、组件的包装)

79 阅读2分钟

二、组件的包装

上节说到通过 html,css 组件构建工具的使用——标签模板。这节要说说怎么包装问题。

先来看看 define 应该长得怎么样

define(组件名字,{模板函数,样式函数,脚本函数})

先弄个函数再说

// hcdr/index.js 中添加
let container = { style: [], script: [] }
function define(name, { template, style, script }) {
  //要想接着给其他组件调用,返回一个函数再说,参数可能是模板可能是样式的,
  // data-表示模板要传递的参数,css-表示样式传递的参数,于是
  return function (data, css) {
    // 如果调用后应该返回字符串出去,否则后面的标签模板就没法工作了
    // 返回之前先弄个容器将样式和模板进行保存再说
    container.style.push(style ? style(css || {}) : "")
    container.script.push(script || "")
    return template(data || {})
  }
}

// 导出
module.exports = { html, css, define }

从上面定义的方法来说,给组件起个名字,然后把定义的 template,style,script 塞给它后,把样式和脚本缓存起来,返回生成的 html 代码给调用者,这样我们定义组件的工具就搞定了,试着定义几个组件试试。 下面,我们将组件一律用大驼峰表示用来区别普通方法。

// test2.js 新增
const {html,css,define}=require("hcdr")

// Header
const Header = define("Nabar", {
  template: () => html`<div class="header">头部</div>`,
  style: () => css`
    .navbar {
      color: red;
    }
  `
})

// Navbar
const Navbar = define("Nabar", {
  template: () => html`<div class="navbar">导航</div>`,
  style: () => css`
    .navbar {
      color: blue;
    }
  `
})

// Footer
const Footer = define("Footer", {
  template: () => html`<div>底部</div>`
})

// Layout 是个容器类的组件,留个类似插槽的变量main来填充主要内容
const Layout = define("Layout", {
  template: ({main}) => html`
    <div id="app">
      <header>${Header()}</header>
      <nav>${Navbar()}</nav>
      <main>${main}</main>
      <footer>${Footer()}</footer>
    </div>
  `
})

// Home
const Home = define("Home", {
  template: () => html`<h1>我是主页</h1>`script:()=>{
      console.log("我是主页")
  }
})

console.log(Layout({slot:Home()}))

执行后,可以得到下面的结果

<div id="app">
  <header><div class="header">头部</div></header>
  <nav><div class="navbar">导航</div></nav>
  <main><h1>我是主页</h1></main>
  <footer><div>底部</div></footer>
</div>

我们页面结构代码已成功生成,但是没看到样式和脚本 这种结构写起来感觉还是很爽的,都是常规的函数和对象。 下节,我们就该把这个给弄上去...