Vue 基础 - 自定义指令和 render 函数

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue 基础 - 自定义指令和 render 函数相关的知识,希望对你有一定的参考价值。

参考技术A 类似组件可以全局注册和局部注册,使用 derective 注册。

指令定义函数提供了几个钩子函数(可选):

钩子函数有以下参数:

在 render 函数中使用 this.$slots 和 props 传递数据:

在render函数中使用 v-model :

在 render 函数中使用作用域插槽:

前端实操案例丨如何实现JS向Vue传值

摘要:项目开发过程中,组件通过render()函数渲染生成,并在组件内部定义了自定义拖拽指令。自定义拖拽指令规定了根据用户可以进行元素拖拽、缩放等一系列逻辑处理的动作。

本文分享自华为云社区《【Vue棘手问题解决】项目实现JS向Vue传值》,原文作者:SHQ5785 。

前言

项目开发过程中,组件通过render()函数渲染生成,并在组件内部定义了自定义拖拽指令。自定义拖拽指令规定了根据用户可以进行元素拖拽、缩放等一系列逻辑处理的动作。

另一个逻辑处理页面由Vue实现,该页面可以实时展示元素相关属性信息(包括size、width、height及left、top等属性)。

思路

  1. 监听器方式实现;
  2. Vuex state实现;

代码实现

.js

// 鼠标按下事件
el.onmousedown = function (e) {
	...
  document.onmouseup = function (e) {
	  document.body.style.cursor = 'pointer';
	  document.onmousemove = null;
	  document.onmouseup = null;
	  isMove = false;
	  document.body.removeChild(mask);
	  // 元素样式relative下方位属性
	  let domStyle = {
	    width: data.width,
	    height: data.height,
	    left: data.left,
	    top: data.top
	  }
	  el.style.cssText = setStyle(el, domStyle)
	  // Vuex state实现方式
	  store.commit('domAzimuth/SET_DOMAZIMUTION', el.style.cssText);
	  // 监听器实现方式
	  // window.postMessage({domStyle: domStyle}, '*')
}

}

.vue

    computed: {
      ...mapGetters('dragModule', ['editLayer']),
      ...mapGetters('domAzimuth', ['directProps']),
      domStyle () {
        return this.directProps
      }
    },
    // 监听器方式中,务必在页面销毁前释放掉监听器,否则会造成内存泄漏!
    beforeDestroy () {
//      window.removeEventListener('message', this.listenerMessage)
    },
    mounted () {
//      window.addEventListener('message', this.listenerMessage)
    },
    watch: {
      domStyle (n) {
        let configs = []
        let model = {}
        for (let name in this.editSoul.model) {
          let config = this.editSoul.model[name]
          model[name] = ''
          config.name = name
           if ('style' === name) {
              config.value = this.directProps
            }
          configs.push(config)
        }
        this.model = model
        this.configs = configs
      },
}

效果

拓展阅读-异步请求Promise导致页面数据渲染错误问题解决措施

场景描述

在Vue项目优化过程中,页面部分应用JS调用promise返回的异步数据,导致页面部分始终无法加载后台返回的数据值。通过触发其他DOM操作(例如折叠栏位的操作),后台数据可以正常渲染展示。处理逻辑大致如下:

<template>
	<div v-for="(items, index) in results" :key="items.itemsID">
		<span v-for="(item, index) in items.appendItems" :key="item.itemID">
			<el-button type="text" @click="handlerClick(item)">
				{{item.itemName}}
			</el-button>
		</span>
	</div>
</template>
<script>
	results.foreach((result, index, results) => {
		results[index].appendItems = []
		aysnMethods(inputParams).then(res => {
			results[index].appendItems = res.returnResults
		})
	})
</script>

问题分析

经过页面数据输出及debugger断点调试,发现在页面渲染结束前,异步数据并未处理完毕,导致页面数据渲染问题。

当vue实例生成后,再次给对象赋值时,并不会自动更新到视图上去; 当我们去看vue文档的时候,会发现有这么一句话:如果在实例创建之后添加新的属性到实例上,它不会触发视图更新。

受 ES5 限制,Vue.js 不能检测到对象属性的添加或删除,即Vue未做到脏数据检查。因为 Vue.js 在初始化实例时将属性转为 getter/setter,所以属性必须在 data 对象上才能让 Vue.js 转换它,才能让它是响应的。

解决措施

通过以上问题分析,可通过v-if控制页面渲染、销毁逻辑,在异步方法请求前销毁相应数据段,异步方法请求成功后新建相应数据段。
代码如下:

<template>
	<div v-if="showForm">
		<div v-for="(items, index) in results" :key="items.itemsID">
			<span v-for="(item, index) in items.appendItems" :key="item.itemID">
				<el-button type="text" @click="handlerClick(item)">
					{{item.itemName}}
				</el-button>
			</span>
		</div>
	</div>
</template>
<script>
	data(): {
		return {
			showForm: false
		}
	}
	results.foreach((result, index, results) => {
		results[index].appendItems = []
		vm.showForm = false
		aysnMethods(inputParams).then(res => {
			results[index].appendItems = res.returnResults
			vm.showForm = false
		})
	})
</script>

 

点击关注,第一时间了解华为云新鲜技术~

以上是关于Vue 基础 - 自定义指令和 render 函数的主要内容,如果未能解决你的问题,请参考以下文章

前端实操案例丨如何实现JS向Vue传值

前端Vue面试必过题 优选(钩子函数)

Vue.js学习 Item13 – 指令系统与自定义指令

vue自定义指令,包装函数节流。

vue自定义指令及应用场景

Render函数:使用原生js替代自定义指令修饰符slot