二十二、组件的概念
二十三、Vue局部组件的使用一:main组件,header组件
二十四、Vue局部组件的使用二:main组件,header组件,aside组件,content组件
二十五、通过props向子组件传递数据
二十六、通过props向子组件渲染对象列表
二十七、子组件可以使用 $emit 触发父组件的自定义事件
二十八、全局组件的创建和使用
二十九、组件内置标签slot插槽
三十、Vue局部过滤器和全局过滤器的使用
三十一、侦听属性之watch
三十二、计算属性之computed
三十三、计算属性的setter方法
三十四、计算属性案例之音乐播放器(略)
三十五、计算属性之音乐播放器样式处理(略)
二十二、组件的概念
使用组件时:data必须是一个函数
组件的注册类型:全局和局部
具体的看官网:
如果不写template,可以直接在<div id="app"></div>中写components中挂载的组件。局部或者全局都可以
一定要注意组件的命名!一定要注意组件的命名!一定要注意组件的命名!,不能有已存在的HTML标签名,例如Header, Main, main-a, main-b 等
组件命名
1:使用kebab-case(短横线)
2:使用 PascalCase(首字母大写)
*在HTML模板中只能使用短横线
文件命名
- 文件名统一采用驼峰式(Camel-Case)
- 页面中
import
引入的名称与注册组件时的名字保持一致,使用首字母大写 - 模板中使用组件必须使用短横线式
二十三、Vue局部组件的使用一:main组件,header组件
<body> <div id="app"> {{msg}} </div> <script type="text/javascript" src="./node_modules/vue/dist/vue.js"></script> <script type="text/javascript"> //先声子 在挂子 在用子 // “声子” var Vheader={ template:`<header class="head">我是头部</header>` }; //1.声明入口组件 /* 1)头部组件 2)侧边栏 3)内容组件 4)脚部组件 */ var Vmain = { //“用子” template: `<div class="main"> <Vheader /> </div>`, components: { //“挂子” 等价于Vheader:Vheader Vheader } }; new Vue({ el:"#app", //3.使用子组件 template:"<Vmain />", data:{ msg:'hello' }, components:{ //2.挂载子组件 组件名:组件对象 Vmain:Vmain } }); </script> </body>
二十四、Vue局部组件的使用二:main组件,header组件,aside组件,content组件
<body> <div id="app"> {{msg}} </div> <script type="text/javascript" src="./node_modules/vue/dist/vue.js"></script> <script type="text/javascript"> //先声子 在挂子 在用子 // “声子” var Vheader={ template:`<header class="header">我是头部</header>` }; var Vaside={ template:`<div class="aside">我是侧边栏</div>` }; var Vcontent={ template:`<div class="content">我是内容区</div>` }; //1.声明入口组件 /* 1)头部组件 2)侧边栏 3)内容组件 4)脚部组件 */ var Vmain = { //“用子” template: `<div class="main"> <Vheader /> <div class="wrap"><Vaside /><Vcontent /></div> </div>`, components: { //“挂子” 等价于Vheader:Vheader Vheader, Vaside, Vcontent } }; new Vue({ el:"#app", //3.使用子组件 template:"<Vmain />", data:{ msg:'hello' }, components:{ //2.挂载子组件 Vmain:Vmain } }); </script> </body>
二十五、通过props向子组件传递数据
局部组件的使用总结:声子、挂子、用子
父组件向子组件传递数据:单向数据流,通过Prop
1.在子组件自定义特性。props:['自定义的属性1', '自定义的属性2']
当一个值传递给一个prop特性的时候,
它就变成了那个组件实例的一个属性,那么我们就可以像访问data中的值一样
2.要在父组件中导入的子组件内部绑定自定义的属性
<Vheader :title='父组件中data声明的数据属性'>
注意:一个组件默认可以拥有任意数量的prop,任何值都可以传递给任何prop
<body> <div id="app"> </div> <script type="text/javascript" src="./node_modules/vue/dist/vue.js"></script> <script type="text/javascript"> var Vheader={ template:`<header class="header">{{title}}</header>`, props:['title'] }; var Vaside={ template:`<div class="aside">我是侧边栏</div>` }; var Vcontent={ template:`<div class="content">我是内容区</div>` }; var Vmain = { template: `<div class="main"> <Vheader :title="title"/> <div class="wrap"><Vaside /><Vcontent /></div> </div>`, components: { Vheader, Vaside, Vcontent }, props:['title'] }; new Vue({ el:"#app", template:"<Vmain :title='text'/>", data:{ text:"我是一个标题hhhhhhh" }, components:{ Vmain:Vmain } }); </script> </body>
渲染结果:
<div class="main"> <header class="header">我是一个标题hhhhhhh</header> <div class="wrap"> <div class="aside">我是侧边栏</div> <div class="content">我是内容区</div> </div> </div>
二十六、通过props向子组件渲染对象列表
注意:在组件中遍历的时候要加key:<li v-for="item in list" :key="item.id">
<body> <div id="app"> </div> <script type="text/javascript" src="./node_modules/vue/dist/vue.js"></script> <script type="text/javascript"> var Vheader={ template:`<header class="header">{{title}}</header>`, props:['title'] }; var Vaside={ template:`<div class="aside">我是侧边栏</div>` }; var Vcontent={ template:`<div class="content"> <ul> <li v-for="item in list" :key="item.id"> <h3>标题:{{item.title}}</h3> <p>内容:{{item.content}}</p> </li> </ul> </div>`, props:['list'] }; var Vmain = { //“用子” template: `<div class="main"> <Vheader :title="title"/> <div class="wrap"><Vaside /><Vcontent :list="list"/></div> </div>`, components: { Vheader, Vaside, Vcontent }, props:['title', 'list'] }; new Vue({ el:"#app", template:"<Vmain :title='text' :list='posts'/>", data:{ text:"我是一个标题hhhhhhh", posts:[ {id:1, title:"组件中的传值1", content:"通过prop传递数据1"}, {id:2, title:"组件中的传值2", content:"通过prop传递数据2"}, {id:3, title:"组件中的传值3", content:"通过prop传递数据3"}, ], }, components:{ Vmain:Vmain } }); </script> </body>
渲染结果:
<body> <div class="main"> <header class="header">我是一个标题hhhhhhh</header> <div class="wrap"> <div class="aside">我是侧边栏</div> <div class="content"> <ul> <li><h3>标题:组件中的传值1</h3> <p>内容:通过prop传递数据1</p></li> <li><h3>标题:组件中的传值2</h3> <p>内容:通过prop传递数据2</p></li> <li><h3>标题:组件中的传值3</h3> <p>内容:通过prop传递数据3</p></li> </ul> </div> </div> </div> </body>
二十七、子组件可以使用 $emit 触发父组件的自定义事件
点击Vcontent里面的按钮,改变Vmain里所有字体的大小。
使用自定义事件 $emit
1.给子组件中的某个按钮绑定原生的事件,我们可以调用内建的
this.$emit("自定义的事件名","传递的数据"),来向父级组件触发一个自定义的事件
2.在父组件中的子组件标签中要绑定自定义的事件
代码:
<body> <div id="app"> </div> <script type="text/javascript" src="./node_modules/vue/dist/vue.js"></script> <script type="text/javascript"> var Vheader={ template:`<header class="header">{{title}}</header>`, props:['title'] }; var Vaside={ template:`<div class="aside">我是侧边栏</div>` }; var Vcontent={ template:`<div class="content"> <button @click="changeSize">改变字体大小</button> <ul> <li v-for="item in list" :key="item.id"> <h3>标题:{{item.title}}</h3> <p>内容:{{item.content}}</p> </li> </ul> </div>`, props:['list'], methods:{ changeSize(){ this.$emit("modifySize",3) } } }; var Vmain = { template: `<div class="main" :style='{fontSize: fontsize+"px"}'> <Vheader :title="title"/> <div class="wrap"><Vaside /><Vcontent :list="list" @modifySize="sizeHandler"/></div> </div>`, components: { Vheader, Vaside, Vcontent }, props:['title', 'list'], methods: { sizeHandler(value){ this.fontsize += value } }, data(){ return { fontsize:18 } } }; new Vue({ el:"#app", template:"<Vmain :title='text' :list='posts'/>", data:{ text:"我是一个标题hhhhhhh", posts:[ {id:1, title:"组件中的传值1", content:"通过prop传递数据1"}, {id:2, title:"组件中的传值2", content:"通过prop传递数据2"}, {id:3, title:"组件中的传值3", content:"通过prop传递数据3"}, ], }, components:{ Vmain:Vmain } }); </script> </body>
二十八、全局组件的创建和使用
局部组件:中的this指的vue实例化对象的子类,继承了vue实例化对象的所有属性
全局组件:创建了在任何地方都可以用
Vue.component('全局组件的名字',{
跟new Vue() 实例化对象中的options是一样,但是要注意:
不管是公共组件还是局部组件 data必须是一个函数,函数一定要返回{}
})
<body> <div id="app"> </div> <script type="text/javascript" src="./node_modules/vue/dist/vue.js"></script> <script type="text/javascript"> //全局组件声明 Vue.component('Vbtn',{ template: '<button type="button">哈哈</button>' }); //在任何地方都能使用全局组件 var Vheader = { template: `<div class="head"> <Vbtn></Vbtn> <Vbtn></Vbtn> </div>` }; var App = { template: '<div class="main">我是App<Vheader></Vheader></div>', components: { Vheader } }; new Vue({ el: '#app', template:'<div><App /></div>', data() { return{ msg:'alex', } }, components:{ App } }); </script> </body>
结果:
<body> <div> <div class="main">我是App <div class="head"> <button type="button">哈哈</button> <button type="button">哈哈</button> </div> </div> </div> </body>
二十九、组件内置标签slot插槽
在子组件内使用特殊的<slot>元素就可以为这个子组件添加一个 slot (插槽),
在父组件模板里,插入在子组件标签内的所有内容将替代子组件的<slot>标签及它的内容.
<body> <div id="app"> </div> <script type="text/javascript" src="./node_modules/vue/dist/vue.js"></script> <script type="text/javascript"> //全局组件 Vue.component('Vbtn', { template: '<button :class="type"><slot>我是默认按钮</slot></button>', props: ['type'] }); //在任何地方都能使用全局组件 var Vheader = { template: `<div class="head"> <Vbtn>登录</Vbtn> <Vbtn>注册</Vbtn> <Vbtn>默认按钮</Vbtn> <Vbtn type="primary">主要按钮</Vbtn> <Vbtn type="success">成功按钮</Vbtn> </div>` }; var App = { template: '<div class="main">我是App<Vheader></Vheader></div>', components: { Vheader } }; new Vue({ el: '#app', template: '<div><App /></div>', data() { return { msg: 'alex', } }, components: { App } }); </script> </body>
结果:(css代码略)
<body> <div> <div class="main">我是App <div class="head"> <button class="default">登录</button> <button class="default">注册</button> <button class="default">默认按钮</button> <button class="default primary">主要按钮</button> <button class="default success">成功按钮</button> </div> </div> </div> </body>
三十、Vue局部过滤器和全局过滤器的使用
过滤器:
过滤器可以用在两个地方:双花括号插值和v-bind表达式。
过滤器应该被添加在JavaScript表达式的尾部,由“管道”符号指示
声明:
filters:{'过滤器名字':function(value){...}}
使用:
{{ 变量 | '过滤器名字' }}
局部过滤器:在组件中声明的过滤器
如果在vue实例化对象里声明filter,这个filter是局部过滤器
全局过滤器:任何地方都能使用
Vue.filter('过滤器名字',function(value){...})
<body> <div id="app"> <input type="text" v-model:value="price"> <h2>{{price | currentPrice}}</h2> <h3>{{ msg | reverse }}</h3> </div> <script type="text/javascript" src="./node_modules/vue/dist/vue.js"></script> <script type="text/javascript"> //全局过滤器,在任何地方使用 Vue.filter('reverse', function (value) { return value.split('').reverse().join(''); }); new Vue({ el: '#app', template: '', data() { return { msg: 'hello world', price: 0 } }, //局部过滤器,在组件内使用 filters: { currentPrice: function (value) { return '$' + value; } } }); </script> </body>
效果:
三十一、侦听属性之watch
Vue 提供了一种更通用的方式来观察和响应 Vue 实例上的数据变动:侦听属性。
当你有一些数据需要随着其它数据变动而变动时,你很容易滥用 watch
——特别是如果你之前使用过 AngularJS。然而,通常更好的做法是使用计算属性而不是命令式的 watch
回调。
watch用于监测data中属性的变化,属性变化触发事件。
监听一个属性用侦听属性watch,监听多个属性用计算属性computed
<body> <div id="app"> <input type="text" v-model:value="name"> <h2>{{name}}</h2> <button @click="clickHandler">修改</button> </div> <script type="text/javascript" src="./node_modules/vue/dist/vue.js"></script> <script type="text/javascript"> new Vue({ el: '#app', template: '', data() { return { name:'' } }, methods:{ clickHandler:function () { this.name = 'alex' } }, watch:{ name:function (value) { if(value === 'alex'){ console.log(value +':哈哈哈') } } } }); </script> </body>
效果:点击“修改”后
三十二、计算属性之computed
监听一个属性用侦听属性watch,监听多个属性用计算属性computed
渲染的时候用双大括号或者v-bind:
简单的逻辑可以使用侦听属性。如果逻辑复杂再用侦听属性就难以维护,应该使用计算属性computed
计算属性实时监听多个数据变化,如果某个事件对数据属性进行了修改,同样会导致计算属性的事件生效
计算属性:默认只有getter方法
data(){
return {name:'alex', age:18}
}
computed{
计算属性方法名:function(){ return ... }
}
<body> <div id="app"> <h3>{{desc}}</h3> <button @click="clickHandler">修改</button> </div> <script type="text/javascript" src="./node_modules/vue/dist/vue.js"></script> <script type="text/javascript"> new Vue({ el: '#app', template: '', data() { return { name: 'alex', age: 18 } }, methods: { clickHandler: function () { this.name = 'wusir'; this.age = '20'; } }, //计算属性声明方式 computed: { desc: function () { return `${this.name}已经${this.age}岁,可以去大保健了` } } }); </script> </body>
效果:
点击“修改”后:
三十三、计算属性的setter方法
<body> <div id="app"> <input type="text" v-model:value="desc"> <h3>{{desc}}</h3> </div> <script type="text/javascript" src="./node_modules/vue/dist/vue.js"></script> <script type="text/javascript"> new Vue({ el: '#app', template: '', data() { return { name: '', } }, computed: { desc: { // getter get: function () { return this.name; }, // setter set: function (newValue) { this.name = newValue; } } } }); </script> </body>
效果:
三十四、计算属性案例之音乐播放器(略)
三十五、计算属性之音乐播放器样式处理(略)