获取数据
通过Axios请求API,调用GET的方法。
async initCarList(){
// 调用GET方法,请求列表数据
// await 等待方下列请求获取完毕
const {data:res}= await axios.get('https://www.escook.cn/api/cart')
console.log(res)
}
async是一种异步函数,就算这个函数没有执行完毕,也不会影响整个程序的运行。
await可以看作一个等待,当完全获取完这个API的数据,才会继续执行这个函数里面的下一步。
保存数据
当我们请求完数据以后,那当然要把数据保存到一个容器里。
用一个空的数组保存列表数据
data(){
return{
//空数组保存列表数据
list:[]
}
调用请求数据函数
通过生命周期函数,来调用这个initCarList()的函数。这里要注意,生命周期函数是和methods同级别,不可以写到methods。
created() {
//组件创建完成后,调用方法
this.initCarList()
}
数据展示
请求的数据列表中有很多以数组形式存在的数据,通过遍历的方法将每一个数组都显示到页面。
这里要绑定Key,相当于每一条数据都有他们自己独一无二的铭牌,比如每个数组中id
<Goods v-for="item in datalist" :key="item.id"></Goods>
渲染标题
商品写在子组件中,要将父组件的数值传递给子组件,使用props自定义属性。
父组件将list的值给props,子组件使用props。
通过下面这个逻辑,要渲染列表其他的数据也是一样的方法。
先设置props,再赋值
props:{
title:{
default:'',
type:String
}
<Goods v-for="item in datalist" :key="item.id" :title="item.goods_name"></Goods>
如果一个一个设置props属性可能会很麻烦,这里我们会发现, 获取的这个数据它是个对象类型
在prop可以写成这样,一整个就是一个对象属性,父组件将所有的数据传到goods里面,再去调用。那么使用的时候可以直接
<span class="goods-price">¥{{goods.goods_price}}</span>
props:{
goods:{
default:{},
type:object
}
注意:这里一定要用到v-bind不然,显示的就是一个静态的字符串。
状态切换
子组件向父组件传值
this.$emit("function",param);function()可以被调用
比如:@function=“newState”
关于调整状态的这个思路:
通过控制台,发现每个对象的属性中都有state属性,利用这个属性完成对状态的切换。
这个打印出来的是API获取的,但实际页面上的值是props给的,所以当前页面上的每个对象都是没有ID的,先为他们绑定id属性
id:{
//如果使用DEFALUT默认值,没有意义,就像每个人必须要有一个身份证一样
//requre为true为必须选择
required:true,
type:Number
当身份给他们上完以后,就要监听复选框了,复选框的值发生改动,接着就是id所对应的state数值改变。
现在监听复选框状态,一旦复选框发生改变,就会触发函数stateChange.
<input type="checkbox" class="custom-control-input" id="cb1" :checked="state" @change="stateChange"/>
子组件向父组件传值
methods:{
// 复选框状态发生变化就会处理函数
stateChange(e) {
//获取事件触发的checked值
const newState = e.target.checked
// 触发自定义事件
this.$emit('state-change', { id: this.id, value: newState })
}
}
<Goods v-for="item in datalist" :key="item.id" :title="item.goods_name" :price="item.goods_price"
:picture="item.goods_img" :state="item.goods_state" :id="item.id" @state-change="getNewState"></Goods>
对datalist遍历,找到和复选框状态改变的id相同的id,赋值,就完成转换了
etNewState(e) {
this.datalist.some(item => {
if (item.id === e.id) {
item.goods_state = e.value
// 终止后续的循环
return true
}
})
}
但是在实现全选的复选框的过程中,出现了一些问题, 每一个函数体都检查了没有错误,结果竟然是调用$emit函数的时候名字写错了,大无语
接下来做全选框,逻辑思路都是大同小异。
这次会多一个computed的计算属性,只要它依赖的属性,也就是内部的属性发生变动,计算属性就会重新执行。
fullState(){
return this.datalist.every(item=>item.goods_state)
}
every遍历每个goods_state,如果每个goods_state的值为true,最终就会返回true,否则为false,这里的计算属性就是监听true 和false之间的切换,将这里返回的值父传子。完成了逆向的商品都被选中,全选框为true。
现在,要正向实现,如果全选框为false,商品都解除true
监听复选框值的变动,触发函数体,实现子传父亲
<input type="checkbox" class="custom-control-input" id="cbFull" :checked="isFull" @change="fullChange" />
methods:{
fullChange(e){
console.log(e.target.checked)
this.$emit('full-change',e.target.checked)
}
}
然后在父组件中遍历修改每个goods
<Footer :is-full="fullState" @full-change="getFullState"></Footer>
getFullState(val) {
console.log(val)
this.datalist.forEach(item => (item.goods_state = val))
}
ok,功能实现。