解决v-html无法理解vue模版的问题-动态获取模版,动态插入app并使用当下app状态数据需求

vue

很多情况下,我们需要使用动态的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状态数据需求 的全部内容, 来源链接: utcz.com/z/379007.html

回到顶部