【问题标题】:Passing data from custom directive to component将数据从自定义指令传递到组件
【发布时间】:2021-10-02 09:27:27
【问题描述】:

我有一个指令从元素绑定中获取 URL,然后使用该 URL 执行 axios GET 请求。

我循环返回的数据,然后我希望能够将返回的数据连同我对它的更改一起存储在组件 data() 对象中 - 新闻,但是我不确定这是否可能/如何实现。

directives: {
    init: {
        mounted(el, binding) {
            el.id = binding.value
            Promise
            .all([axios.get(el.id)])
            .then((response) => {
                let data = response[0].data;
                for (var i in data) {
                    data[i].date = new Date(data[i].date);
                }
            });
        },
    }
},

我希望存储在里面的组件数据:

data() {
    return {
        news: '',
    }
},   

还有模板:

<div class="section news" ref=“myid” v-init:url="'https://www.myurl.com'" id="newsUrl">

【问题讨论】:

  • 这不是指令的目的。指令用于元素上的 DOM 操作(例如设置焦点、颜色等),而不是您尝试应用的功能。要么为自己创建一个mixin,要么找到另一种重用逻辑的方法(例如,如果你正在使用组合api,你可以创建一个纯函数来处理你的逻辑,然后可以将该函数导入任何你需要的地方以进行重用)。但!如果您坚持这样做,您可以从元素发出一个事件并使用处理程序来存储从事件发出的数据。
  • 我明白@Braks 感谢您的回复。在这种情况下,url 是动态生成的,并从我的任何 vue 代码外部添加到 HTML 中。鉴于此,我认为指令是从 html 获取此值的唯一方法?
  • 您究竟是如何生成和添加该 URL 的?
  • 在我的代码中,URL 就像我在这个例子中展示的一样。我的代码被添加到内容管理系统中,并带有一些额外的 javascript,当代码从那里运行时,它允许我从 CMS 中提取数据。我根据用户访问的页面使用从 CMS 中提取的类别和标签对 URL 进行简单的字符串替换。
  • 好吧,如果你能找到一个解决方案将它直接传递到你的应用程序中,请使用它。但是现在,如果您想使用您已经使用过的指令解决方案,只需从您正在使用该指令的元素发出一个事件。我做了同样的事情here。在我的示例中,该指令可用于标准 dom 元素(如
    )或 vue 组件。根据您使用指令的目的,您发出事件的方式会有所不同。

标签: vue.js vuejs3 vue-directives


【解决方案1】:

我同意该指令似乎是错误的处理方式。

但是,技术上可以通过binding.instance 从指令中访问 Vue 组件,因此您可以通过以下方式设置组件的 news 属性:

binding.instance.news = response.data

但您不需要Promise.all,因为只有一个URL,所以只需要一个Promise。你可以直接使用axios.get()

//Promise.all([axios.get(el.id)]).then(([response]) => {/*...*/})
axios.get(el.id).then(response => {/*...*/})

demo

【讨论】:

    【解决方案2】:

    这是我实现我想要的结果的方式,它似乎工作正常,但这不是我发布的问题的直接答案。但是它可以工作,因此如果有人遇到与我类似的问题,这可能是您可以解决的方法:

    在 HTML 中分配一个 ref:

    <div ref="myDiv" id="https://www.myurl.com">
    

    在组件挂载方法上执行我的请求,并将响应数据分配给我的组件数据对象(this.news):

    mounted() {
            Promise
            .resolve(axios.get(this.$refs.myDiv.id))
            .then((response) => (
                this.news = response.data
            ))
        },
    

    然后回到 HTML,我可以像这样循环数据:

    <div v-for="(item, index) in news" :key="index">
       <h2>{{item.title}}</h2>
       <p>{{item.description}}</p>
    </div>
    

    【讨论】:

      猜你喜欢
      • 2015-07-05
      • 2021-10-30
      • 1970-01-01
      • 2018-06-14
      • 2018-08-08
      • 2019-01-09
      • 1970-01-01
      • 2015-04-12
      • 1970-01-01
      相关资源
      最近更新 更多