计算属性
计算属性就是当其依赖属性的值发生变化时,这个属性的值会自动更新,与之相关的DOM部分也会同步自动更新。当有数据需要经过复杂逻辑计算时,可以使用计算属性
简单使用 getter语法糖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| <template> <div> <p>{{allPrice}}</p> </div> </template>
<script> export default{ name:'compute', data() { return{ shops:[ {name:'苹果',price:35}, {name:'西瓜',price:15}, {name:'香蕉',price:25}, {name:'菠萝',price:45}, ] } }, computed:{ //将计算逻辑以函数形式写在 computes中 在template中使用时不需要加(),直接当成属性使用即可 allPrice(){ let res = 0 for(let shop of this.shops){ res+=shop.price } return res } }, methods:{
} } </script>
<style> </style>
|
完整使用 getter与setter, 计算属性一般是不使用set方法的,所以通常使用上面的getter语法糖形式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| <template> <div> <p>{{allPrice}}</p> </div> </template>
<script> export default{ name:'compute', data() { return{ shops:[ {name:'苹果',price:35}, {name:'西瓜',price:15}, {name:'香蕉',price:25}, {name:'菠萝',price:45}, ] } }, computed:{ allPrice{ setter(newValue){ //set 方法是监视对应的属性值,当值发生变化时会自动回调set方法 console.log(newValue) }, getter(){ let res = 0 for(let shop of this.shops){ res+=shop.price } return res } } }, methods:{
} } </script>
<style> </style>
|
注意:methods与computed 都能够实现计算操作,但是computed的优势在于, computed有缓存,它会把计算好的值做了一层缓存,它会观察对应的值有没有变化,如果有变化则再去清空缓存并计算,这样就提升了程序运行的效率
组件
组件是Vue中的一个重要概念,在vue中,每一个界面都是以组件的形式存在的,而组件中还可以再包含组件
全局组件
如果网页中某一个部分在多个场景中经常使用,我们就可以将这个部分抽出来作为一个组件进行复用。
例如我们这里有两个页面,里面的内容分别对应网页的头部和底部。如果在多个界面都使用到了这两个部分,我们就可以把它注册成全局组件,这样就可以在所有界面都使用它
- 首先在main.js 中引入文件,
import 变量名 from 文件位置
- 随后使用 Vue的 compoonet 注册组件 ,第一个值 就是注册的全局组件的名字,我们可以在其他界面通过这个名字来调用这个组件,第二个值就是绑定对应的组件,通过上面的import 定义的名字进行绑定
- 最后就可以在任意地方来调用这个组件了
父子组件通信
- 父组件向子组件传值:
以上面的header 为例,再创建一个组件 Header_child 作为它的子组件(注册组件的步骤省略)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| <template> <div> {{Smessage}} </div> </template>
<script> name:'Header_child' export default{ data() { return{ Smessage:this.message } }, // props 里的数据只做展示用,如需在页面上进行交互修改则需要绑定到data props:{ //在props 中声明父组件传进来的数据 message:{ // 定义属性,父组件向子组件的message传值 type: String, //声明传进来的数据类型 default: 'ss' //声明默认值 } }, } </script>
<style> </style>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| <template> <div> <HeaderC :message="saySomething"></HeaderC> <!-- 使用v-bind 指令,将data中的数据绑定给子组件的 message 属性--> </div> </template>
<script> export default { name: "header", data() { return { saySomething: "Welcome to Your Vue.js App" }; }, }; </script>
<style> </style>
|
子组件向父组件传值:
第一种方式 由于父组件传值使用过v-bind 绑定的,之前学习过双向绑定,所以当子组件的数据发生变化时,父组件对应的值也会变化,所以在子组件中修改绑定的值,即可完成传参
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| <template> <div> <input type="text" v-model="Cmessage" /> <button @click="sayOther">确定</button> </div> </template>
<script> name:'Header_child' export default{ data() { return{ Cmessage:'' } }, methods:{ sayOther(){ this.message = this.Cmessage } }, props:{ //在props 中声明父组件传进来的数据 message:{ // 定义属性,父组件向子组件的message传值 type: String, //声明传进来的数据类型 default: 'ss' //声明默认值 } }, } </script>
<style> </style>
|
第二种方式 事件侦听方式 传值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| <template> <div> 接收到的数据:{{this.showMessage}} <input type="text" v-model="Cmessage" /> <button @click="sayOther">确定</button> </div> </template>
<script> name:'Header_child' export default{ data() { return{ showMessage:this.message Cmessage:'' } }, methods:{ sayOther(){ this.$emit("ChildchangeSay",this.Cmessage)// this.$emit是为了触发父组件的ChildchangeSay事件,Cmessage是子组件传递的数据 } }, props:{ message:{ type: String, default: 'ss' } }, } </script>
<style> </style>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| <template> <div> <HeaderC :message="saySomething" @ChildchangeSay="FatherGetSay"></HeaderC> </div> </template>
<script> export default { name: "header", data() { return { saySomething: "Welcome to Your Vue.js App" }; }, methods:{ FatherGetSay(val){ this.saySomething = val } } }; </script>
<style> </style>
|
- 父组件访问子组件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| <template> <div> <Button @click="btnclick">点击调用子组件方法</Button> <HeaderA ref="child"/> <!-- 3.设置ref属性 --> </div> </template>
<script> import HeaderA from '../Header_child.vue' //1.导入子组件 export default { name: "header", components:{//2. 挂载至当前组件下 HeaderA }, data() { return { saySomething: "Welcome to Your Vue.js App" }; }, methods:{ btnclick() { console.log(this.$refs.child) }, } }; </script>
<style> </style>
|
1 2 3 4 5 6 7 8 9 10 11 12 13
| <template> <div>我是子组件</div> </template> <script> export default { name:"Header_child", methods: { sing() { console.log('我是子组件的方法'); }, }, }; </script>
|
使用 this.$refs.属性名 即可访问子组件
- 子组件访问父组件,与上面相同 使用 $parent 属性访问
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| <template> <div> <h1>我是子组件</h1> <button @click="btnclick">点击调用父组件方法</button> </div> </template>
<script> name:'Header_child' export default{ data() { return{
} }, methods:{ btnclick() { console.log(this.$parent) }, sayHello(){ console.log('abcd') }, }, } </script>
<style> </style>
|
插槽
插槽类似于拼图,可以在一个较大的模板中,定义一个可活动区域插槽,当这个区域想要更换内容时,往里面插入不同的组件即可,
1 2 3 4 5
| <template> <slot name="left">左边</slot> <slot name="center">中间</slot> <slot name="right">右边</slot> </template>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| <template> <div id="all"> <com> <template> <span v-slot="left">啊啊</span> <span v-slot="cebter">zz</span> <span v-slot="right">啊啊</span> </template> </com> </div> </template>
<script>
import com from './test.vue' export default { name: "Header", components:{ com }
</script>
|
当父组件想要改变插槽中的内容或数据时,可以通过属性传参
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <template> <slot :data="list"> //定义data 属性,并赋值list <span v-for="item in list">{{item}}</span> </slot> </template>
<script> export default{ name:'test', data() { return{ list:['张三','李四','王五'] } } } </script>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| <template> <div id="all"> <com> <template slot-scope="slot"> <!-- 通过定义的 slot 来引用插槽对象,再通过插槽对象即可访问插槽中的数据 --> <button v-for="item in slot.data"></button> </template> </com> </div> </template>
<script> import com from './test.vue' export default { name: "Header", components:{ com } }; </script>
|