Vue Angular React - sgml/signature GitHub Wiki

Patterns

  • Multiple Child components: slots

  • Plugins

  • Filters

  • Interpolation defaults {{ foo || true }}

  • Transclusion (Render Slots)

  • NoSuchMethod

  • Getters/Setters (Object.defineProperty)

  • Semantic HTML

  • Caching (CacheFactory/computed)

  • Flux

Anti-Patterns

  • Pub/Sub component APIs: $root, $watch, $emit, $parent, $once, $on, $off

  • Inlining: x-template

  • Force Update: $forceUpdate

MVC

// store/index.js

import Vue from 'vue';
import Vuex from 'vuex';
import { GoogleSpreadsheet } from 'google-spreadsheet'; // Import the google-spreadsheet module

Vue.use(Vuex);

const store = new Vuex.Store({
  state: {
    sheetData: [], // Initialize an empty array to store the fetched data
  },
  mutations: {
    SET_SHEET_DATA(state, data) {
      state.sheetData = data;
    },
  },
  actions: {
    async fetchSheetData({ commit }) {
      try {
        const doc = new GoogleSpreadsheet('<your-sheet-ID>'); // Replace with your actual Google Sheet ID
        await doc.useServiceAccountAuth({
          client_email: process.env.GOOGLE_SERVICE_ACCOUNT_EMAIL,
          private_key: process.env.GOOGLE_PRIVATE_KEY.replace(/\\n/g, '\n'), // Handle line breaks in the private key
          scopes: ['https://www.googleapis.com/auth/spreadsheets'],
        });
        await doc.loadInfo(); // Load document properties and worksheets
        const sheet = doc.sheetsByTitle['foo']; // Replace 'foo' with your sheet name
        const rows = await sheet.getRows(); // Read rows from the sheet
        commit('SET_SHEET_DATA', rows);
      } catch (error) {
        console.error('Error fetching sheet data:', error);
      }
    },
  },
});

export default store;
<!-- YourComponent.vue -->

<template>
  <div>
    <b-table :data="sheetData">
      <template slot-scope="props">
        <b-table-column label="Name" field="name"></b-table-column>
        <b-table-column label="Email" field="email"></b-table-column>
        <!-- Add more columns as needed -->
      </template>
    </b-table>
  </div>
</template>

<script>
import { mapState, mapActions } from 'vuex';

export default {
  computed: {
    ...mapState(['sheetData']),
  },
  created() {
    this.fetchSheetData(); // Call the action to fetch data when the component is created
  },
  methods: {
    ...mapActions(['fetchSheetData']),
  },
};
</script>
# Decoupling
<template>
  <div>
    <ul>
      <li v-for="user in $store.state.users" :key="user.id">{{ user.name }}</li>
    </ul>
    <button @click="addNewUser">Add User</button>
  </div>
</template>

<script>
export default {
  methods: {
    addNewUser() {
      const newUser = { id: 1, name: 'John Doe', email: '[email protected]' };
      this.$store.commit('addUsers', newUser);
    },
  },
};
</script>

Mocking

import Vue from 'vue';
import { mount } from '@vue/test-utils';
import HelloWorld from './HelloWorld.vue';

Vue.config.silent = true;
Vue.config.ignoredElements = ['nuxt-link'];

Vue.config.stubs['nuxt-link'] = {
  template: '<a><slot></slot></a>',
};

Vue.config.stubs['no-ssr'] = {
  template: '<span><slot></slot></span>',
};

test('renders hello world', () => {
  const wrapper = mount(HelloWorld);
  expect(wrapper.text()).toBe('Hello World');
});

/*
    Vue.config.silent: Silences console logs during tests.

    Vue.config.ignoredElements: Ignores Nuxt-specific components like nuxt-link.

    Vue.config.stubs: Mocks Nuxt components with simple templates.
*/

Store as a source of truth (PouchDB as the API)

import Vue from 'vue';
import App from './App.vue';
import store from './store'; // Adjust the path based on your project structure

new Vue({
  render: (h) => h(App),
  store, // Attach the store to Vue
}).$mount('#app');

Mock data

{
  "channel": {
    "title": "W3C Blog",
    "link": "https://www.w3.org/blog/",
    "description": "W3C's official blog",
    "items": [
      {
        "title": "Post Title 1",
        "link": "https://www.w3.org/blog/post1",
        "description": "Foo"
      },
      {
        "title": "Post Title 2",
        "link": "https://www.w3.org/blog/post2",
        "description": "Bar"
      }
    ]
  }
}

Object.defineProperty as a getter/setter pattern

<template>
    <div>
        <p>First Name: {{ firstName }}</p>
        <p>Last Name: {{ lastName }}</p>
        <p>Full Name: {{ fullName }}</p>
    </div>
</template>

<script>
export default {
    data() {
        return {
            firstName: 'John',
            lastName: 'Doe',
        };
    },
    computed: {
        fullName: {
            get() {
                return `${this.firstName} ${this.lastName}`;
            },
            set(value) {
                // You can handle setting the full name here if needed
                const [first, last] = value.split(' ');
                this.firstName = first;
                this.lastName = last;
            },
        },
    },
};
</script>

React Native Issues

performance_issues:
  - title: "Performance Issues with React Native Bridgeless Architecture"
    github_issue: "https://github.com/facebook/react-native/issues/47490"
    description: "This issue discusses performance problems introduced by the bridgeless architecture in React Native 0.74 and later versions, particularly for apps with complex logic and high demands for UI responsiveness."

  - title: "App performance degraded when React Native version updated"
    github_issue: "https://github.com/facebook/react-native/issues/36123"
    description: "This issue highlights performance degradation experienced by users when upgrading from React Native 0.68.0 to 0.71.2, including navigation and UI interaction issues."

  - title: "React Native Performance Profiling"
    github_issue: "https://github.com/facebook/react-native/issues/15371"
    description: "This issue discusses the loss of important performance profiling tools with the introduction of React 16 and React Native 0.45.1, and the challenges in profiling performance bottlenecks."

References

⚠️ **GitHub.com Fallback** ⚠️