笔记:Vue.js 中使用动态组建动态渲染路由的 router-link


 拍摄于 2017-02-03,开工大吉。
拍摄于 2017-02-03,开工大吉。

标题中的动态渲染路由,不确定词用的是否精确,想要表达的意思应该是:将包含 router-link 的字符串传给 Vue 组件的 template 属性的时候,组件在实例化之后自动拥有 router-link 的路由功能(dynamically compile router-link) ,字符串比如如下:

涉及到这个问题的具体需求:

  1. 有一些 legacy 的数据接口,里面包含很多 <a href="link">link</a>
  2. 为了配合 Vue Router 总已经配置好的路由,需要把 <a href="link">link</a> 转换成 <router-link to="link">link</router-link>
  3. 转换成功后的 <router-link>link</router-link> 得可用;

Vue 中保留的 component 组件和 v-bind:is

第一步和第二步在项目中通过正则的方式可以得到挺圆满的解决,主要卡在第三步。 开始尝试了挺多种方式都没能得到可用的 router-link,首先想到 Vue 在编译的时候,会不会自动帮我完成了这一步的转换,通过 routerString,结果不行;其次想到了 v-html 这个 API 能不能帮忙,结果它也无能为力。

最后去社区里发帖询问才知道可以通过生成动态组件,配合一个特殊属性 v-bind:is(:is)(API 链接,暂时没有中文) 的方式来达到预期效果。

关于 component 和 v-bind:is:component 其实是 Vue 的一个预留组件,类似 JavaScript 中 return 是一个预留关键字,一般存在于 template 属性中。

关于 component 和 v-bind:is:component 其实是 Vue 的一个预留组件,类似 JavaScript 中 return 是一个预留关键字,一般存在于 template 属性中。

其次可以对照参考官方 API 文档做的这个 Pen,通过 v-bind:is 来动态加载不同的组件。Pen 中有两个组件:Home 和 Post,通过按钮实现动态挂载。

See the Pen Vue.js dynamic compile router-link by Lien (@movii) on CodePen.

CodePen 链接

点击按钮,在 Home 和 Post 两个组件之间切换,不需使用 vue-router。

示例一

原帖里问的时候本身就包含一些上下文需求,比如需要转换成 router-link 的 string 其实是由外部的 props 传入到当前组件,而项目本身也基于单文件组件的形式进行开发,这里首先试图将问题的解决抽象出来做一个简单的 demo,基于 Vue Router 官方文档中的开始部分的例子,非常简单的 Vue Router 结构。

HTML 部分,将原来例子中的 <router-link to="/foo">Go to Foo</router-link> 改成了一个组件 <dynamic-link>

<dynamic-link> 组件需要渲染出来的内容

<dynametic-link> 的组件声明

See the Pen Dynamically Compile router-link using dynamically component in Vue.js by Lien (@movii) on CodePen.

CodePen 链接

示例二

其次是一个更加接近项目中的例子,父组件通过 props 将值传给子组件,子组件内部自动转换 text 到 router-link。

子组件 <dynamic-link>

HTML 结构

CodePen 链接,预览:

See the Pen Dynamically Compile router-link using dynamically component in Vue.js by Lien (@movii) on CodePen.

CodePen 链接

参考

  • 在 Vue 社区我发的问题帖链接
  • Vue.js 中的动态组件文档:中文英文
  • Vue.js 中的 v-bind:is 文档:英文(暂时没有中文);
  • Vue.js GitHub 中一个 issue,发布时间是 2016 年 1 月 4 日,很想是对通过 :is 来绑定 props 创建动态组件的最早提案:链接

感谢阅读

你们好, 2018 年初把小站从 Jekyll 迁移到 Hugo 的过程中,删除了评论区放的 Disqus 插件,考虑有二:首先无论评论、还是对笔记内容的进一步讨论,读者们更喜欢通过邮件、或者 Twitter 私信的方式来沟通;其次一年多以来 Disqus 后台能看到几乎都是垃圾留言(spam),所以这里直接贴一下邮件、以及 Twitter 账户 地址。

技术发展迭代很快,所以这些笔记内容也有类似新闻的时效性,不免有过时、或者错误的地方,欢迎指正 ^_^。

BEST
Lien(A.K.A 胡椒)
本站总访问量 本站总访客量 本文总阅读量