add Vue.js 2.x:通过ref属性获取DOM元素
This commit is contained in:
parent
d41890c8d0
commit
a34ce883f7
@ -271,7 +271,7 @@ Vue.component('myComponent', myAccount); //第一个参数是组件的名称(
|
|||||||
|
|
||||||
![](http://img.smyhvae.com/20180617_1809.png)
|
![](http://img.smyhvae.com/20180617_1809.png)
|
||||||
|
|
||||||
当然,我们还可以把**模板的定义**存放在`<template>`标签中,这样的话,模板里的html标签就可以出现智能提示和高亮,避免出错。如下:
|
【荐】当然,我们还可以把**模板的定义**存放在`<template>`标签中,这样的话,模板里的html标签就可以出现智能提示和高亮,避免出错。如下:
|
||||||
|
|
||||||
|
|
||||||
```html
|
```html
|
||||||
@ -316,6 +316,34 @@ Vue.component('myComponent', myAccount); //第一个参数是组件的名称(
|
|||||||
|
|
||||||
运行效果不变。
|
运行效果不变。
|
||||||
|
|
||||||
|
上方代码中,如果在注册私有组件时,组件的名称是**驼峰命名**,比如:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
components: { // 定义、注册Vue实例内部的私有组件
|
||||||
|
myLogin: {
|
||||||
|
template: '#loginTmp'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
那么,在标签中使用组件时,需要把大写的驼峰改为小写的字母,同时两个单词之间使用`-`进行连接:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<my-login></my-login>
|
||||||
|
```
|
||||||
|
|
||||||
|
所以,为了避免名字不一致的问题,我们注册组件时,组件的名称可以直接写成`my-login`。比如:(避免驼峰不一致的建议写法)
|
||||||
|
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
components: { // 定义、注册Vue实例内部的私有组件
|
||||||
|
`my-login`: {
|
||||||
|
template: '#loginTmp'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## 为组件添加 data 和 methods
|
## 为组件添加 data 和 methods
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
我们可以这样理解:Vue实例就是一个**父组件**,而我们自定义的组件(包括全局组件、私有组件)就是**子组件**。
|
我们可以这样理解:Vue实例就是一个**父组件**,而我们自定义的组件(包括全局组件、私有组件)就是**子组件**。
|
||||||
|
|
||||||
需要注意的是,子组件不能直接使用父组件中的数据。**父组件可以通过`props`属性向子组件传值**。
|
【重点】需要注意的是,子组件不能直接使用父组件中的数据。**父组件可以通过`props`属性向子组件传值**。
|
||||||
|
|
||||||
### 父组件向子组件传值的代码举例
|
### 父组件向子组件传值的代码举例
|
||||||
|
|
||||||
@ -23,7 +23,8 @@
|
|||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div id="app">
|
<div id="app">
|
||||||
<!--第三步:父组件在引用子组件的时候, 通过 属性绑定(v-bind:)的形式, 把 需要传递给 子组件的数据,以属性绑定的形式,传递到子组件内部,供子组件使用 -->
|
<!-- 第三步:父组件在引用子组件的时候, 通过 属性绑定(v-bind:)的形式, -->
|
||||||
|
<!-- 把 需要传递给 子组件的数据,以属性绑定的形式,传递到子组件内部,供子组件使用 -->
|
||||||
<component1 v-bind:parent-msg="msg"></component1>
|
<component1 v-bind:parent-msg="msg"></component1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -53,15 +54,15 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 注意: 组件中的 所有 props 中的数据,都是通过 父组件 传递给子组件的
|
// 注意: 组件中的 所有 props 中的数据,都是通过 父组件 传递给子组件的
|
||||||
// props 中的数据,都是只读的,无法重新赋值(也就是说,)
|
// props 中的数据,都是只读的,无法重新赋值
|
||||||
props: ['parentMsg'], // 第一步:把父组件传递过来的 parentmsg 属性,先在 props 数组中,定义一下,这样,才能使用这个数据
|
props: ['parentMsg'], // 第一步:把父组件传递过来的 parentMsg 属性,先在 props 数组中,定义一下,这样,才能使用这个数据
|
||||||
directives: {},
|
directives: {},
|
||||||
filters: {},
|
filters: {},
|
||||||
components: {},
|
components: {},
|
||||||
methods: {
|
methods: {
|
||||||
change() {
|
change() {
|
||||||
// 下面这行会报错,因为子组件不要直接修改父组件中的data数据
|
// 下面这行会报错,因为子组件不要直接修改父组件中的data数据
|
||||||
// this.parentmsg = '被修改了'
|
// this.parentMsg = '被修改了'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -76,11 +77,11 @@
|
|||||||
|
|
||||||
效果如下:
|
效果如下:
|
||||||
|
|
||||||
20180618_2350.png
|
![](http://img.smyhvae.com/20180618_2350.png)
|
||||||
|
|
||||||
代码截图如下:
|
代码截图如下:
|
||||||
|
|
||||||
20180618_2355.png
|
![](http://img.smyhvae.com/20180618_2355.png)
|
||||||
|
|
||||||
|
|
||||||
**父组件给子组件传值的步骤**:
|
**父组件给子组件传值的步骤**:
|
||||||
@ -123,7 +124,8 @@
|
|||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div id="app">
|
<div id="app">
|
||||||
<!-- 父组件向子组件 传递 方法,是通过 事件绑定机制; v-on。当我们自定义了 一个 事件属性 parent-show(这个地方不能用驼峰命名)之后,那么,子组件就能够,通过 emit 来调用 传递进去的 这个 方法了 -->
|
<!-- 父组件向子组件 传递 方法,是通过 事件绑定机制; v-on。当我们自定义了 一个 事件属性 parent-show(这个地方不能用驼峰命名)之后,-->
|
||||||
|
<!-- 那么,子组件就能够,通过 emit 来调用 传递进去的 这个 方法了 -->
|
||||||
<!-- 【第一步】。意思是说,`show`是父组件的方法名,`parent-show`是自定义的时间属性,稍后要在子组件中用到 -->
|
<!-- 【第一步】。意思是说,`show`是父组件的方法名,`parent-show`是自定义的时间属性,稍后要在子组件中用到 -->
|
||||||
<component1 @parent-show='show'></component1>
|
<component1 @parent-show='show'></component1>
|
||||||
</div>
|
</div>
|
||||||
@ -131,7 +133,7 @@
|
|||||||
<!-- 定义子组件的模板 -->
|
<!-- 定义子组件的模板 -->
|
||||||
<template id="myTemplate">
|
<template id="myTemplate">
|
||||||
<!-- 【第二步】按照正常的写法来:点击按钮,调用子组件的方法 -->
|
<!-- 【第二步】按照正常的写法来:点击按钮,调用子组件的方法 -->
|
||||||
<h2 @click="childClick">我是子组件,点击调用父组件的方法</h2>
|
<div @click="childClick">我是子组件,点击调用父组件的方法</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@ -177,12 +179,11 @@
|
|||||||
|
|
||||||
效果如下:(点击子组件,触发了父组件的方法)
|
效果如下:(点击子组件,触发了父组件的方法)
|
||||||
|
|
||||||
|
![](http://img.smyhvae.com/20180701_1800.png)
|
||||||
|
|
||||||
根据上面的代码,我们可以总结出,父组件将方法传递给子组件,分为三步,具体可以看上方代码的注释。
|
根据上面的代码,我们可以总结出,父组件将方法传递给子组件,分为三步,具体可以看上方代码的注释。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## 子组件向父组件传值
|
## 子组件向父组件传值
|
||||||
|
|
||||||
上面的一段中,我们再看一遍**父组件将方法传递给子组件**的这段代码(一定要再看一遍,因为我们是要在此基础之上做修改)。
|
上面的一段中,我们再看一遍**父组件将方法传递给子组件**的这段代码(一定要再看一遍,因为我们是要在此基础之上做修改)。
|
||||||
@ -257,7 +258,7 @@
|
|||||||
|
|
||||||
运行结果:(点击`<h2>`之后)
|
运行结果:(点击`<h2>`之后)
|
||||||
|
|
||||||
20180623_1640.png
|
![](http://img.smyhvae.com/20180623_1640.png)
|
||||||
|
|
||||||
**代码举例2**:(将子组件中的data数据传递给父组件,存放到父组件的data中)
|
**代码举例2**:(将子组件中的data数据传递给父组件,存放到父组件的data中)
|
||||||
|
|
||||||
@ -336,7 +337,7 @@
|
|||||||
运行结果:(点击`<h2>`之后)
|
运行结果:(点击`<h2>`之后)
|
||||||
|
|
||||||
|
|
||||||
20180623_1655.png
|
![](http://img.smyhvae.com/20180623_1655.png)
|
||||||
|
|
||||||
|
|
||||||
## 案例:发表评论功能的实现
|
## 案例:发表评论功能的实现
|
||||||
@ -479,7 +480,94 @@
|
|||||||
|
|
||||||
我们当然可以使用JS原生的做法(document.getElementById)或者 jQuery 来获取DOM,但是这种做法却在无形中操作了DOM,在Vue框架中并不推荐这种做法。
|
我们当然可以使用JS原生的做法(document.getElementById)或者 jQuery 来获取DOM,但是这种做法却在无形中操作了DOM,在Vue框架中并不推荐这种做法。
|
||||||
|
|
||||||
|
我们可以通过`ref`属性获取DOM元素。
|
||||||
|
|
||||||
|
`ref`的英文单词是**reference**,表示**引用**。我们平时可以经常看到控制台会报错**referenceError**的错误,就和引用类型的数据有关。
|
||||||
|
|
||||||
|
|
||||||
|
**在Vue中,通过 ref 属性获取DOM元素**的步骤:
|
||||||
|
|
||||||
|
(1)第一步:在标签中给 DOM 元素设置 ref 属性。
|
||||||
|
|
||||||
|
```html
|
||||||
|
<h3 id="myH3" ref="myTitle"> 今天天气太好了</h3>
|
||||||
|
```
|
||||||
|
|
||||||
|
(2)第二步:通过 this.this.$refs.xxx 获取 DOM 元素
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
console.log(this.$refs.myTitle.innerText)
|
||||||
|
```
|
||||||
|
|
||||||
|
**举例如下**:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||||
|
<title>Document</title>
|
||||||
|
<script src="vue2.5.16.js"></script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="app">
|
||||||
|
|
||||||
|
<!-- 第一步:在标签中给 DOM 元素设置 ref 属性 -->
|
||||||
|
<h3 id="myH3" ref="myTitle"> 今天天气太好了</h3>
|
||||||
|
|
||||||
|
<input type="button" value="按钮元素" @click="getElement" ref="myBtn">
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
var login = {
|
||||||
|
template: '<h1>登录组件</h1>',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
msg: 'son msg'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
show() {
|
||||||
|
console.log('调用了子组件的方法')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建 Vue 实例,得到 ViewModel
|
||||||
|
var vm = new Vue({
|
||||||
|
el: '#app',
|
||||||
|
data: {},
|
||||||
|
methods: {
|
||||||
|
getElement() {
|
||||||
|
// 原生js获取DOM元素
|
||||||
|
// console.log(document.getElementById('myTitle').innerText)
|
||||||
|
|
||||||
|
// 第二步:通过 this.this.$refs.xxx 获取 DOM 元素
|
||||||
|
console.log(this.$refs.myTitle.innerText)
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
login
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
|
```
|
||||||
|
|
||||||
|
运行上方代码,然后我们在控制台输入`vm`,就可以看到:
|
||||||
|
|
||||||
|
![](http://img.smyhvae.com/20180701_1640.png)
|
||||||
|
|
||||||
|
|
||||||
### 使用 ref 属性获取整个子组件
|
### 使用 ref 属性获取整个子组件
|
||||||
@ -487,25 +575,76 @@
|
|||||||
根据上面的例子,我们可以得出**规律**:只要`ref`属性加在了DOM元素身上,我们就可以获取这个DOM元素。
|
根据上面的例子,我们可以得出**规律**:只要`ref`属性加在了DOM元素身上,我们就可以获取这个DOM元素。
|
||||||
|
|
||||||
|
|
||||||
|
那我们可以通过ref属性获取整个**Vue子组件**吗?当然可以。这样做的意义是:**在父组件中通过`ref`属性拿到了子组件之后,就可以进一步拿到子组件中的data和method。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
举例:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||||
|
<title>Document</title>
|
||||||
|
<script src="vue2.5.16.js"></script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="app">
|
||||||
|
|
||||||
|
<input type="button" value="点击按钮" @click="getElement">
|
||||||
|
|
||||||
|
<login-component ref="loginTemplate"></login-component>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
// 创建 Vue 实例,得到 ViewModel
|
||||||
|
var vm = new Vue({
|
||||||
|
el: '#app',
|
||||||
|
data: {},
|
||||||
|
methods: {
|
||||||
|
getElement() {
|
||||||
|
|
||||||
|
//在父组件中,通过ref获取整个子组件,进而获取子组件的data
|
||||||
|
console.log(this.$refs.loginTemplate.myData)
|
||||||
|
|
||||||
|
//在父组件中,通过ref获取整个子组件,进而获取子组件的method
|
||||||
|
this.$refs.loginTemplate.showMethod()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
'login-component': {
|
||||||
|
template: '<h1>登录组件</h1>',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
myData: '子组件的data'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
showMethod() {
|
||||||
|
console.log('调用子组件的method')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
|
```
|
||||||
|
|
||||||
|
运行代码,点击按钮后,效果如下:
|
||||||
|
|
||||||
|
![](http://img.smyhvae.com/20180701_1735.png)
|
||||||
|
|
||||||
|
我们直接在控制台输入`vm`,可以看到:
|
||||||
|
|
||||||
|
![](http://img.smyhvae.com/20180701_1740.png)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user