组件
创建
组件的定义:实现应用中局部功能代码和资源的集合
-
定义组件
Vue.extend(option)
option:和n
new Vue(option)
里的option几乎一致,但有点区别- el不写 原因:最终所有的组件都是vm管理,有vm决定服务哪一个容器
- data必须写成函数 原因:避免组件被复用的时候,数据存在引用关系
注意:可以使用template可以配置组件结构
-
注册组件
-
全局注册
Vue.component('组件名','组件')
-
局部注册
new Vue({ components: { '组件名' } })
-
-
使用组件:使用组件标签
组件名
- 一个单词组件:首字母大写或是小写都可以
- 多个单词组件:用
-
连接其余小写;首字母都大写(条件:需要Vue脚手架支持才可以)
注意:
- 组件名要尽可能的回避html中已有的元素名称
- 组件name配置项指定组件在开发者工具中呈现的名字
VueComponent构造函数
- 组件本质上一个名为VueComponent的构造函数,且不是程序员自己定义的,是Vue.extend生成的
- 我们只需要写组件标签就可以创建一个组件对象,我们简称vc,即Vue帮我们进行了new VueComponent
- 每次调用Vue.extend都会返回一个新的VueComponent
- this指向,在组件配置中 data,methods,watch,computed函数的this指向vc
**注意:VueComponent.prototype.__
proty__
==Vue.prototype **
属性
- ref属性,打标识,利用vc.$refs获取到打了标识的元素节点
属性传值
-
子组件以数组的形式接受
props: ['name','sex']
-
以对象的形式接收:限制传入的类型
props: { name:String, sex: String }
-
对象的完整写法,包括对类型的限制,默认值,是否必要
props: { name: { type:String, default:99, required:true } }
注意:props是只读的,不允许直接对传入的值进行修改,如果要修改会报错,如果业务需求要修改,可以复制一份到data里,修改data里的数据
子组件向父组件传值
- 父组件向子组件穿一个函数
- 子组件接受
props
- 调用传来的函数,将子组件传的值放在函数的参数内
插槽
-
默认插槽:写的全部接收
<slot></slot>
-
具名插槽:子组件中写name名字,父组件中用slot接收
...子组件中 <slot name="game1"></slot> <slot name="game2"></slot> ....父组件 <!-- 具名插槽 --> <category title="games"> <h3 slot="game1">{{games[0]}}</h3> <h4 slot="game2">{{games[1]}}</h4> </category>
-
作用域插槽:数据在组件自生,但根据数据生成的结构需要组件的使用者决定
<!-- 自定义插槽 --> <categorylist> <!-- <template scope="scopelist"> {{scopelist.movie}} </template> --> <!-- <template scope="{movie}"> {{movie}} </template> --> <h3 slot="title">movie</h3> <template slot-scope="{movie}"> <!-- <h3>movie</h3> --> <!-- {{movie}} --> <h3>{{movie[0]}}</h3> </template> </categorylist> .......子组件中movie为数据 <slot :movie='movie'></slot>
自定义事件
一种组件间通信的方式,使用与子组件--》父组件
父组件给子组件绑定自定义事件(事件的回调)在父组件中
绑定事件方式
-
父组件中
<Demo @demo="test">
或<Demo v-on:demo="test">
,test是父组件中方法(回调函数) -
<Demo ref="xxx"> ... mounted() { this.$refs.xxx.$on('demo',this.test) }
触发自定事件:this.$emit('demo',数据)
解绑自定义事件:this.$off('demo')
(解绑一个),如果要解绑多个可以用数组传入多个
组件用原生DOM事件,需要native修饰符
注意:
- 通过
this.$refs.xxx.$on('demo',回调)绑定自定义事件,回调要么配置methods方法中,要么用箭头函数,否则this指向会指向绑定的子组件对象
- 如果在子元素模板对象绑定内置事件,会当作内置对象来看待
组件间的通信方式
-
父组件传递数据给子组件
-
通过属性传值的方式,子组件用
props:[]
来接受数据 -
privide
和reject
组合使用传值...父组件 provide: { msg: 'appmsg数据' } ...后代组件 inject: ['msg']
数据会被代理
created() { console.log('created',this.msg) }, // 可以被访问到
注意:msg的数据是单向的,且不可更改,如果想更改,可以传data里面的数据,父组件中实现数据代理
-
-
父组件传递数据给子组件,并且双向数据绑定(子组件数据改变后父组件也改变)
-
通过自定义事件来将子组件的数据通过参数的形式传到父组件
-
在父组件中写回调函数,父组件调用的子组件标签中定义自定义事件
<Demo @demo="test">
或<Demo v-on:demo="test
<categorylist @change1="change1" :count="count"></categorylist> ..... methods: { change1() { // 子组件中用#emit触发事件调用回调函数 console.log('change1调用') this.count++ } }
-
在子组件中用
this.$emit()
调用事件// 传入的是自定义事件名字,是字符串要用字符串,如果有参数在后面添加 this.$emit("change1")
-
-
在父组件属性加
sync
来绑定数据count ,子组件用props
接受<categorylist :count.sync="count"></categorylist> .... //async其实相当于简写 props: ['count'], methods: { add(){let nc = this.count nc++ this.$emit("update:count",nc)} }
-
v-model绑定
// ... @input="msg" :value="msg"... <people v-model="msg"></people> ... props: ["value"], methods: { vchenge() { this.$emit("input",'修改后的value值') } }
-
多级传递
...父组件正常绑定事件 <category :title="title" @change="change"></category> ...中间层 可以通过this.$attrs来得到上一层传来的数据,不用porps接收 <categorylist v-bind="$attrs" v-on="$listeners"></categorylist> ...终点组件 props: ['title']
-
事件总线
-
在Vue的prototype上
Vue.prototype.$bus = this
new Vue({ // 编译模板 render: h=> h(App), beforeCreate() { Vue.prototype.$bus = this } }).$mount('#app')
-
在接受数据的组件定义自定义事件并写回调函数
mounted() { this.$bus.$on("lfclick", (data) => { this.text = data; }); },
-
在发送数据的组件触发自定义事件,并传递数据到参数中
this.$bus.$emit('lfclick','4444')
注意:绑定后要在beforeDestroy中
$this.$off()
注销 -
-
动态组件
实现切换功能,传统写法
component
-
写3个buttom模块添加点击事件,再3个组件写具体内容===>给每个tab添加一个组件标签
<button @click="fn(0)">1</button> <button @click="fn(1)">2</button> <button @click="fn(2)">3</button> <people v-show="peoples[0]"></people> <category v-show="peoples[1]"></category> <goods v-show="peoples[2]"></goods>
-
根据点击事件传入的参数判断哪个组件标签显示
methods: { fn(flag) { this.peoples.fill(false) // 数组没有的变化用$set this.$set(this.peoples,flag,true) console.log(this.peoples) }
在Vue中内置组件component可以更加简便的实现切换功能
-
同样要先写3个点击事件,传入的参数是组件名
<button @click="fn('category')">1</button> <button @click="fn('people')">2</button> <button @click="fn('goods')">3</button> <component :is="text"></component>
-
在
component
里的is属性写组件名,显示的就是哪个属性methods: { fn(flag) { this.text = flag }
注意:每次更换tab的时候会将原来组件对象销毁,生成一个新的组件对象
应用场景:你有时会想保持这些组件的状态,以避免反复重新渲染导致的性能问题。这时候可以用keep-alive
组件
keep-alive
对于不活动的组件实例缓存
属性
- include:字符串或是正则表达式
- exclude:字符串或是正则表达式
- max:数字,最多可以缓存多少组件实例(缓存最近的组件实例)
注意:写正则的时候要v-bind
异步加载组件
people: ()=>import('./components/People.vue'),
标签:...,Vue,自定义,事件,Vue2,props,组件
From: https://www.cnblogs.com/shuilifang/p/16768911.html