目录
复习-定义组件的方式(可跳过)
父组件向子组件传值
子组件向父组件传值
更详细的拓展资料:vue组件间通信
ref获取DOM元素和组件
复习-定义组件的方式(可跳过)
<!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="./lib/vue-2.4.0.js"></script>
</head>
<body>
<div id="app">
<!-- <mylogin></mylogin> -->
<login></login>
</div>
<script>
// 通过 对象 字面量的形式, 定义了一个 组件模板对象
var login = {
template: '<h1>1234555</h1>'
}
// 通过 Vue.component 把组件模板对象,注册为一个全局的Vue组件,同时为这个组件起了一个名称,可以让我们通过标签形式,在页面中直接引入这个组件
// Vue.component('mylogin', login)
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: '#app',
components: { // 定义的私有组件
// 'mylogin': login // '组件的名称': 组件的模板对象
login // 注意在 ES2015+ 中,在对象中放一个类似 login 的变量名其实是 login: login 的缩写
}
});
</script>
</body>
</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="./lib/vue-2.4.0.js"></script>
</head>
<body>
<div id="app">
<!-- 父组件可以在引用子组件的时候, 通过属性绑定(v-bind:) 的形式, 把需要传递给子组件的数据,以属性绑定的形式,传递到子组件内部,供子组件使用 -->
<com1 :parentmsg="msg"></com1>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
msg: '我是父组件中的数据'
},
components: {
// 子组件中,默认无法访问到 父组件中的 data 上的数据 和 methods 中的方法
com1: {
data() { // 子组件中的 data 数据是子组件自身私有的,比如子组件通过 Ajax 请求回来的数据
return {
title: '123',
content: 'qqq'
}
},
template: '<h1>这是子组件 --- {{ parentmsg }}</h1>',
// 注意: 组件中 props 的所有数据,都是通过父组件传递给子组件的,且数据都是只读的,无法重新赋值
props: ['parentmsg'], // 把父组件传递过来的 parentmsg 属性定义在 props 数组中才能使用这个数据
}
}
});
</script>
</body>
</html>
运行结果:
说明:
父组件可以在引用子组件的时候, 通过属性绑定(v-bind:) 的形式, 把需要传递给子组件的数据,以属性绑定的形式,传递到子组件内部,供子组件使用。
子组件中,默认无法访问到 父组件中的 data 上的数据 和 methods 中的方法,子组件中的 data 数据是子组件自身私有的,比如子组件通过 Ajax 请求回来的数据
注意: 组件中 props 的所有数据,都是通过父组件传递给子组件的,且数据都是只读的,无法重新赋值,把父组件传递过来的 parentmsg 属性定义在 props 数组中才能使用这个数据。那能不能修改props中的数据呢?可以但不建议直接修改的,虽然可以直接修改,但修改之后控制台会报警告,因为传递的可能是对象引用,其他组件也在引用这个父组件传递的值。
正确修改props数据的方法:在data中多一个属性最为props的副本,比如data(){return {mymsg : this.parentmsg }},这样去修改mymsg就可以达到同样的效果了。
这里没有讲组件分离出来
components: {
com1: {
data() {
return {
title: '123',
content: 'qqq'
}
},
template: '<h1>这是子组件 --- {{ parentmsg }}</h1>',
props: ['parentmsg'],
}
}
如果分离出来A.vue
则A.vue是
<template>
<h1>这是子组件 --- {{ parentmsg }}</h1>',
</template>
export default{
data() {
return {
title: '123',
content: 'qqq'
}
},
props: ['parentmsg'],
}
}
并且原来的页面的<script>标签中导入import A from '.\A.vue',并且在局部components声明就行了(既导入又声明,不过在webstorm中导入后没有声明直接使用,编译器会自动在components中声明的)
子组件向父组件传值
<!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="./lib/vue-2.4.0.js"></script>
</head>
<body>
<div id="app">
<!-- 子组件向父组件传递值,使用的是事件绑定机制:v-on, 当我们自定义了一个事件属性之后,那么父组件就能够通过某些方式来调用传递进来的值 -->
<com2 @func="show"></com2>
</div>
<template id="tmpl">
<div>
<h1>这是子组件</h1>
<input type="button" value="这是子组件中的按钮 - 点击它,触发父组件的 func 方法" @click="myclick">
</div>
</template>
<script>
// 定义了一个字面量类型的组件对象
var com2 = {
template: '#tmpl', // 通过指定的Id加载指定的 template 元素中的内容当作组件的HTML结构
data() {
return {
sonmsg: { name: '小头儿子', age: 6 }
}
},
methods: {
myclick() {
// 当点击子组件的按钮的时候,触发父组件方法,并传递值
// emit 英文原意: 是触发,调用、发射的意思
this.$emit('func', this.sonmsg)
}
}
}
var vm = new Vue({
el: '#app',
data: {
datamsgFormSon: null
},
methods: {
show(data) {
// 获取子组件方法传入参数的值
console.log('调用了父组件身上的 show 方法')
console.log(data)
this.datamsgFormSon = data
}
},
components: {
com2 // com2: com2
}
});
</script>
</body>
</html>
运行结果:
点击按钮之后
注意:
子组件向父组件传递值,使用的是事件绑定机制:v-on, 当我们自定义了一个事件属性之后,那么父组件就能够通过某些方式来调用传递进来的值
更详细的拓展资料:vue组件间通信
写的很好,都不用多说,点击下面链接
vue -- 非父子组件传值,事件总线(eventbus)的使用方式
ref获取DOM元素和组件
<!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="./lib/vue-2.4.0.js"></script>
</head>
<body>
<div id="app">
<input type="button" value="获取元素" @click="getElement">
<h3 id="myh3" ref="myh3">哈哈哈, 今天天气太好了!!!</h3>
<hr>
<login ref="mylogin"></login>
</div>
<script>
var login = {
template: '<h1>登录组件</h1>',
data() {
return {
msg: 'son msg'
}
},
methods: {
show() {
console.log('调用了子组件的方法')
}
}
}
var vm = new Vue({
el: '#app',
methods: {
getElement() {
// console.log(document.getElementById('myh3').innerText)
// ref 是 英文单词 【reference】 值类型 和 引用类型 referenceError
console.log(this.$refs.myh3.innerText) // 用在普通DOM元素上
console.log(this.$refs.mylogin.msg) // 用在子组件上
this.$refs.mylogin.show()
}
},
components: {
login // login:login
}
});
</script>
</body>
</html>
运行结果
点击按钮后如下
注意:
vm.$refs是一个对象,持有注册过 ref 的所有 DOM 元素和组件实例。
它可以访问子组件实例或子元素
如果ref用在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例。
例子:可以利用ref获取到DOM元素,然后改变其属性,比如改变背景色
===============Talk is cheap, show me the code================