如何使用vue中的$onvue 实时更新dataa数据并渲染

Vue 动态添加模板的几种方法 - 推酷
Vue 动态添加模板的几种方法
以下方法只适用于 Vue1.0 版本,推荐系数由高到低排列。
通常我们会在组件里的 template 属性定义模板,或者是在
文件里的 template 标签里写模板。但是有时候会需要动态生成模板的需求,例如让用户自定义组件模板,或者设置组件的布局。
例如要做一个类 select 的组件,用户传入 options 数据,通过
prop 获取选中值,最基本的原型如下。
ponent('XSelect', {
template: `
&div class="select"&
&input :value="value" readonly /&
class="option"
v-for="option in options"
@click="value = option.value"&
&span v-text="option.label"&&/span&
props: ['value','options']
如果此时需要增加一个 API 支持让用户自定义 option 部分的模板。此处用
并不能解决问题。
通过 $options.template 修改
通过打印组件对象可以获得一个信息,在
里定义了一个
属性,写在 template 标签里的模板,最终编译后也会在 $options.template 里。通过文档的
可以得知,在
实例已经结束解析选项, 但是还没有开始 DOM 编译
也就是说,如果用户通过 prop 的数据我们可以获得,但是模板其实还没有渲染成 DOM。经过测试,在
this.$options.template
是可以改变最终生成的 DOM 的,同时也能拿到 props 的内容。
那么我们可以修改下代码,使其支持自定义模板
ponent('XSelect', {
'options',
name: 'template',
default:'&span v-text="option.label"&&/span&'
created() {
varoptionTpl =this.template
this.$options.template =`
&div class="select"&
&input :value="value" readonly /&
class="option"
v-for="option in options"
@click="value = option.value"&
${optionTpl}
用户使用是就可以传入模板了
:value.sync="value"
template="&span&标签: {{ option.label }}, 值: {{ option.value }}&/span&"
:options="[
{value: 1, label: 'a'},
{value: 2, label: 'b'},
{value: 3, label: 'c'}
&/x-select&
可能存在的问题
我们知道 Vue 在内部帮我们做了许多优化,但是在这里可能会由于某些优化导致动态拼接的模板无法渲染成功。例如这里我们不使用
而是手工遍历 options 生成需要的 HTML
consttpl = options.map(opt =&`&div&${this.optionTpl}&/div&`)
this.$options.template =`
&div class="select"&
&input :value="value" readonly&
这里会导致一个 BUG,如果一个页面有多个
组件,并且 options 长度不一样,会导致长的 options 的组件后面几个选项渲染不出来。究其原因是 Vue 会帮我们缓存模板编译结果。翻看代码可以找到
里有做优化,同时提供的
_linkerCachable
使用。我们可以通过设置
this.$options._linkerCachable = false
达到我们的目的。
这样我们就可以开发让用户自定义布局的组件了,用户传入布局参数,通过手工拼接模板,设置了
_linkerCachable = false
也不会被缓存。
通过 $options.partials 动态添加 partial
使用 partials 也能达到添加自定义模板的目的,但是通常的做法是要全局注册 partial,这么做并不优雅。
就是这么做的。如果重名了会被覆盖(初次渲染不会,但是数据更新重新渲染 DOM 时就会被覆盖)。
通过文档我们知道可以在组件内部通过 partials 属性注册局部的 partial,因此自然而然也可以在
this.$options.partials
去动态添加了。
ponent('XSelect', {
template: `
&div class="select"&
&input :value="value" readonly /&
class="option"
v-for="option in options"
@click="value = option.value"&
&partial name="option"&&/partial&
props: ['template','value','options'],
partials: {
option: '&span v-text="option.label"&&/span&'
created() {
if(this.template) {
this.$options.partials.option =this.template
用 interpolate 渲染模板
这种方式就略显蛋疼,而且效率最差。
也是我最开始做动态渲染模板想到的方式,不推荐使用。
ponent('XSelect', {
template: `
&div class="select"&
&input :value="value" readonly /&
class="option"
v-for="option in options"
@click="value = option.value"
v-html="renderOption(option)"&
'options',
name: 'template',
default:'&span v-text="option.label"&&/span&'
methods: {
renderOption(option) {
this.option = option
returnthis.$interpolate(this.template)
目前并没有找到合适的解决方案。2.0 的 Vue 将 compile 工作提前,并且 compiler 也是单独一个包(除非你直接引用的是
文件,包含 compiler 和 runtime,那么第一种方法是适用的),那么并不能动态的生成模板。除非用户传入的是 render 能识别的 DOM tree。
按照这样的思路,其实可以让用户传入的模板预先编译好,传入到组件内,拼接 DOM tree 看起来也能解决问题。那么可以这么玩。
看看就好, 性能太渣
首先要安装 Vue JSX 的
name: 'XSelect',
render(h) {
// 这里获得的 this.template 其实是一个函数,调用该函数返回 DOM
// 因此这里的关键代码是拼接一个新的函数,接受 `option` 参数以及上下文
// 使用 new Function 创建一个新函数
&divclass="select"&
&inputvalue={this.value}readonly/&
this.options.map(option =&
on-click={() =& this.$emit('input', option.value) }
class="option"&
{ new Function('option', 'return ' + this.template)(option)(h) }
props: ['template', 'value', 'options']
el: '#app',
created() {
// 初始化需要传入的模板,这里会被 Vue 的 JSX 插件转成 DOM tree
this.template = h =&&span&标签: { option.label }, 值: { option.value }&/span&
render(h) {
v-model="value"
:template="template"
:options="[
{value: 1, label: 'a'},
{value: 2, label: 'b'},
{value: 3, label: 'c'}
&/x-select&)
综上,在 Vue 1.x 里不存在
的概念,所以想动态修改模板还是有许多方式的,甚至还可以结合
&slot&&/slot&
里的内容拼接进模板里。但 2.0 就麻烦了,并找不到理想的方法。
已发表评论数()
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见
正文不准确
标题不准确
排版有问题
主题不准确
没有分页内容
图片无法显示
视频无法显示
与原文不一致Vue动态组件之表单的CURD - 简书
Vue动态组件之表单的CURD
我在Vue动态组件上的坑上重复踩了两次,一模一样的两次思考过程。我想,这个重复思考的过程并不是偶然,说明是很有必要讨论一下这个问题的。那么为了这个意义,我来说一下最近遇到的问题,有关于『 Vue动态组件 』的问题。由于本人平时经常做的事就是操作表单,Vue的数据绑定和样式绑定等特别适合我现在的开发模式。但是表单常出现的CURD,就不是简单的双向绑定那么简单的操作了。
首先对想要实现的功能进行简短的描述:由于模板数据的Keyword是动态添加的,需要写一条就增加一条keyword记录并输出,而输出的keyword需要可以进行修改和删除操作;在进行修改操作的时候,选中的记录会绑定到输入框中,在输入框中进行修改后,能实现双向绑定到列表中的数据上;删除操作,就是删除当前选中的记录;最后点击提交的时候要能够把所有的keyword的作为一个数组,添加到目标对象中去。这是最简单不过的增删查改,用jQuery来解决的时候,考验的就是对数组结构的操作。但是如果要把他写成组件,将面临『动态组件』的问题。我一开始思考这个问题的时候,并不是打算将所有的keyword作为一个列表输出,然后在列表上进行修改和删除操作。而是打算只要点击“添加关键字”,就动态插入输入框,并为每个输入框绑定v-model,这样就能够实现实时的删除和修改操作。--------------------!!!然而这样的思路是错误的!!!--------------------因为思路是错误的,所以按照错误的思路,第一步想要实现的就是动态生成组件。
这是html部分, 在父级,主要是一个div用来插入组件,一个button用来触发插入事件。在组件部分,主要是一个header用来触发一个测试点击事件,用来测试是否能够调用组件的methods,并且有一个img标签,用来测试是否能够读取构造组件时候的data。
这是js部分,先是创建了一个组件about的构造器,它对应的组件id是html中的#about,构造组件的data只能是一个function,真正的data可以作为一个对象写在function的return中。我们现在构造的这个about组件中的data返回的是一个img的src,它的methods是点击之后log。在model中注册了组件about,使用构造函数new了一个about。并将new出来的about组件手动挂载($mount)到model实例中去,然后再在相应的dom结构(#main)中插入($appendTo)组件。这样每次点击“添加组件”按钮的时候就能够,新注册一个about组件,并手动挂载后插入。这样就实现动态生成组件,但是这样生成的组件只是简单的进行数据渲染,而并不存在表单操作。所以离一开始我的错误思路只差一步,那就是给插入的组件进行双向绑定。
这里顺便一提,对于上传到七牛上的图片文件的在线链接,能够利用在链接后面增加参数,达到压缩图片的效果。如上图,关键字就是『 ?imageView2/1 』,之后的参数『w』『h』和『q』是设置宽、高和图片质量的参数。
这就是实现的效果,一开始只有一个按钮,点击按钮之后,动态插入了组件about。利用extend 、$mount、 $appendTo实现了动态插入组件,之后我又新建了一个demo用于实现动态组件的双向绑定。先上一下效果图,然后就会知道这样做的思路是多么的愚蠢。
输入框中的内容纯粹是为了测试用,下同~第一步,页面自带一个原始的表单,表单包括两个项目,学校名称和学校网址。这个表单绑定的是我的数组对象的第0个元素。
第二步,当我点击“添加组件”按钮之后,我会动态插入一个表单,在数组对象中push一个空对象,并log出我的对象。我插入的表单组件中的项目依然是学校名称和学校网址,并且我让插入的表单组件的输入框绑定我数组的第(length-1)个元素。这样我在输入框中进行的数据操作能够通过双向绑定写入目标对象。在这一步,我在输入框输入的是“集美大学”和""。到这里看上去似乎一切都是正常的,接下来,肯定会需要再次进行push操作。
第三步,再次点击“添加组件”按钮之后,依然是动态插入了一个数组,并且数组对象中push了一个空对象。数组长度为3。我们可以从控制台看出,我的数组对象是正确的。第0个元素是“厦门大学”,第1个元素是“集美大学”。值得一提的是由于log的操作是在点击“添加组件”,然后插入空对象之后触发的,所以我现在新输入的数组的第三个元素“123”并没有在控制台中输出,但是我只要在输入框中进行数据操作,实际上它是写入目标数组的,并不是数组对象的第3个元素没有写入。同时,注意页面上动态组件的变化,当我在第三个表单中填写“123”和“456”的时候,第二个表单的内容也发生的相应的变化,一方面说明,我的双向绑定是有成功写入目标数组的,另一方面,说明表单组件的输入框如果绑定的是第(length-1)个的数组元素的话,length的值也是随着数组变化而变化的。所以会出现第二个表单的内容会跟随我在第三个表单的输入框中的输入值进行动态变化。这里会有几个疑问:1.有人会认为,【反正提交给后台的数组是正确的不就好了吗】,那么要做到这样的前提就是【每一次的操作都是准确无误的操作】。因为现在这样,已经无法做到删除和修改。2.有人会认为,【只要每次给输入框绑定事先经过计算的(length-1)的结果不就好了吗】,那么为了这个要求,需要重新构造对象的属性。这个对象会在原来的“学校名称”和“学校网址”的基础上再多一个属性比如叫“currentLength”,专门用来记录创建对象那个时刻的(length-1)的结果,比如“集美大学”的兄弟属性“currentLength”就应该为1,“123”的兄弟属性“currentLength”就应该为2。但是我在传json给后台的时候,并不需要这个“currentLength”,那么又要重新创建一个对象。这样就失去双向绑定可以不用构造对象的意义了。3.有人会认为,【可能会需要一个提交当前表单的操作】,这个是没有必要的操作,因为双向绑定,本身就是动态写入的。只要你在绑定的输入框中输入相应的数据,原先的数组对象的元素都会改变的。我们来看下这个实现动态绑定组件的代码吧~
这是html的代码,父级#main中本身就有一个section存放表单,表单的输入框绑定的是目标对象companies的第0个元素。组件部分绑定的是目标对象的第(length-1)个对象。
这是js的代码,构建组件的data的时候,要先让companies从model实例中传过来,用一个新的对象com来存。在父级#main的button触发了点击事件之后,先push了一个空对象,然后用之前的$mount进行手动挂载,最后打印当前数组。思考这个问题,思考了好几个小时,连次晚饭的时候都在想啊!!!依稀记得那天吃的西北拉面。就连跟柯哲吃饭的时候,柯哲问我,”明天学校的考试是最后一科吗“,我都懒得回答,只是点了个头。我想,柯哲当时肯定心想(′???`) “这个傻×”--------------------!!!然而接下来的思路是正确的!!!--------------------发现不能利用动态组件来解决表单的问题,所以就换一个思路,固定一个表单,而不需要动态添加表单。另外设置一个表单显示目标数组,然后把需要进行操作的对象绑定到那个固定的表单中去。话不多说,举一个例子,&动态添加单项选择题的选项& ,先上效果图。
我在第一个红框中输入我要录入的信息,点击“添加一个选项”按钮,然后能够第二个红框中进行动态渲染我的目标对象中的每一个元素。在点击“修改”按钮后,能够将点击的这个元素动态渲染到第一个红框中的表单中,这样就能够通过输入框进行实时更新数据操作。在点击“删除”按钮后,能够删除当前元素。需要明确的一点就是,第二个红框中的列表显示的每一个框,就是我【当前目标数组中的实时元素】。
如图,我先添加了B和C两个选项。具体的操作就是在输入框中输入数据,然后点击“新增一个选项”,就能够在底下的显示区域动态渲染每个选项。
如果我点击了”编辑“按钮,当前元素就会被动态渲染到输入框中。如果我在输入框进行修改,底下的显示区域也是实时动态修改的。
如果我点击了”删除“按钮,当前元素就会从目标对象中移除。接下来看下代码:
这是html代码,父级中的两个输入框绑定的对象是newoption,这个对象就像是一个中介,如果需要push新对象到目标数组,就先把值写入newoption,然后把newoption的值push到目标数组中去。如果需要修改目标数组的元素,就把需要修改的元素的值传给newoption,然后通过和newoption绑定的输入框进行数据渲染和修改。其中#table的作用就是用一个v-for循环来动态输出目标对象的每个元素,目标对象就是list.options。并且每个元素都有”编辑“和”删除“操作。
这是js代码中的数据部分,其中options是我的目标数组对象。而newoption是我的中介对象。newoption对象会动态存储我在输入框中输入的数据。
这是在点击”增加一个选项“的时候触发的事件。把newoption中的值push进目标数组。此时的this的指向是model实例。注意push的写法。当push成功后,选项列表是能够马上动态渲染options的元素的(这个点我强调了好几次,Vue的双向绑定)。插入之后不需要对newoption进行初始化。
这是在点击”编辑“的时候触发的事件。把options对应下标的元素传给newoption,用于进行动态修改。$index.指的就是循环中的”op“的下标。此时的newoption和options[$index]都是指向同一个元素。
这是在点击”删除“的时候触发的事件。”op“指的是当前在循环中渲染的元素,把当前的元素对象$remove了,就完成了删除的操作。表单中的其他的数据渲染不存在数组的增删查改,所以就不详细说明了。点击网页上的”提交“按钮的操作只需要把data中的list对象通过ajax传给后台就好,并不需要自己构造数组对象。这样才能算是实现了一个表单最基本的动态绑定。嗯。这就是在动态组件上的思考过程。初次发文,谢谢大家。差不多了,我去吃个草莓。
一个想太多的女孩
过分细心 而又 过分粗枝大叶
过分认真 而又 总是...}

我要回帖

更多关于 vue2 ajax data 渲染 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信