Vue组件二——data选项、局部组件、组件通信

data选项

  • data选项用于储存组件数据

与实例data差别

  1. 必须存储在有返回值的函数当中
  2. 数据设置在返回值对象里
1、方式一
data:function(){
return{
title:"组件标题",
content:"组件内容"
}
}
2、ES6的简写方式
data(){
return{
title:"组件标题",
content:"组件内容"
}
}

作用:确保每个组件实例单独维护一份返回对象的独立拷贝,相互之间不受影响(因为函数内部是单独的作用域)

Props选项

props命名规则

示例:我想跳转

建议prop定义时命名采用camelCase(驼峰命名),父组件绑定时使用kebab—case(因为html的属性不区分大小写)

局部注册

  • 局部注册组件只能作用在当前实例或组件中

挂载在id为app的实例中的组件ComA,ComB只能在app实例内使用

<div id="app">
<com-a></com-a>
<com-b></com-b>
</div>

方式一:在实例内部定义

		<script type="text/javascript">
new Vue({
el:"#app",
components:{
'ComA':{
template:"<div>{{word}}</div>",
data:function(){
return{
word:"this is A Compotent"
}
}
},
'ComB':{
template:"<div>{{word}}</div>",
data:function(){
return{
word:"this is B Compotent"
}
}
},
}
})
</script>

方式二:在实例外单独定义,实例内调用

		<script type="text/javascript">
var ComA ={
template:"<div>{{word}}</div>",
data:function(){
return{
word:"this is A Compotent"
}
}
};
var ComB = {
template:"<div>{{word}}</div>",
data:function(){
return{
word:"this is B Compotent"
}
}
};
new Vue({
el:"#app",
components:{
//—kabak命名必须带'',pascal命名法可不带引号
'com—a':ComA,
ComB:ComB
}
})
</script>

ES6简写:

要求:组件定义的名称必须符合pascal命名规则

			new Vue({
el:"#app",
components:{
ComA,
ComB
}
})

效果:

this is A Compotent

this is B Compotent

组件通信

组件通信——组件间传递数据的操作

常见类型:

  • 父组件向子组件传值
  • 子组件向父组件传值
  • 非父子组件传值
  • 其他通信方式

父组件向子组件传值

  1. 通过子组件的props选项参数接收父组件的传值
  2. 传值的类型可以是是值类型,也可以是数组及对象

三种传值方式:

  • 直接赋值
  • 传匿名值变量
  • 传父实例变量,随父组件数据值的变化而改变
		<div id="app">
<!--直接赋值—— props里的title直接赋值-->
<com-a my-title = "直接赋值的标题"></com-a>
<!--匿名值变量—— 相当于将值为'这是静态标题'的匿名变量赋值给props里的title -->
<com-a v-bind:my-title="'这是静态标题'"></com-a>
<!-- 将父实例数据title、content这两个变量赋值给props里的title、words -->
<com-a :my-title="title" :words="content"></com-a>
</div>
    	<script type="text/javascript">
Vue.component('ComA',{
props:['myTitle','words'],
template:`<div>
<h3>{{title}}</h3>
<p>{{words}}</p>
</div>`
});
new Vue({
el:"#app",
data:{
title:"全局标题",
content:"全局内容"
}
})
</script>
v-for在传值中的应用
		<div id="app">
<com-a v-for="item in items" :key="item.title"
:item-title="item.title"
:item-words="item.content"
:item="item"
></com-a>
</div>
			<script type="text/javascript">
Vue.component('ComA',{
props:['itemTitle','itemWords','item'],
template:`<div>
<h3>{{itemTitle}}</h3>
<p>{{item.content}}</p>
</div>`
});
new Vue({
el:"#app",
data:{
items:[
{
title:"全局标题1",
content:"全局内容1"
},
{
title:"全局标题2",
content:"全局内容2"
},
{
title:"全局标题3",
content:"全局内容3"
}
] }
})
</script>

子组件向父组件传值

自定义触发事件

子组件向父组件传值需要自定义事件

  1. 子组件数据变化时,通过$emit() 触发自定义事件
  2. 自定义事件名称建议使用kebab-case

具体步骤:

  1. 在子组件的方法里通过$emit() 自定义触发事件名称
  2. 在子组件实例html上指定自定义触发事件名称对应的响应函数或表达式
  3. 在父组件定义函数的具体内容(如果响应是表达式此步骤省略)
		<div id="app">
<!-- 2、在自定义组件里声明这个事件对应的函数或者表达式 -->
<com-a v-for="item in items" :key="item.id"
:item-title="item.title"
@count-change="TotalCount++"
></com-a>
<span>TotalCount:{{TotalCount}}</span>
</div>
			<script type="text/javascript">
Vue.component('ComA',{
props:['itemTitle','itemWords','item'],
template:`<div>
<div >
<span>{{itemTitle}}</span>
<span>{{count}}</span>
<button type="button" @click="countIns">+1</button>
</div>
</div>`,
data(){
return {
count:0
}
},
methods:{
'countIns':function(){
//1、通过emit自定义一个事件count-change
this.$emit('count-change');
this.count++;
}
}
});
new Vue({
el:"#app",
data:{
items:[
{
title:"苹果",
id:"1"
},
{
title:"香蕉",
id:"2"
},
{
title:"芒果",
id:"3"
}
],
TotalCount:0 },
methods:{
totalchange:function(){ this.TotalCount++;
}
}
})
</script>

效果:

$emit详解

1、无参数(参考上述例子)

  • 定义:

    this.$emit('count-change');

    指定(此处指定的是表达式):

    <com-a v-for="item in items" :key="item.id"
    :item-title="item.title"
    @count-change="TotalCount++"
    ></com-a>

2、带参数,通过$event去接收参数

  • 定义:

    this.$emit('count-change',5);
  • 指定(此处指定的是函数):

    			<com-a v-for="item in items" :key="item.id"
    :item-title="item.title"
    @count-change="totalchange($event)"
    ></com-a>
  • 在父组件定义对应的响应函数totalchange

    methods:{
    // 3、在父组件定义触发事件对应的函数
    totalchange:function(num){
    this.TotalCount+= num;
    }
    }

效果:

非父子组件传值

分类

  • 兄弟组件

  • 完全无关的组件

兄弟组件传值

思路1:通过父组件进行数据中转

思路n....

如下图思路:

  1. 首先通过com-a传值给父组件data里的value接收
  2. 将父组件的value传给com-b组件里props里的val接收
<div id="app">
<com-a @count-change="value=$event"></com-a>
<com-b :val="value"></com-b>
</div>
new Vue({
el:"#app",
data:{
items:[
value:""
]
}
})

完整代码:

		<div id="app">
<com-a @title-change="value=$event"></com-a>
<com-b :val="value"></com-b>
</div>
    <script type="text/javascript">
Vue.component('ComA',{
template:`<div>
<h3>这是组件A的标题:{{title}}</h3>
<button type="button" @click="countIns">传值</button>
</div>`,
data(){
return {
title:"生日快乐"
}
},
methods:{
countIns(){
this.$emit('title-change',this.title);
}
}
});
Vue.component('ComB',{
props:['val'],
template:`<div>
<h3>这是组件B的标题:{{val}}</h3>
</div>`
}); new Vue({
el:"#app",
data:{
value:""
}
})
</script>

效果:

完全无关组件传值(EventBus)

定义

EventBus(事件总线),类似数据搬运工、邮递员的角色

  • 一个独立的事件中心
  • 用于管理不同组件间的传值操作。
形式
  • 通过Vue实例来管理传值操作
  • 通过注册事件、调用事件来实现数据传递
  • 发送组件——触发bus事件,通过$emit去触发

    接收组件——给bus注册对应事件,通过$on去注册接收函数
步骤
  1. 新建一个Eventbus.js,定义一个bus的实例

    // 定义eventBus实例
    var bus = new Vue();
  2. 在html里引入EventBus.js

    	<head>
    <meta charset="utf-8">
    <title></title>
    <script src="vue.js" type="text/javascript" charset="utf-8"></script>
    <!-- 1、引入定义的eventbus -->
    <script src="EventBus.js" type="text/javascript" charset="utf-8"></script>
    </head>
  3. 组件里触发和注册

    		<div id="app">
    <com-a :my-title="title"></com-a>
    <com-b></com-b>
    </div>
    		<script type="text/javascript">
    // 传递组件A
    Vue.component('com-a',{
    props:['myTitle'],
    template:`<div>
    <span>{{myTitle}}</span>
    <span>{{count}}</span>
    <button type="button" @click="countIns">+1</button>
    </div>`,
    data(){
    return{
    count:0
    }
    },
    methods:{
    countIns(){
    //2、传递者——定义触发事件
    bus.$emit('count-change',1);
    this.count++;
    }
    } });
    //接收组件B
    Vue.component('com-b',{ template:`<div>
    <span>totalCount:{{totalCount}}</span>
    </div>`,
    data(){
    return {
    totalCount:0
    }
    },
    created() {
    //ES6的写法
    // bus.$on('count-change',num=>{
    // console.log(this.totalCount);
    // this.totalCount += num;
    // });
    // 注意和上面ES6写法的区别,此处方法内的this是指的函数,不能通过this.totalCount取到值
    var t =this;
    //3、接收者——通过$on获取值
    bus.$on('count-change',function(num){
    console.log(this);
    t.totalCount += num;
    });
    }
    });
    new Vue({
    el:"#app",
    data:{
    title:"苹果",
    id:1,
    totalCount:0
    }
    });
    </script>

    效果:

Vue(10)——Vue组件二(data选项、局部组件、组件通信)的更多相关文章

  1. Vue 全局注册逐渐 和 局部注册组件

    //定义一个名为 button-counter 的新组件 Script: Vue.component('button-counter',{//button-counter 这个是组件的名字 data: ...

  2. vue 组件 全局注册和局部注册

    全局注册,注册的组件需要在初始化根实例之前注册了组件: 局部注册,通过使用组件实例选项注册,可以使组件仅在另一个组件或者实例的作用域中可用: 全局组件 js Vue.component('tab-ti ...

  3. Vue框架(二)——Vue指令(v-once指令、v-cloak指令、条件指令、v-pre指令、循环指令)、todolist案例、Vue实例(计算、监听)、组件、组件数据交互

    Vue指令 1.v-once指令  单独使用,限制的标签内容一旦赋值,便不可被动更改(如果是输入框,可以主动修改) <!DOCTYPE html> <html lang=" ...

  4. vue 学习笔记(二)

    最近公司赶项目,一直也没时间看 vue,之前看下的都快忘得差不多了.哈哈哈,来一起回顾一下vue 学习笔记(一)后,继续向下看嘛. #表单输入绑定 基础用法 v-model 会忽略所有表单元素的 va ...

  5. vue-为什么子组件中的data选项必须是函数?

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. python 全栈开发,Day89(sorted面试题,Pycharm配置支持vue语法,Vue基础语法,小清单练习)

    一.sorted面试题 面试题: [11, 33, 4, 2, 11, 4, 9, 2] 去重并保持原来的顺序 答案1: list1 = [11, 33, 4, 2, 11, 4, 9, 2] ret ...

  7. vue单文件组件data选项的函数体获取vue实例对象

    因配置的关系,导致 vue的data选项中存在事件.而事件无法获取 vue 的实例对象:项目是单文件形式的,以下代码只是例子 new Vue({ el:..., data:{ a: { onevent ...

  8. vue构造函数(根实例化时和组件实例对象选项)参数:选项详解

    实例选项(即传给构造函数的options):数据,DOM,生命周期钩子函数,资源,组合,其他 数据 data 属性能够响应数据变化,当这些数据改变时,视图会进行重渲染. 访问方式: 1.通过 vm.$ ...

  9. Vue 根组件,局部,全局组件 | 组件间通信,案例组件化

    一 组件 <div id="app"> <h1>{{ msg }}</h1> </div> <script src=" ...

  10. JS组件系列——又一款MVVM组件:Vue(二:构建自己的Vue组件)

    前言:转眼距离上篇 JS组件系列——又一款MVVM组件:Vue(一:30分钟搞定前端增删改查) 已有好几个月了,今天打算将它捡起来,发现好久不用,Vue相关技术点都生疏不少.经过这几个月的时间,Vue ...

随机推荐

  1. DeepSeek-R1 技术全景解析:从原理到实践的“炼金术配方” ——附多阶段训练流程图与核心误区澄清

    字数:约3200字|预计阅读时间:8分钟 (调试着R1的API接口,看着控制台瀑布般流淌的思维链日志)此刻我仿佛看到AlphaGo的棋谱在代码世界重生--这是属于推理模型的AlphaZero时刻. D ...

  2. FreeSql学习笔记——1.入门

    前言 学习过程中,使用的是.Net 5 WebApi项目,数据库使用的是SQL Server,主要会整理下常用的api,现在就开始吧~   初始化 先选择一个WebCoreApi项目进行创建,创建完项 ...

  3. Linux - Linux终端里的二维码

    qrencode:Linux 操作系统中生成二维码,点此进入下载页面 1.将tar包上传到 Linux 服务器上并解压:tar -zxvf qrencode-x.x.x.tar.gz 2.在 .bas ...

  4. [解决方案]git pull : error: cannot lock ref 'refs/remotes/origin/*' (unable to update local ref)

    错误 git pull 报错不能更新本地分支 错误分析 本地分支跟远程分支不匹配 导致更新失败 解决方案 备份自己修改的代码 .git\refs\remotes (文件路径)对应删除你报错的分支 gi ...

  5. 响应式编程之Reactive Streams介绍

    Reactive Streams 是一种用于‌异步流处理的标准化规范,旨在解决传统异步编程中的背压管理.资源消耗及响应速度等问题‌. 一.核心概念 ‌基本模型‌ ‌发布者(Publisher)‌:负责 ...

  6. Windows编程----进程的当前目录

    进程的当前目录 Windows  Api中有大量的函数在调用的时候,需要传递路径.比如创建文件,创建目录,删除目录,删除文件等等.创建文件的APICreateFile做比喻,如果我们要创建的文件路径不 ...

  7. 谷歌 Chrome 浏览器离线安装 vue devtools 插件

    由于某些原因,Chrome 应用商店访问不了,所以只能离线安装 vue devtools 插件,离线安装也有两种方法. 方法一:自编译 vue devtools 插件 这方法要求动手能力强的同学. 前 ...

  8. golang倒腾一款简配的具有请求排队功能的并发受限服务器

    golang官方指南给了一些代码片段来,层层递进演示了信道的能力: 1>. 信号量 2>. 限流能力 var sem = make(chan int, MaxOutstanding) fu ...

  9. mysql导入失败

    mysqldump导出数据库表的数据会加上一些SQL的注释,这些注释会在批量执行SQL语句中造成错误,需要提前删除. sql开始部分: SET @@SESSION.SQL_LOG_BIN = @MYS ...

  10. 基于OpenSSL的密码管理系统-应用密码学课程报告

    第1章 概要设计 1.1 设计目的 本研究旨在设计并实现一个基于OpenSSL的密码管理系统,该系统具备密钥对的生成.密钥上传.密钥的核对.身份认证.文件与邮件的加密和解密.数字签名及数字证书管理等常 ...