《Vue设计与实现》第四章 第6节 计算属性

1.《Vue设计与实现》computed计算属性

let computed = (getter) => {
    let effectFn = effect(getter, {
        lazy: true, // 这个参数就表示,副作用函数(getter)先不执行,而是返回给effectFn变量
    })
    // 我们需要在返回一个对象,让这个对象在访问value属性时,才会计算对应的值
    let obj = {
      get value() {
        return effectFn(); // 当我们在访问value属性时,才会去执行这个函数
      }
    }
    return obj;
}

effect修改的地方,这里只是写了,lazy参数具体干什么用,没有把完整的effect实现写出来

let effect = (fn, options) => {
   // 我们将副作用函数包裹一层
   let effectFn = () => {
     activeEffect = effectFn;
     const res = fn();
     return res;
   }
   effectFn.deps = [];
   effectFn.options = options;
   if (options.lazy) {
      return effectFn; // 我们就先不执行这个副作用函数
   } else {
     effectFn(); // 否则我们就直接调用了这个函数
   }
}

但是上面的计算属性,函数存在一下问题的。

那就是,当关联的响应式数据,没有发生变化时,是不应该去重新执行计算的,而是只有当关联的数据发生改变时才会重新执行计算返回。

解决方案:

  1. 我们用一个变量表示是否需要重新执行计算 dirty
  2. 因为响应式数据一旦发生了改变,就会自动触发对应的副作用函数的重新执行
  3. 那么我需要在这个副作用函数执行完毕之后将 dirty 转换为 true就可以了

说白了,我们就是需要去监听也好,当与计算属性相关联的响应式数据发送改变,就改变dirty变量

修改我们的computed里的effect调用时,传递scheduler表示调度执行,说白了就是将最终的执行权力交给用户自己(我自己)

修改computed

let computed = (getter) => {
   let dirty = true, value;
   // dirty 表示是否需要重新计算执行
   // value 是表示计算结果
   let effectFn = effect(getter, {
       lazy: true,
       scheduler(fn){
           fn();
           // 当我们的副作用执行完毕之后,就需要将
           dirty = true; // 表示需要重新执行 
       }
   })
   let obj = {
      get value() {
      
        if (dirty) {
          // 只有当dirty为true时,才会重新执行
          value = effectFn();
          dirty = false;
          // 当执行了之后,就需要将dirty改为false,表示不需要重新执行
        }
        return value;
      }
   
   }
}

不好意思,这个实现还是存在一个小问题

那就是在 effect 中使用了计算属性,但是修改了响应式数据之后没有将副作用函数重新执行
什么意思呢?

let dataForm = computed(() => obj.name + obj.sex));

// 我们在effect中使用这个计算属性
effect(() => {
    console.log('此时没有重新执行');
    dataForm.value;
})
obj.name = 99;

当我们修改了,obj.name之后,effect参数没有重新执行。

仔细思考我们会发现,这是一个典型的effect嵌套问题

因为:

  1. obj这个响应式数据,的修改是会触发computed里面的effect副作用函数的执行
  2. 而外面的effect又没有对应的响应式数据与之关联

现在我们就需要手动触发,建立依赖关系,也需要手动触发响应

let computed = (getter) => {
   let dirty = true, value;
   // dirty 表示是否需要重新计算执行
   // value 是表示计算结果
   let effectFn = effect(getter, {
       lazy: true,
       scheduler(fn){
           fn();
           // 当我们的副作用执行完毕之后,就需要将
           dirty = true; // 表示需要重新执行 
           trigger(obj, 'value'); // 手动触发
       }
   })
   let obj = {
      get value() {
      
        if (dirty) {
          // 只有当dirty为true时,才会重新执行
          value = effectFn();
          dirty = false;
          // 当执行了之后,就需要将dirty改为false,表示不需要重新执行
        }
        track(obj, 'value'); // 其实这个value,是很随便的一个属性,意思是啥都行
        return value;
      }
   
   }
}

目的就是,让当前的的副作用函数,也就是外面的effect中的父作用函数,与obj响应式数据建立联系,

这里需要解决,嵌套effect时的副作用函数覆盖的问题因为此时的effect是没有写完整的,完整之后activeEffect变量就是最外层的副作用函数了。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: Vue图片列表实现轮播的步骤如下: 1. 首先,在Vue的模板中,创建一个div容器,用于显示轮播图。可以设置容器的宽度和高度,根据需要进行调整。 2. 在Vue的data中定义一个数组,用于存储轮播图的图片地址。可以在数组中添加多个图片地址,以实现多张图片的轮播。 3. 在Vue的methods中,编写一个方法,用于切换图片。可以使用Vue的响应式数据来实现切换图片的效果。在该方法中,通过改变存储图片地址的数组的索引值来切换图片。 4. 可以在Vue的mounted钩子函数中,调用切换图片的方法,并使用定时器,设置时间间隔,实现图片的自动切换。 5. 在Vue的模板中,使用v-for指令遍历图片数组,将每张图片显示在div容器中。可以使用img标签来显示图片,通过设置图片的src属性来指定图片地址。 6. 可以为轮播图添加前后切换按钮,实现手动切换图片的功能。在Vue的methods中编写前后切换图片的方法,并在模板中绑定到按钮上,通过点击按钮来切换图片。 以上就是使用Vue实现图片列表轮播的简单步骤。具体的实现可以根据项目需求进行调整和扩展。 ### 回答2: Vue的图片列表实现轮播可以通过以下几个步骤来实现: 1. 首先,我们需要创建一个Vue实例作为整个应用的入口点,可以在HTML文件中引入Vue库,并在script标签中创建Vue实例。 2. 在Vue实例的data选项中定义一个数组来存储需要展示的图片列表,每个图片对象包含图片的URL以及其他相关属性。 3. 在HTML模板中使用v-for指令来循环遍历图片数组,创建多个图片的DOM元素。 4. 使用CSS样式设置图片的布局和样式,并使用v-bind指令将图片的URL绑定到对应的img标签的src属性上。 5. 使用Vue的computed属性来计算当前图片的索引值,并设置一个定时器来定时改变当前图片的索引,从而实现轮播效果。 6. 在计算属性中使用三元表达式来判断当前图片的索引是否超出图片数组的边界,如果超出,则将索引重置为0。 7. 在HTML模板中使用v-bind:class指令来动态设置当前图片的样式,可以在CSS中定义一个active类来添加特殊样式。 8. 在Vue实例的mounted生命周期钩子中启动定时器,以便在Vue实例加载完成后立即开始轮播。 通过以上步骤,我们可以实现一个简单的图片列表轮播效果,当页面加载完毕时,图片会自动进行轮播,展示不同的图片。可以根据需求调整图片切换的速度、动画效果等。 ### 回答3: 在Vue实现图片列表的轮播可以通过以下步骤进行: 1. 在Vue组件中引入所需的图片列表数据,可以通过使用数组或对象的形式进行存储,每个元素包括图片的路径、标题等信息。 2. 创建一个Vue的数据属性来存储当前轮播图片的索引值,例如`currentIndex`,初始化为0。 3. 在Vue模板中,使用v-for指令遍历图片列表数据,将每个图片以适当的方式展示在页面中。 4. 使用CSS样式设置图片外部容器的宽度和高度,并将样式的overflow属性设置为隐藏,以确保只显示容器内的一张图片。 5. 使用Vue计算属性,根据`currentIndex`值获取当前展示的图片信息。 6. 使用Vue的定时器方法,例如`setInterval`,在指定的时间间隔内更新`currentIndex`的值,以实现图片的自动轮播效果。 7. 在Vue模板中,使用绑定事件的方式为左右箭头按钮设置点击事件,通过改变`currentIndex`的值来切换上一张或下一张图片。 8. 可以根据需求,为轮播图添加一些过渡效果,例如淡入淡出或滑动效果,使用Vue的过渡动画组件来实现。 9. 如果希望实现无限循环的轮播效果,可以在图片列表的首尾分别添加与最后一张和第一张图片相同的内容,并在切换到首尾图片时,通过动画效果实现无缝切换。 通过上述步骤,可以在Vue实现一个简单的图片列表轮播效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值