vue(基础二)_组件,过滤器,具名插槽
一、前言
主要包括: 1、组件(全局组件和局部组件)
2、父组件和子组件之间的通信(单层)
3、插槽和具名插槽
4、过滤器
二、主要内容
1、组件
(1)组件在mvc中充当的角色
(1)局部组件
三个步骤:1、创建局部主键,2.挂载局部组件,3.使用局部组件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style type="text/css"> .h{ width: 400px; height: 100px; background-color: red; } .f{ width: 400px; height: 50px; background-color: green; } .c{ width: 400px; height: 180px; background-color: blue; } </style> </head> <body> <div id="app"> </div> <script type="text/javascript" src="node_modules/vue/dist/vue.js"></script> <script type="text/javascript"> //创建子组件 //1.子组件中没有el,其余和父组件是一样的 var Vheader = { template:`<header class="h">这是h5的头部</header>`, data(){ return{ } } } var Vcontent = { template:`<div class="c">这是h5的内容</div>`, data(){ return{ } } } var Vfooter = { template:`<div class="f">这是h5的尾部</div>`, data(){ return{ } } } var App={ data(){ //2.子组件中这里的data一定要写返回值的形式 return{ } }, template:` <div> <Vheader /> <Vcontent /> <Vfooter /> </div> `, components:{ Vheader, Vcontent, Vfooter } } new Vue({ el:'#app', data(){ return { } }, template:'<App></App>',//使用子组件 components:{ App//挂载子组件 } }) </script> </body> </html>
显示如图:
注意点:子组件在调用其他组件的时候也一定要用一个div包裹住,如果不包裹会提示以下错误
var App={ data(){ //2.子组件中这里的data一定要写返回值的形式 return{ } }, template:` <div> <Vheader /> <Vcontent /> <Vfooter /> </div> `, components:{ Vheader, Vcontent, Vfooter } }
(2)全局组件:第一个参数是组件名,使用的时候不需要挂载,直接在页面中使用
Vue.component('Vbtn',{ template:` <button>按钮</button> ` });
2、父组件和子组件之间的通信(单层)
(1)父组件向子组件通信原则:
1.父组件中先给子组件定义一个自定义属性,并将自己的data里面的数据传给这个自定义属性
2.子组件通过props:[]接受自定义属性
3.子组件就可以使用该自定义属性
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <div id="app"> </div> <script type="text/javascript" src="node_modules/vue/dist/vue.js"></script> <script type="text/javascript"> //子组件 Vue.component('Child', { template:` <div> 这里是子组件 <input :value='childData'> </div> `, props:['childData'] }) //1.先在父组件中定义一个自定义属性 //2.子组件中用prop[]接收 //父组件 Vue.component('Parent',{ data(){ return { msg:'这是父组件中的数据' } }, template:`<div> 这是父组件 <Child :childData='msg'></Child> </div>` }) new Vue({ el:'#app', data(){ return { } }, template:'<Parent></Parent>', }) </script> </body> </html>
具体实现:
查看页面显示结果:
(2)子组件向父组件传递数据原则:
1.在父组件中绑定自定义事件
2.在子组件中触发元原生的事件 在methods中使用$emit()触发已经定义的事件,
$emit()中含有两个参数, 第一个参数:父组件中定义的函数,第二个参数:子组件的数据
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <div id='app'></div> <script type="text/javascript" src="node_modules/vue/dist/vue.js"></script> <script type="text/javascript"> //子组件 Vue.component('Child', { template:` <div> 这里是子组件 <input v-model='childData' @input='childerValue(childData)'> </div> `, props:['childData'], methods:{ childerValue(val){ //// 触发父组件 中声明的自定义事件 vue $emit() // 第一个参数是触发自定义事件的名字 第二个参数就是传进去的值 this.$emit('childerHander', val) } } }) //父组件 Vue.component('Parent',{ data(){ return { msg:'这是父组件中的数据' } }, template:`<div> 这是父组件 <Child @childerHander='childerHander'></Child> </div>`, methods:{ //定义自定义的事件 childerHander(val){ console.log(val) } } }) new Vue({ el:'#app', data(){ return { } }, template:'<Parent></Parent>', }) </script> </body> </html>
具体实现如下:
注意:不能直接修改props[]里面的属性,否则会报错:详情参考:https://blog.csdn.net/qq_41009742/article/details/84316157
vue.js:634 [Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "childData"
found in
---> <Child>
<Parent>
<Root>
3、插槽和具名插槽:官网:https://cn.vuejs.org/v2/guide/components-slots.html#ad
(1)举一个例子引出插槽的概念
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <div id="app"> </div> <script type="text/javascript" src="node_modules/vue/dist/vue.js"></script> <script type="text/javascript"> //子组件 Vue.component('Cbtn', { template:` <button></button> `, }) //父组件 Vue.component('Parent',{ data(){ return { msg:'这是父组件中的数据' } }, template:`<div> 这是父组件 <Cbtn>注册</Cbtn> <Cbtn>登录</Cbtn> </div>` }) new Vue({ el:'#app', data(){ return { } }, template:'<Parent></Parent>', }) </script> </body> </html>
核心代码:
在浏览器中查看:发现按钮上面的文字并没有替换成我们想要的,
(2)但是很多时候我们并不希望组件中的数据内容被写死,比如我们想还可以根据自己的需要在组件中加入其它标签,
解决方案:<slot></slot>
4、过滤器
(1)局部过滤
(2)全局过滤
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <div id="app"> </div> <script type="text/javascript" src="node_modules/vue/dist/vue.js"></script> <script type="text/javascript"> // 全局过滤器 Vue.filter('myReverse',function(value,arg1) { return arg1+' '+ value.split('').reverse().join(''); }); new Vue({ el:'#app', data(){ return { money:50, msg:'hello vue' } }, template:'<div><div>{{money | formatMoney}}</div> <div>{{msg | myReverse("hihi")}}</div></div>', //局部过滤器 filters:{ formatMoney(value){ return '$' + value; } } }) </script> </body> </html>
三、总结
1、
注意点:子组件在调用其他组件的时候也一定要用一个div包裹住
2.prop:[]中的属性原则上是不能随意改动的,如果要改动最好在data定义一个属性来接收