Open zoumiaojiang opened 6 years ago
我这边总结了一下 mip 1.0 和 2.0 的方案,大部分情况都能够兼容的,但是在 HTML 方面有几点需要讨论下:
mip 1.0 含有几个特殊的标签:
<mip-data>
、<template>
以及几个特殊的属性:
m-bind
、m-text
、on
等
这里有几个问题: 1、由于现在有站长使用了这些特殊的标签和属性,我们是否需要兼容 mip 1.0 的这些? 2、如果我们要兼容,怎么设计组件化方案? 3、如果不兼容,怎么考虑站长升级的问题?
我细化了下我们的方案,现在应该是可以完全兼容 1.0 的,大家可以 review 一下
sandbox方案可参考 https://github.com/searchfe/sandbox
mip 组件化方案
mip 组件化方案就是 vue 2.x 的方案,我们对 vue 做一些适应于 MIP 解决方案的改造处理,组件化方案主要包含以下几个部分:
其中,模版语法,生命周期、双向数据绑定原理等内容都和 vue 保持一致。
我们重点需要关注几点内容:
组件数据传入的机制
当在 html 页面中以自定义元素的方式引用组件的时候,需要考虑到直出数据的传入问题,在这里有两种方式:
props 传值的方式
适合传入「字符串」、「数字」,「布尔型」等简单类型的数据
<script>
的方式适合传入结构化的数据,比如「数组」、「对象」等:
如果不想使用
script
方式传入结构化的数据,还是想要借助于 props 机制,由于 custom element 是跑在 runtime 的时候,所以不能直接将 object 或者 array 丢到 props 里,只能换一种方法:props 可以接受 JSON string,MIP2.0 会自动解析 JSON string 为结构化的绑定数据:在模版中就可以通过 props 获取这个对象了:
兼容 MIP 1.0 的匿名 slot 机制
比如现在浏览器的 mip 页面中的
<mip-b>
标签的结构是如下所示:对应的
<mip-b>
的组件 vue 模版如下:只要在组件中定义一个匿名的 标签,这个匿名的 slot 将接收 custom element 中的内容,当然也可以在 custom element 中指定具名的 slot,前提是模版中需要定义这个具名的 slot。
HTML 模版语法机制
在 html 的使用自定义标签中,不允许直接出现 vue 的模版语法,如果出现了,都当成正常 HTML 内容处理:
这段 html 只会渲染成
{{ data.name }}
,而不是xxx
。mip-template
如果需要在浏览器端的自定义标签中支持模版语法,需要借助
mip-template
标签,可以直接写 vue 模版语法,使用方式如下:这种方式适用于只是纯展现的场景,不适合有交互的情况。并且必须使用
mip-template
标签。兼容 1.0 的
<template>
标签为了兼容 mip 1.0 的展现场景,由于 1.0 版本中的
<template type="mip-mustache">
标签是基于 mustache 实现的,所以我们可以直接使用 mip 的mip-mustache
组件,<template type="mip-mustache">
只会在其他组件中被使用,例如被mip-list
组件使用:默认
<template type="mip-mustache">
标签为一个匿名的slot
,如有多个,需要标明具名的slot
。支持 HTML 事件处理
为了兼容 1.0,需要提供这样的一种语法糖,用来在 HTML 标签中可以绑定事件,并使用组件的事件处理函数或者调用 MIP 自身的通用事件处理函数。
兼容 1.0 的
<mip-data>
标签 和m-bind
属性相关这部分可以完全直接使用 mip 1.0 关于 mip-bind 的逻辑,相当于除了 2.0 组件化方案外,另外再提供一种双向绑定的机制。
了解 mip 1.0 这块的内容后,发现 1.0 的
<mip-data>
标签 和mip-bind
属性相关只是适合做纯展现和简单交互的工作,复杂的工作还是要依赖 2.0 组件化机制。新增 asyncData/syncData 生命周期支持
asyncData 生命周期中主要是处理异步请求数据,这部分的数据对应的内容不会在非浏览器环境下(通常指的是 spider)执行。 syncData 和 created 生命周期一致,处理需要直出(props 或者组件内的
<script>
中的)的数据以及对应内容,这个在非浏览器环境中也会执行。需要对当前执行环境进行判断
支持 spider 环境的「SSR」
当在 spider 环境执行 MIP 2.0 runtime 的时候,为了 SEO 和性能需要,要确保能够渲染出一份内容直接存储到 MIP CDN,然后在搜索结果页中可以被展现。
原理是:在 spider 环境下,不会执行
asyncData
的生命周期,只会执行syncData
的生命周期,这样开发者可以决定哪些内容是可以直接被搜索引擎索引并缓存的。这里面需要注意的是,需要确保每个依赖的组件都会被渲染完成,类似 VUE 的 SSR 功能,也就是 MIP 2.0 组件在 spider 环境中渲染出来的内容类似如下:
组件反解混合机制
当在搜索结果页中展现了 MIP CDN 的内容之后,其实有两个问题:
这时候,需要有个步骤将 MIP CDN 中在搜索结果页展现的内容进行组件反解混合,在 MIP CDN 中的页面中是以下形式:
而对应的 MIP 组件模块应该是如下:
组件反解混合解决方案:
参照 VUE SSR 方案进行 MIP CDN 内容到 MIP 组件 client 端渲染的反解混合绑定事件的操作(这里需要深入了解一下 VUE SSR 机制)。
提供组件安全沙盒环境
MIP 2.0 组件需要控在制组件中使用危险的全局变量的操作,比如
window
,document
等,MIP 需要提供一个模块来专门提供给组件自动注入并使用(借助于 loader 来解决)。sandbox
具体的实现细节需要由 MIP runtime 给出 sandbox 模块。封装基础组件
MIP 插件化
实现和 Vue 一样的插件化机制。
组件化方案的产出
产出为
umd
模块