【问题标题】:How do I change the CSS of an element based on returned data from Firebase?如何根据 Firebase 返回的数据更改元素的 CSS?
【发布时间】:2021-01-12 04:50:48
【问题描述】:

我正在开发一个使用 vanilla JS、Vue js 和 Firebase 的投票应用程序。我快完成了,但我找不到一种方法让用户投票时投票按钮有不同的颜色(就像 YouTube 的喜欢和不喜欢按钮一样),所以如果用户离开并再次回来,他们投票的东西/downvoted 保持颜色。

这是我目前的代码...

index.js(云函数):

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();


exports.newUserSignup = functions.auth.user().onCreate((user)=> {
   return admin.firestore().collection('users').doc(user.uid).set({
        upVotedOn: [],
        downVotedOn: []
    })
});

exports.addRequest = functions.https.onCall((data, context) => {
    return admin.firestore().collection('requests').add({
        text: data.text,
        songN: data.songN,
        upVotes: 0,
        downVotes: 0,
    });
});

exports.upvote = functions.https.onCall(async (data, context) => {
    const user = admin.firestore().collection('users').doc(context.auth.uid);
    const request = admin.firestore().collection('requests').doc(data.id);

    const doc = await user.get();

    if(doc.data().upVotedOn.includes(data.id)) {
        throw new functions.https.HttpsError(
            'failed-precondition', 'You can only upvote a song once'
        );
    }
    await user.update({
        upVotedOn: [...doc.data().upVotedOn, data.id]
    });
    
    return request.update({
        upVotes: admin.firestore.FieldValue.increment(1),
        upColored: true
    });
});

exports.downvote = functions.https.onCall(async (data, context) => {
    const user = admin.firestore().collection('users').doc(context.auth.uid);
    const request = admin.firestore().collection('requests').doc(data.id);

    const doc = await user.get();

    if(doc.data().downVotedOn.includes(data.id)) {
        throw new functions.https.HttpsError(
            'failed-precondition', 'You can only downvote a song once'
        );
    }
    await user.update({
        downVotedOn: [...doc.data().upVotedOn, data.id]
    });
    
    return request.update({
        downVotes: admin.firestore.FieldValue.increment(1),
        downColored: true
    });
});

app.js(前端/vue js代码):

var form = document.querySelector(".form101");
var spotifyInput = document.getElementById("spotifyembd");
var songName = document.getElementById("songname")
var spotifyEmbed = document.getElementById("spotifyEmbed");
var songTitle = document.getElementById("title");
var up = document.getElementById("up");
var down = document.getElementById("down");

var app = new Vue({
    el: '#unitWrapper',
    data: {
        requests: [],
    },
    methods: {
        upV(id){
            const upvote = firebase.functions().httpsCallable("upvote");
            upvote({id: id})
            .catch(err => {
                showNotification();
            });
        },
        downV(id){
            const downvote = firebase.functions().httpsCallable("downvote");
            downvote({id: id})
            .catch(err => {
                showNotification();
            });
        }
    },
    mounted(){
    const ref = firebase.firestore().collection('requests').orderBy('upVotes', 'desc');
    ref.onSnapshot(snapshot => {

    let requests = [];
    snapshot.forEach(doc => {
        requests.push({...doc.data(), id: doc.id})
    });
    this.requests = requests;
  });
}
});

form.addEventListener("submit", (e)=> {
    e.preventDefault();
    var songInput = `https://open.spotify.com/embed/track/${spotifyInput.value}`


    const addRequest = firebase.functions().httpsCallable('addRequest');
    addRequest({
        text: songInput,
        songN: songName.value
    })
    .then(() => {
        form.reset();
    })
});

const notification = document.querySelector('.notification');
const showNotification = () => {
  notification.textContent = "You can only upvote or downvote a song once";
  notification.classList.add('active');
  setTimeout(() => {
    notification.classList.remove('active');
    notification.textContent = '';
  }, 4000);
};

这是一个非常简单的应用程序,我只需要这个功能,这样用户就不会对他们做了什么和没有投票感到困惑,请帮助。

【问题讨论】:

  • Vue 基于 VNode 机制。所以使用 Vue: Style binding 而不是直接操作 Dom 将是正确的方法。否则,您在开发应用程序的过程中必须与各种副作用作斗争。

标签: javascript css firebase vue.js google-cloud-functions


【解决方案1】:

与您的通知接近尾声非常相似,您可以执行以下操作:

var vote_state =(直接从 firebase 或通过 API 风格的无服务器请求获取)

让 item = document.querySelector('item');

常量 setVotedState = () => { item.classList.add(vote-${vote_state});

然后设置投票赞成或反对票的 CSS 样式,例如使用不同的颜色。

【讨论】:

    【解决方案2】:

    使用 Vue,您可以根据您在 vue 实例的数据对象中提供的数据,有条件地在元素上添加样式或类:

    • <div v-bind:class="{ active: isActive }"></div>
    • <div :class="{ active: isActive }"></div>

    • <div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
    • <div :style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>

    它的工作方式与键/值对相同,键是类或 css 规则,值是控制其存在的表达式。

    isActive、activeColor 和 fontSize 或任何您希望将其称为数据对象的属性。

    我建议阅读这篇文章以获得更多知识:https://v3.vuejs.org/guide/class-and-style.html#binding-html-classes

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-17
      • 2015-08-15
      • 2014-11-18
      • 2014-11-10
      • 2020-06-18
      相关资源
      最近更新 更多