VueJs + Laravel - 类似按钮组件

Posted

技术标签:

【中文标题】VueJs + Laravel - 类似按钮组件【英文标题】:VueJs + Laravel - like button component 【发布时间】:2019-04-03 23:53:52 【问题描述】:

我正在尝试对 VueJS 有一个很好的理解,并且我将它与 Laravel 5.7 一起用于个人项目,但我无法完全弄清楚如何做一个可能很简单的任务“喜欢”按钮\图标。

所以,情况就是这样,我有一个页面,显示来自我的数据库的各种帖子,并且在每个帖子的底部我想要一个“like toogle”按钮,我用一个图标,后面跟着喜欢的数量那个帖子;一开始这个按钮会包含从对应的数据库表中检索到的数据,但是如果你点击它会增加一个显示的数字并在数据库中插入一个新的like。

我将“like”图标作为一个组件:

<section class="bottomInfo">
 <p>
 <likes now=" $article->likes "></likes> 
 <span class="spacer"></span>
 <span class="entypo-chat"> 
   $article->comments 
 </p>
</section> <!-- end .bottomInfo -->

正如你所看到的,有一个&lt;likes&gt;,我在其中添加了一个道具now,据我到目前为止对组件的理解,这样我可以从我的数据库中插入数据作为起始值(@ 987654324@ 包含 db 行值),问题是,我不知道在哪里\如何在我的应用程序中保留该值,我还将在其中使用 axios 来增加喜欢。

这是组件:

<template>    
    <span class="entypo-heart">  now </span>    
</template>

<script>
    export default 
        props: ['now'],
        data() 
            return 
                like: this.now
            
        ,
        mounted() 
            console.log('Component mounted.');
            
    
</script>

我试图做的(我不知道它是否正确)是将now 的值传递给名为like 的属性内的data 函数,所以,如果我理解正确,那变量 like 现在是我的主 Vue 实例中属性的一部分,就是这个

const app = new Vue(
    el: '#main',
    mounted () 
        console.log("The value of 'like' property is " + this.like)

    ,
    methods: 
        toggleLike: function() 

         //end toggleLike
    
);

mounted 函数应该打印该属性值,但我得到了

The value of 'like' property is undefined

为什么?这是它的工作原理吗?我怎样才能做到这一点,以便我可以获得该值并在单击时更新它,然后向我的 API 发出请求? (我的意思是,我不是在问如何做这些单一的任务,只是在哪里\如何在这种情况下实现它)。我的组件逻辑正确吗?

【问题讨论】:

【参考方案1】:

可能多一点冗长不会有坏处:

props: 
  now: 
    type: Number,
    required: true
  

不要使用data 函数,而是使用computed 属性:

computed: 
  likes: 
    get: function() 
      return this.now
    
  

但是,问题来了。

如果您需要在用户点赞后更改点赞数,则必须更新this.now。但你不能!它是一种属性,而属性是纯粹的。 Vue会抱怨mutating a property

所以现在你可以引入data variable 来确定用户是否点击了那个赞按钮:

data() 
  return 
    liked: 0
  

现在我们可以更新我们的计算属性:

likes: 
  get: function() 
    return this.now + this.liked
  

但是,我们喜欢什么?现在我们需要另一个属性:

props: 
  id: 
    type: Number,
    required: true
  ,
  now: 
    type: Number,
    required: true
  

我们添加一个方法:

methods: 
  add: function() 
    //axios?
    axios.post(`/api/articles/$this.id/like`)
      .then (response => 
        // now we can update our `liked` proper

        this.liked = 1
      ).catch(error => 
        // handle errors if you need to
      )
  

而且,让我们确保点击我们的心会触发该事件:

<span class="entypo-heart" @click="add">  now </span> 

最后,我们的likes 组件需要我们文章中的id 属性:

<likes now=" $article->likes " id=" $article->id "></likes> 

一切就绪;你现在是个巫师了,哈利。

编辑

应该注意的是,用户将永远能够一遍又一遍地喜欢这个。因此,您需要在click 函数中进行一些检查以确定他们是否喜欢它。您还需要一个新的propcomputed property 来确定它是否已被点赞。这还不是全部。

【讨论】:

我假设您编写的所有内容都进入了组件脚本,而不是主实例,否则我的错。无论如何,我尝试给 prop 赋值 5 :&lt;likes :now="5"&gt;&lt;/likes&gt; (我放了 :now 因为他认为我给出的字符串包含 5 而不是数字),但我仍然得到日志 The value of 'likes' property is undefined 。我复制了你给我的所有东西,不多不少,主 Vue 实例中唯一的东西是返回该错误的 console.log(现在我没有放 data() 部分,因为我想看看我是否可以打印从组件传递的属性值)。 你可以在这里看到代码codesandbox.io/s/j1n5w345y9,正如你在控制台中看到的,这两个属性返回 undefined @K3nzie 从主 Vue 实例中删除 mounted () console.log("The value of 'like' property is " + this.like) , 但是......这就是我的问题的重点,我想在我的主实例中查看这些值(另外,因为我需要使用 axios 并且它不会让我在组件中使用它),所以您告诉我您编写的所有代码都在组件脚本标签中?我认为您应该将逻辑放在主实例 new Vue(... 中,我的意思是,我将组件视为应该只是主应用程序的“扩展”(考虑到如果您不将其放在 el: '#app'范围它甚至不加载)。 @K3nzie 如果我们在处理 SPA,您所说的某些方法实际上会有所不同。但是您在这里处理的是一种集成方法。如果你想停止FOUC,那么你应该考虑使用v-cloak directive。数据管理应该在组件中进行,而不是在主 Vue 实例上。如果您担心泄露 id,请使用 sluguuid 并在 Laravel 中更新您的 route model binding 以接受这些并解决 DI。

以上是关于VueJs + Laravel - 类似按钮组件的主要内容,如果未能解决你的问题,请参考以下文章

Vuejs - 单击组件​​中的按钮时未触发事件

单击laravel vuejs中的按钮后如何隐藏bootstrap-vue模式

Laravel 和 VueJS:在 Blade 中调用 VueJS 方法

CSRF 令牌不匹配错误,Laravel 5.3/VueJS2

从 VueJS 的父组件中引用子组件的索引

vuejs 和 laravel-vuejs 看不到组件的变化