13-Vue特殊属性-ref

13-Vue特殊属性-ref,第1张

ref :被用来给元素或子组件注册引用信息,引用信息将会注册在父组件的 $refs 对象上。如果在普通的DOM元素上使用,那么指向的就是普通的DOM元素。

Vue特点: 数据驱动界面更新, 无需 *** 作DOM来更新界面

也就是说Vue不推荐我们直接 *** 作DOM, 但是在开发中有时候我们确实需要拿到DOM *** 作DOM

那么如果不推荐使用原生的语法获取DOM, 我们应该如何获取DOM

在Vue中如果想要拿到DOM元素我们可以通过ref来获取

例如: <p ref="myP">我是段落</p>

例如 this$refmyP

refs : 一个对象,持有注册过 ref 特性 的所有 DOM 元素和组件实例

注意: refs 只会在组件渲染完成之后生效,并且它们不是响应式的。这只意味着一个直接的子组件封装的“逃生舱”——你应该避免在模板或计算属性中访问 $refs 结语

在讲ref特点之前我们先来回顾, 原生语法获取元素的特点

例如: 通过原生的语法 documentquerySelector 获取到的都是被渲染之后DOM元素, 也就是原生的元素

在Vue中如果想获取原生的元素或者获取自定义的组件, 可以通过ref来获取

拿到了组件后, 还可以访问组件中的数据

vue生命周期的栗子

注意触发vue的created事件以后,this便指向vue实例,这点很重要

<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

<title>vue生命周期</title>

<script src="/js/vuejs"></script>

<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />

</head>

<body>

<div class="test" style="border: 1px black dashed;padding: 8px;">

{{a}}

</div>

<div class="test2" style="border: 1px red solid;margin-top: 10px;padding: 8px;">

我是内容二

</div>

<script type="text/javascript">

var myVue = new Vue({

el: "test",

data: {

a: "我是内容,在控制台输入myVuea=123456,可以改变我的值"

},

created: function () {

//在实例创建之后同步调用。此时实例已经结束解析选项,这意味着已建立:数据绑定,计算属性,方法,watcher/事件回调。

//但是还没有开始 DOM 编译,$el 还不存在,但是实例存在,即thisa存在,可打印出来 。

consolelog("建立");

},

beforeCompile: function () {

consolelog("未开始编译");

},

compiled: function () {

//在编译结束后调用。此时所有的指令已生效,因而数据的变化将触发 DOM 更新。但是不担保 $el 已插入文档。

consolelog("编译完成");

},

ready: function () {

//在编译结束和 $el 第一次插入文档之后调用,如在第一次 attached 钩子之后调用。注意必须是由 Vue 插入(如 vm$appendTo() 等方法或指令更新)才触发 ready 钩子。

consolelog("一切准备好了");

},

attached :function () { //myVue$appendTo("test2")暂时触发不了,不知道怎么解决

//在 vm$el 插入 DOM 时调用。必须是由指令或实例方法(如 $appendTo())插入,直接 *** 作 vm$el 不会 触发这个钩子。

consolelog("插入DOM成功");

},

detached :function () { //触发事件 myVue$destroy(true),其中参数true控制是否删除DOM节点或者myVue$remove()

//在 vm$el 从 DOM 中删除时调用。必须是由指令或实例方法删除,直接 *** 作 vm$el 不会 触发这个钩子。

consolelog("删除DOM成功");

},

beforeDestroy: function () { //触发方式,在console里面打myVue$destroy();

//在开始销毁实例时调用。此时实例仍然有功能。

consolelog("销毁前");

},

destroyed: function () { //触发方式,在console里面打myVue$destroy();其中myVue$destroy(true)是删除DOM节点,会触发detached函数,但是实例仍然存在

//在实例被销毁之后调用。此时所有的绑定和实例的指令已经解绑,注意是解绑不是销毁,所有的子实例也已经被销毁。

consolelog("已销毁");

}

});

</script>

</body>

</html>

直接在标签中添加click事件(@click=fn),然后在vue实例中的(methods)配置项里添加方法fn,实现你的功能。这样不行吗?vue框架不是不能用原生js获取dom元素,只是用框架就是为了避免 *** 作dom元素

在组件上定义ref="名字",可以通过this$refs名字,,,获取dom元素。。例如下面:

<div id="out">

    <h2>组件 *** 作</h2>

    <hr/>

    <p ref="tit">组件 *** 作组件 *** 作v组件 *** 作组件 *** 作组件 *** 作</p>

    <button @click="tap">点击</button>

</div>

</body>

<script type="text/javascript">

var vm = new Vue({

        el:'#out',

        data:{

        },

methods:{

        tap(){

             consolelog(this$refstitinnerHTML)//获取dom元素把dom元素的内容拿了出来

        }

    }

})

v-model,,,在输入框,单选框,多选框等等,添加v-model=“tit”的时候v-model的值必须在data里面声明;

v-model的值是他们的value值

再有一棵树形结构的 JavaScript 对象后,我们现在需要做的就是将这棵树跟真实的 Dom 树形成映射关系,首先简单回顾之前遇到的 mountComponent 方法:

我们已经执行完了 vm_render 方法拿到了 VNode ,现在将它作为参数传给 vm_update 方法并执行。 vm_update 这个方法的作用就是就是将 VNode 转为真实的 Dom ,不过它有两个执行的时机:

我们现在先来看下 vm_update 方法的定义:

这里的 vm$el 是之前在 mountComponent 方法内就挂载的,一个真实 Dom 元素。首次渲染会传入 vm$el 以及得到的 VNode ,所以看下 vm__patch__ 定义:

__patch__ 是 createPatchFunction 方法内部返回的一个方法,它接受一个对象:

nodeOps 属性:封装了 *** 作原生 Dom 的一些方法的集合,如创建、插入、移除这些,再使用到的地方再详解。

modules 属性:创建真实 Dom 也需要生成它的如 class / attrs / style 等属性。 modules 是一个数组集合,数组的每一项都是这些属性对应的钩子方法,这些属性的创建、更新、销毁等都有对应钩子方法,当某一时刻需要做某件事,执行对应的钩子即可。比如它们都有 create 这个钩子方法,如将这些 create 钩子收集到一个数组内,需要在真实 Dom 上创建这些属性时,依次执行数组的每一项,也就是依次创建了它们。

这里大家记住一句话即可,无论 VNode 是什么类型的节点,只有三种类型的节点会被创建并插入到的 Dom 中:元素节点、注释节点、和文本节点。

我们接着来看下 createPatchFunction 它究竟返回一个什么样的方法:

首次渲染时没有 oldVnode , oldVnode 就是 $el ,一个真实的 dom ,经过 emptyNodeAt(oldVnode) 方法包装:

再将传入的 $el 属性转为了 VNode 格式之后,我们继续:

createElm 方法开始生成真实的 Dom , VNode 生成真实的 Dom 的方式还是分为元素节点和组件两种方式,所以我们使用上一章生成的 VNode 分别说明。

大家可以先看下这个流程图有一个印象即可,接下来再看具体实现时相信思路会清晰很多:

开始创建 Dom ,我们来看下它的定义:

依次判断是否是元素节点、注释节点、文本节点,分别创建它们然后插入到父节点里面,这里主要介绍创建元素节点,另外两个并没有复杂的逻辑。我们来看下 createChild 方法定义:

开始创建子节点,遍历 VNode 的每一项,每一项还是使用之前的 createElm 方法创建 Dom 。如果某一项又是数组,继续调用 createChild 创建某一项的子节点;如果某一项不是数组,创建文本节点并将它添加到父节点内。像这样使用递归的形式将嵌套的 VNode 全部创建为真实的 Dom 。

再看一遍流程图,相信大家疑惑已经减少很多:

首先还是看张简易流程图,留个印象即可,方便理清之后的逻辑顺序:

执行 createComponent 方法,如果是元素节点不会返回任何东西,所以是 undefined ,会继续走接下来的创建元素节点的逻辑。现在是组件,我们看下 createComponent 的实现:

首先会将组件的 vnodedata 赋值给 i ,是否有这个属性就能判断是否是组件 vnode 。之后的 if(isDef(i = ihook) && isDef(i = iinit)) 集判断和赋值为一体, if 内的 i(vnode) 就是执行的组件 init(vnode) 方法。这个时候我们来看下组件的 init 钩子方法做了什么:

activeInstance 是一个全局的变量,再 update 方法内赋值为当前实例,再当前实例做 __patch__ 的过程中作为子组件的父实例传入,在子组件的 initLifecycle 时构建组件关系。将 createComponentInstanceForVnode 执行的结果赋值给了 vnodecomponentInstance ,所以看下它的返回的结果是什么:

再组件的 init 方法内首先执行 createComponentInstanceForVnode 方法,这个方法的内部就会将子组件的构造函数实例化,因为子组件的构造函数继承了基类 Vue 的所有能力,这个时候相当于执行 new Vue({}) ,接下来又会执行 _init 方法进行一系列的子组件的初始化逻辑,我们回到 _init 方法内,因为它们之间还是有些不同的地方:

前面都还执行的好好的,最后却因为没有 el 属性,所以没有挂载, createComponentInstanceForVnode 方法执行完毕。这个时候我们回到组件的 init 方法,补全剩下的逻辑:

我们在 init 方法内手动挂载这个组件,接着又会执行组件的 _render() 方法得到组件内元素节点 VNode ,然后执行 vm_update() ,执行组件的 __patch__ 方法,因为 $mount 方法传入的是 undefined , oldVnode 也是 undefined ,会执行 __patch__ 内的这段逻辑:

这次执行 createElm 时没有传入第三个参数父节点的,那组件创建好的 Dom 放哪生效了?没有父节点也要生成 Dom 不是,这个时候执行的是组件的 __patch__ ,所以参数 vnode 就是组件内元素节点的 vnode 了:

很明显这个时候不是组件了,即使是组件也没关系,大不了还是执行一遍 createComponent 创建组件的逻辑,因为总会有组件是由元素节点组成的。这个时候我们执行一遍创建元素节点的逻辑,因为没有第三个参数父节点,所以组件的 Dom 虽然创建好了,并不会在这里插入。请注意这个时候组件的 init 已经完成,但是组件的 createComponent 方法并没有完成,我们补全它的逻辑:

无论是嵌套多么深的组件,遇到组件的后就执行 init ,在 init 的 __patch__ 过程中又遇到嵌套组件,那就再执行嵌套组件的 init ,嵌套组件完成 __patch__ 后将真实的 Dom 插入到它的父节点内,接着执行完外层组件的 __patch__ 又插入到它的父节点内,最后插入到 body 内,完成嵌套组件的创建过程,总之还是一个由里及外的过程。

再回过头来看这张图,相信会好理解很多~

接下来会将 updateComponent 传入到一个 Watcher 的类中,这个类是干嘛的,我们下一章再说明,接下来执行 mounted 钩子方法。至此 new Vue 的整个流程就全部走完了。我们回顾下从 new Vue 开始它的执行顺序:

最后我们还是以一道 vue 可能会被问到的面试题作为本章的结束吧~

顺手点个赞或关注呗,找起来也方便~

你可能会用的上的一个vue功能组件库,持续完善中

首先

vue的点击事件

是用

@click

=

“clickfun()”

属性

在html中绑定的,

在点击的函数中

添加$event

参数就可以

比如

<button

@click

=

“clickfun($event)”>点击</button>

methods:

{

clickfun(e)

{

//

etarget

是你当前点击的元素

//

ecurrentTarget

是你绑定事件的元素

}

},

以上这篇vue

的点击事件获取当前点击的元素方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:vue如何获取点击事件源的方法VUE中v-on:click事件中获取当前dom元素的代码vue获取当前点击的元素并传值的实例vue获取dom元素注意事项在Vue组件中获取全局的点击事件方法

获取DOM或者组件实例可以使用ref属性,写法和vue20需要区分开 。

总结:

1Vue2中可以通过ref直接 *** 作单个DOM和组件 this$refsinfoinnerHTML

2Vue2中可以批量通过ref *** 作DOM和组件 this$refsfruit[0]innerHTML

vue30里面模板的ref是跟着定义走的(先定义再使用, 模板中的名字和定义的名字要一致 )先返回再使用

vue20里面的使用是跟着模板走(先模板中用,然后根据模板使用ref, 获取DOM的ref要和模板的一样 )

总结: *** 作单个DOM或者组件的流程

1定义一个响应式变量

2把变量返回给模板使用

3模板中绑定上述返回的数据

4可以通过info变量 *** 作DOM或者组件实例

1定义 *** 作DOM的函数----通过形参获取单个DOM元素

总结: ref批量 *** 作元素的流程

1定义一个 *** 作DOM的函数

2把该函数绑定到模板上( 必须动态绑定 )

3在函数中可以通过参数得到单个元素,这个元素一般可以放到数组中

4通过上述数组即可 *** 作批量的元素

以上就是关于13-Vue特殊属性-ref全部的内容,包括:13-Vue特殊属性-ref、vue 怎么获取到dom渲染vm数据完毕之后的生命周期钩子、Vue+element ui页面,怎么 *** 作dom元素等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/9852983.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-02
下一篇2023-05-02

发表评论

登录后才能评论

评论列表(0条)

    保存