首页 > 解决方案 > 使用 vue (Laravel) 完成简单的任务

问题描述

我最近开始学习 vue.js(来自 angular 2+),我看了一些教程,一切似乎都很顺利。

在完成教程后,我一如既往地为自己创建了一个小应用程序,以确保我知道自己在做什么。但我似乎真的很纠结于 Vue。

到目前为止,该应用程序非常简单。一个用户发布了一个故事,这个故事有评论......就这么简单

我到了希望用户能够在那里编辑评论的地步,但似乎我无法弄清楚如何做到这一点。我希望这样当用户单击编辑按钮时,评论会更改为文本区域或某种输入。

此时我在项目中完全没有使用vue。所有页面都使用刀片呈现。

我试图弄清楚你打算如何使用它?所以我有以下问题

  1. 您是否打算使用多个 vue 组件,在刀片中循环并在每次迭代时创建一个?

    <div id="app">
        @foreach($comments as $comment)
            <comment {Stuff passed in}></comment>
        @endforeach
    </div>
    
  2. 您是否打算拥有一个从 api 获取数据并将它们循环到 vue 组件中的 vue“应用程序”?

        const comments = new Vue({
            el: '#comments#'
        })
    
  3. 由于所有网站都是一个多页应用程序(不想走 SPA 路线),假设我现在有一个产品页面,该产品有一个属性列表(与评论几乎相同)。我要创建另一个 vue 应用程序吗?

    const comments = new Vue({
        el: '#comments',
    });
    
    
    const productThings = new Vue({
        el: '#productThings'
    })
    
    1. 如果我想在由 vue 控制的页面上划分部分(让我们说评论部分和另一个交互部分)这是否必须是 2 个 vue“应用程序”,就像上面的代码示例一样,一个是“评论”,一个是“ somethingelse”或者整个页面必须是一个大的 vue 组件。

      // Comment loop, How ever this gets handled with vue 
      // Some other content 
      // Another place I need it to be interactive````
      

仅仅为了完成简单的任务,这似乎非常复杂,而且似乎很快就会失控(我只能想象在 6 个月后回到这个状态并试图弄清楚发生了什么)。

你可以看到我对这一切有多么困惑,我读得越多,我似乎就越困惑。

标签: javascriptphplaravelvue.jslaravel-blade

解决方案


Vue 用于创建成熟的 SPA Web 应用程序,但只能作为插件使用,无需构建过程,用于更简单的用例。通常你会集成 Vue Router 来创建多页面体验,但你也可以只定义单个组件并将它们安装在一个元素上。在您的情况下,通过混合 PHP 和 Vue,我建议您选择没有构建过程和插入组件的方式。

Vue 是一个带有静态模板的 JavaScript 框架。所以,你不应该生成动态模板,然后将它们传递给 Vue,而是定义静态模板,然后只将数据传递给 Vue。例如,您可以通过 Ajax 以 JSON 格式获取数据,然后处理该数据以例如呈现评论列表。

如果您使用 Vue 作为插件而不使用路由,则需要在各自的页面上安装两个单独的 Vue 实例。您当然可以重用这些组件的一部分。请记住,您不能在这些实例之间共享数据(使用 SPA 的好处之一)。但是,您可以通过 LocalStorage/SessionStorage/IndexedDB 共享数据。

访问数据的一种常见方法是通过 REST API(通过 Ajax/fetch)。您将在 HTTP REST 接口后面以适当的格式(通常是 JSON)提供数据。然后,Vue 获取数据(另请参阅axios以轻松获取数据),然后使用它来构建组件。另一种方法(不太好)是仅使用您的服务器端编程语言呈现数据并将其放入 JavaScript 变量中,这样您就可以在运行时访问数据。

这是一个基本的例子。请记住,从属性绑定值是一种反模式,因此我没有以双向方式绑定注释文本。我还对评论数据进行了硬编码,并且不从远程获取它。

Vue.config.devtools = false;
Vue.config.productionTip = false;

Vue.component('comment', {
  data () {
    return {
      commentAsInput: false
    };
  },
  props: {
    commentObject: {
      type: Object,
      required: true
    }
  },
  template: `<div>
    <a href="#" @click="commentAsInput = !commentAsInput" v-if="!commentAsInput">
      {{ commentObject.text }}
    </a>
    <textarea :value="commentObject.text" v-if="commentAsInput" />
  </div>`
});

Vue.component('comments', {
  data () {
    return {
      comments: [{ id: 124, text: 'fkgnsdklgnl' }, { id: 2135325, text: 'nlekng345gn' }]
    }
  },
  template: `<div>
    <h1>Comments</h1>
    <div v-for="comment in comments" :key="comment.id">
      <comment :comment-object="comment" />
    </div>
  </div>`
});

new Vue({
  el: '#app',
  template: `<comments />`
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app"></div>


推荐阅读