Задать вопрос
SkipTyler
@SkipTyler
Junior+ Front-End developer

Vue + SSR | Как прокинуть миксин в конфиг файл?

Всем привет!
Пишу конфиг под ssr

Добавил миксин, для замены title и meta
Объявил её глобально в файле app.js
import headMixin from './util/title'
    Vue.mixin(headMixin);


При первой загрузке страницы, или же при переходе в корень сайта она срабатывает.

Если переходить на другую страницу, то не работает(

Хотел добавить её в конфиг файл entry-client.js в ф-ю router.onReady()

import Vue from 'vue'
    import 'es6-promise/auto'
    import {createApp} from './app'
    import ProgressBar from './components/ProgressBar.vue'
    
    const bar = Vue.prototype.$bar = new Vue(ProgressBar).$mount();
    document.body.appendChild(bar.$el);
    
    Vue.mixin({
      beforeRouteUpdate(to, from, next) {
        const {asyncData} = this.$options;
        if (asyncData) {
          asyncData({
            store: this.$store,
            route: to
          }).then(next).catch(next)
        } else {
          next()
        }
      }
    });
    
    const {app, router, store} = createApp();
    
    if (window.__INITIAL_STATE__) {
      store.replaceState(window.__INITIAL_STATE__)
    }
    
    router.onReady(() => {
    
      router.beforeResolve((to, from, next) => {
        const matched = router.getMatchedComponents(to);
        const prevMatched = router.getMatchedComponents(from);
        let diffed = false;
        const activated = matched.filter((c, i) => {
          return diffed || (diffed = (prevMatched[i] !== c))
        });
        const asyncDataHooks = activated.map(c => c.asyncData).filter(_ => _);
        if (!asyncDataHooks.length) {
          return next()
        }
    
        // TODO Обсудить наличие статусбара
        bar.start();
        Promise.all(asyncDataHooks.map(hook => hook({ store, route: to })))
          .then(() => {
            bar.finish();
            next()
          })
          .catch(next)
      });
    
      app.$mount('#app')
    });


Но не могу понять, как это правильно сделать(

Сам миксин тут

const cleanMetas = () => {
      return new Promise((resolve, reject) => {
        const items = document.head.querySelectorAll('meta');
        for (const i in items) {
          if (typeof items[i] === 'object'
              && ['viewport'].findIndex(val => val === items[i].name) !== 0
              && items[i].name !== '')
            document.head.removeChild(items[i])
        }
        resolve()
      })
    };
    
    const createMeta = (vm, name, ...attr) => {
      const meta = document.createElement('meta');
      meta.setAttribute(name[0], name[1]);
      for (const i in attr) {
        const at = attr[i];
        for (const k in at) {
          meta.setAttribute(at[k][0], getString(vm, at[k][1]))
        }
      }
      document.head.appendChild(meta);
    };
    
    const getString = (vm, content) => {
      return typeof content === 'function'
          ? content.call(vm)
          : content
    };
    
    export const getMeta = (vm, meta, env) => {
      if (typeof meta !== 'object')
        return;
    
      if (env) {
        return Object.keys(meta)
            .map(value => {
              return Object.keys(meta[value])
                  .map(key => `${key}="${getString(vm, meta[value][key])}"`)
                  .join(" ");
            })
            .map(value => `  <meta ${value} >`)
            .join("\n");
    
      } else {
        return meta
      }
    };
    
    const serverHeadMixin = {
      created() {
        const {head} = this.$options;
        if (head) {
          const {title} = head;
          if (title)
            this.$ssrContext.title = getString(this, title);
    
          const {meta} = head;
          if (meta)
            this.$ssrContext.meta = `\n${getMeta(this, meta, true)}`
        }
      }
    };
    
    const clientHeadMixin = {
      mounted() {
        const vm = this;
    
        const {head} = this.$options;
        if (head) {
          const {title} = head;
          if (title) {
            document.title = getString(this, title)
          }
    
    
        }
    
        if (head) {
          cleanMetas().then(() => {
            const {meta} = head;
            if (meta)
              for (const nm in meta) {
                const name = Object.entries(meta[nm])[0];
                const attr = Object.entries(meta[nm]).splice(1, Object.entries(meta[nm]).length);
                createMeta(vm, name, attr)
              }
          })
    
        }
      }
    };
    
    
    export default process.env.VUE_ENV === 'server'
        ? serverHeadMixin
        : clientHeadMixin


Ссылка на репозиторий с полным конфигом
  • Вопрос задан
  • 113 просмотров
Подписаться 1 Средний Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы