Vue父子組件數(shù)據(jù)雙向綁定(父傳子、子傳父)及ref、$refs、is、:is的使用與區(qū)別
既然有父傳子那么肯定有子傳父,有子傳父肯定也有兩者之間相互綁定
這里我們先看一下子傳父的寫法:
一、子傳父:$emit()
看代碼:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>子傳父</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<style type="text/css">
button {
margin-left: 5px;
}
</style>
<body>
<div id="app">
<cpn1 @itemclick="cpnclick"></cpn1>
</div>
<template id="cpn1">
<div>
<button type="button" v-for="item in menu" :key="item.id"
@click="btnclick(item)">{{item.name}}</button>
</div>
</template>
<script type="text/javascript">
const cpn = {
template: "#cpn1",
data() {
return {
menu: [{
id: 'one',
name: '首頁'
},
{
id: 'two',
name: '分類'
},
{
id: 'three',
name: '購物'
},
{
id: 'four',
name: '我的'
},
],
}
},
methods: {
btnclick(item) {
this.$emit('itemclick', item)
// 子傳父 在子組件中做一個點擊事件通過$emit派發(fā)出 給父組件 同時可以攜帶參數(shù)
}
}
};
const vm = new Vue({
el: '#app',
methods: {
cpnclick(item) {
console.log('cpnclick' + item.name);
}
},
components: {
"cpn1": cpn
}
})
</script>
</body>
</html>打印效果:

兩者之間的關(guān)系:
1、父組件可以使用 props 把數(shù)據(jù)傳給子組件。
2、子組件可以使用 $emit 觸發(fā)父組件的自定義事件。
二、監(jiān)聽原生點擊事件:.native
不加.native時,不會觸發(fā)原生的點擊事件
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>不加native修飾符</title>
</head>
<style>
div{
cursor: pointer;
}
</style>
<body>
<div id="app">
<cpn @click="handelClick"></cpn> // 這里沒有加native修飾符
</div>
<!-- 子組件 -->
<template id="cpn">
<div>
我是子組件
</div>
</template>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
<script>
const cpn = {
template:'#cpn',
}
const app = new Vue({
el: "#app",
methods: {
handelClick(){
console.log('click');
}
},
components:{
cpn
}
})
</script>
</body>
</html>效果如下:

不加修飾符是不會監(jiān)聽到原生點擊事件的。
如果是加了.native修飾符時:
添加方法:
<cpn @click.native="handelClick"></cpn>
效果如下圖所示:

三、組件通信的案例:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="app">
<cpn :number1="num1" :number2="num2"></cpn>
</div>
<template id="cpn">
<div>
<h2>{{datanum1}}</h2>
<input type="text" v-model="datanum1"/>
<h2>{{datanum2}}</h2>
<input type="text" v-model="datanum2"/>
</div>
</template>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
<script>
const cpn = {
template:'#cpn',
data(){
return {
datanum1:this.number1,
datanum2:this.number2,
}
},
props:{
number1:{
type:[String,Number]
},
number2:{
type:[String,Number]
},
}
}
const app = new Vue({
el: "#app",
data() {
return {
num1:1,
num2:2
}
},
components:{
cpn
}
})
</script>
</body>
</html>效果如下:

四、實現(xiàn)父子之間的值的雙向綁定
在子組件中添加監(jiān)聽器,利用props和$emit來進(jìn)行父子之間的雙向綁定
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="app">
<cpn :number1="num1" :number2="num2" @dataclick1="changeClick1" @dataclick2="changeClick2"></cpn>
</div>
<template id="cpn">
<div>
<h2>{{datanum1}}</h2>
<h3>number1:{{number1}}</h3>
<input type="text" v-model="datanum1" />
<h2>{{datanum2}}</h2>
<h3>number2:{{number2}}</h3>
<input type="text" v-model="datanum2" />
</div>
</template>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
<script>
const cpn = {
template: '#cpn',
data() {
return {
datanum1: this.number1,
datanum2: this.number2
}
},
props: {
number1: {
type: [String, Number]
},
number2: {
type: [String, Number]
}
},
watch: {
datanum1(n) {
console.log('datanum1被監(jiān)聽了');
this.$emit('dataclick1', n / 100)
},
datanum2(n) {
console.log('datanum2被監(jiān)聽了');
this.$emit('dataclick2', n * 100)
}
}
}
const app = new Vue({
el: "#app",
data() {
return {
num1: 1,
num2: 2
}
},
methods: {
changeClick1(value) {
this.num1 = value
},
changeClick2(value) {
this.num2 = value
}
},
computed: {
},
components:{
cpn
}
})
</script>
</body>
</html>效果

一個是除10一個是
五、父訪問子 $refs
JavaScript中獲取元素可以使用document.querySelector,那可以在Vue中使用嗎?
我們可以測試一下
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="app">
<p id="bb" @click="handelClick" ref="aa">Nanchen</p>
</div>
<script type="text/javascript">
const vm = new Vue({
el: '#app',
data() {
return {
}
},
methods: {
handelClick(){
var bb = document.querySelector('bb');
console.log(bb);
}
}
})
</script>
</body>
</html>打印結(jié)果:

答案是可以的,但是如果使用原生JS獲取元素的話,那么用Vue就沒有意義了,Vue中有特定的語法
官網(wǎng)解釋:
$refs方式:ref 被用來給元素或子組件注冊引用信息。引用信息將會注冊在父組件的 $refs 對象上。如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子組件上,引用就指向組件實例
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="app">
<p id="bb" @click="handelClick" ref="aa">Nanchen</p>
</div>
<script type="text/javascript">
const vm = new Vue({
el: '#app',
data() {
return {
}
},
methods: {
/* handelClick(){
var bb = document.querySelector('bb');
console.log(bb);
} */
handelClick() {
console.log(this.$refs.aa);
}
}
})
</script>
</body>
</html>效果與上圖一致:

六、使用$refs獲取組件中的值
既然可以獲取普通元素那么也可以獲得組件中的元素或者值
看這個例子:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="app">
<cpn ref="aaa"></cpn>
<button @click="handelClick">點擊</button>
</div>
<!-- 子組件 -->
<template id="cpn">
<div>
我是子組件
</div>
</template>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
<script>
const cpn = {
template:'#cpn',
data(){
return {
name:'我是子組件的name' //獲取子組件的屬性
}
},
}
const app = new Vue({
el: "#app",
methods: {
handelClick(){
console.log(this.$refs.aaa.name);
}
},
components:{
cpn
}
})
</script>
</body>
</html>效果如下:

下面看一個擴展:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="app">
<count ref="one" @change="handclick"></count>
<count ref="two" @change="handclick"></count>
<h2>{{total}}</h2>
</div>
<script type="text/javascript">
Vue.component('count',{
template:
`<div @click="handclick">
{{number}}
</div>`,
data(){
return{
number:0
}
},
methods:{
handclick(){
this.number++;
this.$emit('change')
}
}
})
const vm = new Vue({
el:'#app',
data(){
return{
total:0
}
},
methods:{
handclick(){
this.total= this.$refs.one.number + this.$refs.two.number
}
}
})
</script>
</body>
</html>效果如下:


不僅如此,ref還可以調(diào)用組件中的方法:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="app">
<hello-world ref="hello"></hello-world>
<button @click="getHello">獲取helloworld組件中的值</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
<script>
Vue.component('helloWorld',{
template:`<div>helloWorld</div>`,
data(){
return {
number:0
}
},
methods:{
/*handelClick(){
console.log('我是子組件的方法');
}*/
}
})
const app = new Vue({
el: "#app",
data: {
},
methods: {
getHello(){
/* this.$refs.hello.handelClick(); */
console.log(this.$refs.hello.$el.innerHTML);
}
},
})
</script>
</body>
</html>效果如下:

六、is與:is
is
作用:解決了html模板的限制。
看下面這段代碼:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="app">
<table>
<row></row>
</table>
</div>
<script type="text/javascript">
Vue.component('row',{
template: '<tr><td>111</td></tr>'
})
const vm = new Vue({
el:'#app',
data(){
return{
}
},
})
</script>
</body>
</html>會正常輸出
但是:

會發(fā)現(xiàn)tr并不在table中,
解決辦法:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="app">
<table>
<tr is="row"></tr>
</table>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
<script>
Vue.component('row', {
template: '<tr><td>111</td></tr>'
})
const app = new Vue({
el: "#app",
})
</script>
</body>
</html>打印結(jié)果:

用:is還可以用來綁定動態(tài)組件
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="app">
<component :is="type"></component>
<button type="button" @click="changeClick">切換</button>
</div>
<script type="text/javascript">
// 這里要定義兩個全局組件
Vue.component('child-one',{
template:'<div>child-one</div>'
}),
Vue.component('child-two',{
template:'<div>child-two</div>'
})
const vm = new Vue({
el:'#app',
data(){
return{
type:'child-one'
}
},
methods:{
changeClick(){
this.type = this.type === 'child-one' ? 'child-two' :'child-one'
}
}
})
</script>
</body>
</html>效果如下:


以上就是Vue父子組件數(shù)據(jù)雙向綁定(父傳子、子傳父)及ref、$refs、is、:is的使用與區(qū)別的詳細(xì)內(nèi)容,更多關(guān)于Vue父子組件數(shù)據(jù)雙向綁定的資料請關(guān)注腳本之家其它相關(guān)文章!
- vue子組件改變父組件傳遞的prop值通過sync實現(xiàn)數(shù)據(jù)雙向綁定(DEMO)
- Vue.js實現(xiàn)數(shù)據(jù)雙向綁定的代碼示例
- 使用Vue.js實現(xiàn)數(shù)據(jù)的雙向綁定
- 淺析Vue3中通過v-model實現(xiàn)父子組件的雙向數(shù)據(jù)綁定及利用computed簡化父子組件雙向綁定
- vue中如何解除數(shù)據(jù)之間的雙向綁定
- vue3中reactive數(shù)據(jù)被重新賦值后無法雙向綁定的解決
- proxy實現(xiàn)vue3數(shù)據(jù)雙向綁定原理
- vue自定義組件實現(xiàn)v-model雙向綁定數(shù)據(jù)的實例代碼
- vue 數(shù)據(jù)雙向綁定的實現(xiàn)方法
- Vue項目開發(fā)實現(xiàn)父組件與子組件數(shù)據(jù)間的雙向綁定原理及適用場景
相關(guān)文章
vue.js 表格分頁ajax 異步加載數(shù)據(jù)
Vue.js通過簡潔的API提供高效的數(shù)據(jù)綁定和靈活的組件系統(tǒng).這篇文章主要介紹了vue.js 表格分頁ajax 異步加載數(shù)據(jù)的相關(guān)資料,需要的朋友可以參考下2016-10-10
vue基于html2canvas和jspdf?生成pdf?、解決jspdf中文亂碼問題的方法詳解
這篇文章主要介紹了vue基于html2canvas和jspdf?生成pdf?、解決jspdf中文亂碼問題的方法,結(jié)合實例形式詳細(xì)描述了中文亂碼問題的原因、解決方法與相關(guān)注意事項,需要的朋友可以參考下2023-06-06
vue2.0使用Sortable.js實現(xiàn)的拖拽功能示例
本篇文章主要介紹了vue2.0使用Sortable.js實現(xiàn)的拖拽功能示例,具有一定的參考價值,感興趣的小伙伴們可以參考一下。2017-02-02

