目录
VUE组件/组件数据传递
组件化开发的好处:重复使用 提高效率
全局组件:在任意组件中都可以使用,包括全局组件内调用另一个全局组件
调用组件:
在html页面中 你需要用组件的地方
直接 标签 组件名即可
<组件名字></组件名字>
# 组件可重复调用
语法:
Vue.component('组件名字',{'组件内数据'})
# 生成一个组件 需要在 vue对象外
template:
# 组件渲染的标签 一个div标签包裹一下
data(){ return{组件内数据值} }
# 必要要用data方法取返回数据
methods:{}
# 组件内执行的函数
Vue.component('child', {
template:
<div>
<button>后退</button>
<span style="font-size: 40px">首页--{{ name }}</span>
<button @click="handleFor">前进</button>
</div>
data() {
# data必须是方法,返回对象
return {
name: '彭于晏',
}
methods: {
handleFor() {
this.name = 'lqz'
}
局部组件
局部组件只能在自己的组件中使用
局部组件需要定义在一个组件内
属于一个属性
举例:相当于在app这个组件中 编写了一个局部组件 这个局部组件只能在app组件内使用,
不可以再其他组件中使用
如果你在 A组件中编写了局部组件B,那局部组件B只能在A组件标签内才可以使用
var vm = new Vue({
el: '#app',
data: {
dataList:[],
},
methods:{},
created(){
axios.get('http://127.0.0.1:8001/api/goods/film/').then(res=>{
this.dataList = res.data.data.films
})
},
mounted(){},
components:{
#可以再任意组件中添加局部组件属性
'局部组件名':{
template:
<div>
<button>后退</button>
<span style="font-size: 40px">首页--{{ name }}</span>
<button @click="handleFor">前进</button>
</div>
data() {
return { name: '彭于晏', }
methods: {
handleFor() {
this.name = 'lqz'
}
}}})
-组件有自己独有的html,css,js 数据 事件
-在组件中,this 代指当前组件
-父子组件的数据data是无法共享的
-组件的data是1个函数,需要有返回值(return)
组件间数据传递 父传子
自定义属性的方式
1.定义一个组件 var child
2.将定义好的组件 添加入根组件内 components:{child}
3.在子组件标签内 添加自定义属性获取父组件的值<child :name="name">
4.子组件内接收自定义的属性 props:['name']
5.这样子组件内就也有了name这个属性,对应的值就是父组件的name
注意:自定义属性名不可以有大写,不要用驼峰可以使用_
<div id="app">
<child :name="name"></child>
</div>
<script>
var child = {template:'{ <div><p>{{age}}</p>' +
'我是子组件' +
'我是父组件的name:{{name}}'+
'</div> }',
data(){return {age:'19'}},
props:['name']
}
var vm = new Vue({
el:'#app',
data:{
name:'moon',
},
components:{
child
}
})
</script>
组件间数据传递 子传父
自定义事件的方式
1.首先在子组件标签上添加一个自定义事件@myevent="handleevent" 任意命名
2.在子组件内添加一个单击事件来触发 自定义事件
handleClick() { this.$emit('myevent',this.mytest) }
# 子组件内部事件,触发后执行 子组件的自定义事件('事件名','需要传递的数据')
3.在父组件内创建这个事件,来接收传递的参数 也就是接收到了子组件的数据
methods: {handleevent(mytest) {this.mytest = mytest}
# 通过事件 拿到了子组件传来的数据参数mytest,然后父组件接收一下即可
<div id="app">
<hr>
<child @myevent="handleevent"></child>
<hr>
<p>子组件传递的数据:{{mytest}}</p>
</div>
<script>
var child = {
template:
'{ <div> <input type="text" v-model="mytest"> {{mytest}}' +
'<button @click="handleClick">点我传递</button>' +
'</div> }',
data() {
return {age: '19', mytest: ''}
},
methods: {
handleClick() {
this.$emit('myevent',this.mytest)
# 子组件中,触发自定义事件的执行,会执行父组件自定义事件绑定的函数,有几个参数,就传几个参数
}
},
}
var vm = new Vue({
el: '#app',
data: {
name: 'moon',
mytest: '',
},
methods: {
handleevent(mytest) {
this.mytest = mytest
}
},
components: {
child
}
})
</script>
更方便的父子组件数据-ref(推荐)
可以给标签添加ref属性
任何标签都可以加上ref属性,有了ref属性就可以根组件中this.$refs.属性名拿到标签对象
# ref属性放在普通标签上 <input type="text" ref="myinput">
-通过this.$refs.myinput 拿到的是原生dom对象,通过原生dom修改 标签
#ref属性放在组件上 <child ref="mychild"></child>
-通过this.$refs.mychild 拿到的是组件对象,既然拿到了组件对象,组件对象中的 变量,方法,都能直接通过 . 的方式调用
-因此不需要关注是子传父,还是父传子,直接通过组件对象,使用即可
1.给子组件添加<child ref="child_obj"></child>属性
2.添加了这个属性的标签都可以被主组件拿到
# 父用子的数据
3.在主组件里面 this.child_obj = this.$refs.child_obj 使用
# this.$refs.child_obj可以直接拿到子组件对象, 有了对象就可以直接用子主键中的所有数据和方法,
<child ref="child_obj"></child>
new Vue({
el:'#app',
data:{name:'主组件',child_obj:''},
# 提前准备一个变量来接收子对象
methods:{
hanleClick(){
this.child_obj = this.$refs.child_obj
# 事件触发,通过给子组件的refs属性拿到子组件对象
# 然后这样在主键值中就可以用
},
},
components:{
child
}
})
子用父的数据
4.在主组件里面有了子组件对象,可以对子组件对象直接添加数据,把主组件的数据传给子组件
var child = {
template:' <div><h3>子拿父的:{{age}}</h3></div> ',
data(){
return {name:'子来了',age:''}
# 先子组件呢定义要接收的变量
},
}
methods:{
hanleClick(){
this.child_obj = this.$refs.child_obj
this.$refs.child_obj.age = '主来了'
# 通过ref属性拿到子组件对象,然后把主组件的数据之直接赋予子组件即可
},
},
基础方法实现导航栏
<div id="app">
<span @click="handelClick('home')"> 首页 </span> |<span @click="handelClick('order')">订单</span>
|<span @click="handelClick('goods')">商品</span>
<home v-if="choose=='home'"></home>
<order v-else-if="choose=='order'"></order>
<goods v-else></goods>
</div>
# v-if来控制组件是否展示
# 通过绑定事件传参的方式,区分现在要执行的是哪个组件
<script>
var home = {
template: '{ <div> <h2>我是home</h2> </div>> }'
}
var order = {
template: '{ <div> <h2>我是order</h2> </div>> }'
}
var goods = {
template: '{ <div> <h2>我是goods</h2> </div>> }'
}
new Vue({
el: '#app',
data: {
choose: 'home'
},
methods: {
handelClick(type) {
this.choose = type
}
},
components: {
home, order, goods
}
})
</script>
动态组件实现导航/和keep_alive方法
<div id="app">
<span @click="handelClick('home')"> 首页 </span> |<span @click="handelClick('order')">订单</span>
|<span @click="handelClick('goods')">商品</span>
<component :is="choose"></component>
</div>
# <component :is="choose"></component>动态组件,is的值是什么就会执行对应的组件
# 通过事件来控制 执行的组件
script>
var home = {
template: '{ <div> <h2>我是home</h2> </div>> }'
}
var order = {
template: '{ <div> <h2>我是order</h2> </div>> }'
}
var goods = {
template: '{ <div> <h2>我是goods</h2> </div>> }'
}
new Vue({
el: '#app',
data: {
choose: 'home'
},
methods: {
handelClick(type) {
this.choose = type
}
},
components: {
home, order, goods
}
})
</script>
keep_alive方法保持组件不销毁
正常当你在页面切换组件,组件就会刷新,你在组件内输入未生效的都会被清楚
例如 搜索框输入的文字,输入一半的文章等,我们可以通过keep_alive标签包裹组件,
<keep-alive>
<component :is="choose"></component>
</keep-alive>
# 这样就会保存组件的状态,例如你输入一半的文章组件,你切换到了其他组件,再回来,未完成的文章还是在的
组件插槽
<keep-alive>
<component :is="choose">给组件添加数据</component>
</keep-alive>
调用组件后是无法再改变组件的内容的,所以需要在组件中预留插槽,这样调用组件后才可以添加内容
# 一般情况下,编写完1个组件之后,组件的内容都是写死的,需要加数据 只能去组件中修改,扩展性很差
# 然后就出现了插槽这个概念,只需在组件中添加<slot></slot>,就可以在body的组件标签中添加内容
匿名插槽
<keep-alive>
<component :is="choose">给组件添加数据</component>
# 如果组件中没有插槽,那么调用后是无法再插入数据的
# 如果组件中有插槽,那么这里插入的内容 是会在组件中显示的
</keep-alive>
</div>
</body>
<script>
var home = {
template: '{ <div> <h2>我是home</h2> <slot> </slot></div>> }'
} # home 组件预留了插槽,
var order = {
template: '{ <div> <h2>我是order</h2> </div>> }'
# order 组件没有预留插槽
}
具名插槽
匿名插槽是不准确的,如果一个组件中有多个插槽那就会出现重复
可以给插槽标签添加name属性 然后在插入内容时 指定插入的插槽
var home = {
template: '{ <div> <h2>我是home</h2>
<slot name="a1"></slot>
<p>哈哈哈 <slot name="a2"> </slot> </p></div>> }'}
# <slot name="插槽名"></slot>
<keep-alive>
<component :is="choose"> <p slot="a2">给组件添加数据</p></component>
</keep-alive>
# 在组件内插入内容时,可以指定标签插入的位置 slot="a2" 这样就会插入到组件中预留的有名插槽中、
标签:VUE,name,插槽,知识,var,child,组件,data
From: https://www.cnblogs.com/moongodnnn/p/17131374.html