解决v-html无法理解vue模版的问题-动态获取模版,动态插入app并使用当下app状态数据需求
很多情况下,我们需要使用动态的html作为某个dom元素的inner html,如果这个内容是标准的html的话,则v-html能够圆满满足需求,而如果内容包含了vue组件,则使用v-html就不能达到你希望的目标了。
我研究有两种方案来解决,一种原生使用v-if提供的compile和mount特性;第二种类则使用render函数带来的特殊能力实现这一点。
其中render函数的方案有一个现成的vue组件作为参考. v-runtime-template.
该组件产生的背景:
在项目开发中需要从server上接收template string.比如,即允许用户自己通过拖拽来设计接口风格的程序中,通常被保存为vue template code,而该code会使用由前端工程师开发好的预定义组件。这些组件将通过api调用请求数据并且填充页面的一个部分。
正如上面所说的,v-html很大程度上能够部分满足需求:
<template>
<div>
<div v-html="template"></div>
</div>
</template> <script>
export default {
data: () => ({
template: `
<h2>Howdy Yo!</h2>
<a href="croco-fantasy">Go to the croco-fantasy</a>
`
}),
};
</script>
上面的template字符串可以从server ajax call中获得。问题是,如果该template string中包含了vue template code,则无能为力!
export default {
data: () => ({
template: `
<app-title>Howdy Yo!</app-title>
<vue-router to="/croco-fantasy">Go to the croco-fantasy</vue-router>
`
}),
};
v-html并不能理解vue-router这个tag,因此将会丢弃很多重要功能。
这时作者就需要开发一个能够解决该类问题的"proxy"组件
v-runtime-template的实现原理是: 自动获得v-runtime-template的父组件的context并且使得vue编译并且attach.
render(h) {
if (this.template) {
const parent = this.parent || this.$parent
const {
$data: parentData = {},
$props: parentProps = {},
$options: parentOptions = {}
} = parent;
const {
components: parentComponents = {},
computed: parentComputed = {},
methods: parentMethods = {}
} = parentOptions;
const {
$data = {},
$props = {},
$options: { methods = {}, computed = {}, components = {} } = {}
} = this;
const passthrough = {
$data: {},
$props: {},
$options: {},
components: {},
computed: {},
methods: {}
};
//build new objects by removing keys if already exists (e.g. created by mixins)
Object.keys(parentData).forEach(e => {
if (typeof $data[e] === "undefined")
passthrough.$data[e] = parentData[e];
});
Object.keys(parentProps).forEach(e => {
if (typeof $props[e] === "undefined")
passthrough.$props[e] = parentProps[e];
});
Object.keys(parentMethods).forEach(e => {
if (typeof methods[e] === "undefined")
passthrough.methods[e] = parentMethods[e];
});
Object.keys(parentComputed).forEach(e => {
if (typeof computed[e] === "undefined")
passthrough.computed[e] = parentComputed[e];
});
Object.keys(parentComponents).forEach(e => {
if (typeof components[e] === "undefined")
passthrough.components[e] = parentComponents[e];
});
const methodKeys = Object.keys(passthrough.methods || {});
const dataKeys = Object.keys(passthrough.$data || {});
const propKeys = Object.keys(passthrough.$props || {});
const templatePropKeys = Object.keys(this.templateProps);
const allKeys = dataKeys.concat(propKeys).concat(methodKeys).concat(templatePropKeys);
const methodsFromProps = buildFromProps(parent, methodKeys);
const finalProps = merge([
passthrough.$data,
passthrough.$props,
methodsFromProps,
this.templateProps
]);
const provide = this.$parent._provided;
const dynamic = {
template: this.template || "<div></div>",
props: allKeys,
computed: passthrough.computed,
components: passthrough.components,
provide: provide
};
return h(dynamic, { props: finalProps });
}
}
以上代码就是v-runtime-template的核心render函数.
<template>
<div>
<v-runtime-template :template="template"/>
</div>
</template> <script>
import VRuntimeTemplate from "v-runtime-template";
import AppTitle from "./AppTitle"; export default {
data: () => ({
template: `
<app-title>Howdy Yo!</app-title>
<vue-router to="/croco-fantasy">Go to the croco-fantasy</vue-router>
`
}),
components: {
AppTitle
}
};
</script>
上面就是使用v-runtime-template核心用法代码。有一点需要额外指出的是,它还可以访问父组件的scope,意味着任何通过data,props,computed或者methods能够访问的都能用.这样你就可以拥有dynaimc templates的能力:可被父组件访问的活跃reactive数据.
比如:
export default {
data: () => ({
animal: "Crocodile",
template: `
<app-title>Howdy {{animal}}!</app-title>
<button @click="goToCrocoland">Go to crocoland</button>
`
}),
methods: {
goToCrocoland() {
// ...
}
}
如果你需要动态地应用从server端返回的template,并能插入vue app中获得对应的scope context访问能力,那么v-runtime-template是一个非常不错的选择!~
https://alligator.io/vuejs/v-runtime-template/
解决v-html无法理解vue模版的问题-动态获取模版,动态插入app并使用当下app状态数据需求的更多相关文章
- 深入理解 Vue 组件
深入理解 Vue 组件 组件使用中的细节点 使用 is 属性,解决组件使用中的bug问题 <!DOCTYPE html> <html lang="en"> ...
- 深刻理解Vue中的组件
转载:https://segmentfault.com/a/1190000010527064 --20更新: Vue2.6已经更新了关于内容插槽和作用域插槽的API和用法,为了不误导大家,我把插槽的内 ...
- VUE.js入门学习(3)-深入理解VUE组建
1.使用组件的细节点 (1)is="模版名" (2)在子组建定义data的时候,data必须是一个函数,而不能是一个对象,每个子组建都有自己的数据存储.之间不会相互影响. (3)操 ...
- 理解vue中的scope的使用
理解vue中的scope的使用 我们都知道vue slot插槽可以传递任何属性或html元素,但是在调用组件的页面中我们可以使用 template scope="props"来获取 ...
- 理解Vue中的Render渲染函数
理解Vue中的Render渲染函数 VUE一般使用template来创建HTML,然后在有的时候,我们需要使用javascript来创建html,这时候我们需要使用render函数.比如如下我想要实现 ...
- 深入理解vue
一 理解vue的核心理念 使用vue会让人感到身心愉悦,它同时具备angular和react的优点,轻量级,api简单,文档齐全,简单强大,麻雀虽小五脏俱全. 倘若用一句话来概括vue,那么我首先想到 ...
- 简单理解Vue中的nextTick
Vue中的nextTick涉及到Vue中DOM的异步更新,感觉很有意思,特意了解了一下.其中关于nextTick的源码涉及到不少知识,很多不太理解,暂且根据自己的一些感悟介绍下nextTick. 一. ...
- vue系列---理解Vue中的computed,watch,methods的区别及源码实现(六)
_ 阅读目录 一. 理解Vue中的computed用法 二:computed 和 methods的区别? 三:Vue中的watch的用法 四:computed的基本原理及源码实现 回到顶部 一. 理解 ...
- 彻底解决eslint与webstorm针对vue的script标签缩进处理方式冲突问题
彻底解决eslint与webstorm针对vue的script标签缩进处理方式冲突问题 2018年12月08日 21:58:26 Kevin395 阅读数 1753 背景不多介绍了,直接上代码. ...
随机推荐
- centos7静黙安装Oracle11.2.0软件响应文件oracle_install.rsp
oracle.install.responseFileVersion=/oracle/install/rspfmt_dbinstall_response_schema_v11_2_0 oracle.i ...
- 动态加载swiper,默认显示最后一个swiper-slide解决方案???
问题描述: 用ajax动态加载swiper-slide以后,由于我是自适应屏幕的尺寸来决定一屏显示多少图片,所以加了 slidesPerView:'auto'这条属性,加了这条属性过后,每次刷新页面的 ...
- 面向对象高级B(元类)
元类 python一切皆对象,类实际上也是一个一个对象 类是一个对象,那他一定是由一个类实例化得到,这个类就叫元类 如何找元类 class Person: def __init__(self, nam ...
- Scrapy笔记06- Item Pipeline
Scrapy笔记06- Item Pipeline 当一个item被蜘蛛爬取到之后会被发送给Item Pipeline,然后多个组件按照顺序处理这个item. 每个Item Pipeline组件其实就 ...
- GOOD BYE OI
大米饼正式退役了,OI给我带来很多东西 我会的数学知识基本都在下面了 博客园的评论区问题如果我看到了应该是会尽力回答的... 这也是我作为一个OIer最后一次讲课的讲稿 20190731 多项式乘法 ...
- 使用mxnet实现卷积神经网络LeNet
1.LeNet模型 LeNet是一个早期用来识别手写数字的卷积神经网络,这个名字来源于LeNet论文的第一作者Yann LeCun.LeNet展示了通过梯度下降训练卷积神经网络可以达到手写数字识别在当 ...
- virtualbox安装问题总结
还是老问题 重点重点: https://blog.csdn.net/Loisleen/article/details/84975165#1install_the_gcc_make_perl_packa ...
- Spring Boot 2.2.1 发布,一个有点坑的版本!
上一篇:Spring Boot 2.2.0 正式发布,支持 JDK 13! Spring Boot 2.2.0 没发布多久,Spring Boot 2.2.1 又发布了,这是一个很有意思,又有点 &q ...
- mysql(三)索引
参考文档:索引的基本操作 & 简单优化:https://www.cnblogs.com/zz-tt/p/6609828.html聚簇索引vs非聚簇索引:https://www.cnblogs. ...
- 记一次Pr字幕模糊问题及解决方法
目录 问题: 解决: 问题: 1.导出视频后,发现字幕很模糊 2.发现我们导出时的设置如下图,画面大小为432x244 3.即使暴力修改宽度为1080,导出画面的清晰度也不会有什么变化. 解决: 1. ...