社区项目前端vue总结

前序

在开发社区项目的前端时,根据当前的流行,选择了前后端分离,另外一方面也可以实现后端与前端的解耦。使修改前端代码的时候,无需再打包后台程序。

另外用用vue,提升一下技能。后端程序也得会前端啊。

一些总结

在开发中,总有一些方法在多个组件或者view中使用,每次都需要手动引入对应的方法,导致很繁琐,那么有没有方法不在每个需要的对应方法的组件导入呢?有需求-就会有解决方案。

我们的需求,就是将一些常用或公共的方法,在使用的地方无需重新导入,而是直接引入就可以,那么,这不就是我们java中的全局变量,或者静态类、spring的ioc容器吗?

那么,在vue中,我们应该如何解决这个问题呢?

根据百度,以及vue的官方文档找到了解决方案,可以将我们的通用方法,挂载到vue的prototype(原型)上,从而实现全局使用。

https://cn.vuejs.org/v2/cookbook/adding-instance-properties.html

挂载全局方法

代码示例:
main.js
import * as tools from "@/utils/common"
Vue.prototype.$tools = tools

使用:
this.$tools.toastError("未登录")

父子组件传值

很多时候,我们都会将一个复杂的页面,抽出多个小的组件去编码实现,然后再组装到view。但是这样就会存在一些数据之间的交互问题。常见的场景就是子组件需要父组件的数据、父组件需要子组件的数据、兄弟组件需要兄弟的数据。

根据官方解决方案如下

通过 Prop 向子组件传递数据

1.父组件调用子组件的时候 绑定动态属性
    <v-header :title="title"></v-header>

2、在子组件里面通过 props接收父组件传过来的数据
    props:['title']

监听子组件事件(子组件 $emit(父组件监听的函数名,数据),@函数名=函数名)

1.父组件定义监听方法
    tabItemClick(itemId) {
    	
    }
2.绑定监听方法到子组件    
     <TabList
        id="tab-list"
        :showRecommen="true"
        @tabItemClick="tabItemClick"
      ></TabList>
3.子组件通过 this.$emit("tabItemClick",  this.id);传递数据到父组件监听的函数

父组件主动获取子组件的数据和方法

1.调用子组件的时候定义一个ref

    <v-header ref="header"></v-header>

2.在父组件里面通过

    this.$refs.header.属性

    this.$refs.header.方法

子组件主动获取父组件的数据和方法

    this.$parent.数据

    this.$parent.方法

部署在非根目录下的问题

本次的社区项目,前台和后台是2个独立的vue项目。部署的时候想根目录下部署前台,然后nginx代理admin路径到后台项目,

在打包完成后,部署到nginx后,发现,后台项目的css,js能都404。猜测是目录的问题,然后查阅百度,找到了解决方案,可以指定publicPath参数和assetsDir参数。

publicPath:该配置能帮助你为项目中的所有资源指定一个基础路径。因此我们部署到正式环境的话,publicPath尽量定义成相对路径('./'),这样打包后就可以部署在任意目录了 。

assetsDir:定义打包后的静态资源目录

alias:定义别名。方法引入src下的内容,从而避免使用大量相对路径

官方文档https://cli.vuejs.org/zh/config/#publicpath

const path = require('path')

function resolve(dir) {
    return path.join(__dirname, dir)
}

module.exports = {
    // 选项...
    publicPath: process.env.NODE_ENV === "production" ? './' : '/',
    assetsDir: 'static',
    configureWebpack: {
        resolve: {
            alias: {
                '@': resolve('src')
            }
        }
    },

}

Message弹多次的情况(如何只弹一次)

需求:部分提示信息,通过axios的response拦截器进行处理,进行友好的信息提示,但是在实际中,一个页面必定存在多个请求,那么,根据msg的提示信息,就会出现多个。但是这样友好型不够,我只想弹一次。本着有需求就有解决方案,我进行了百度。

解决方案:

定义一个类,这个类用于处理各种信息提示,如成功、错误、警告等。

弹框的时候判断当前页面是否已经存在了弹框的元素,如果已经存在,则不提示,否则可以进行提示。

并且在使用的地方,进行单例。

message.js
import { Message } from 'element-ui'
// 私有属性,只在当前文件可用
const showMessage = Symbol('showMessage')
export default class domMessage {
    success(options, single = true) {
        this[showMessage]('success', options, single)
    }
    warning(options, single = true) {
        this[showMessage]('warning', options, single)
    }
    info(options, single = true) {
        this[showMessage]('info', options, single)
    }
    error(options, single = true) {
            this[showMessage]('error', options, single)
        }
        [showMessage](type, options, single) {
            if (single) {
                // 关键代码,判断当前页是否有el-message标签,如果没有则执行弹窗操作
                if (document.getElementsByClassName('el-message').length === 0) {
                    Message[type](options)
                }
            } else {
                Message[type](options)
            }
        }
}


使用
方法外初始化,只初始化一次
var messageOnce = new MessageOne();

在需要使用的方法内调用        
messageOnce.error({
            message: res.data.msg
        })

判断对象是否为空

Object.keys(postData).length == 0

Quill富文本编辑器自动获取焦点导致页面自动在最下面

因为要发帖,所以引入了富文本,用的时候挺好用,但是在正式测试的时候,发现点击帖子,就自动到了页面的最下面(因为编辑器在最下面)。咨询了一下前端的朋友,说把编辑器的代码注释掉看看正常不。注释后,发现正常。于是想到了焦点,然后,我就看看富文本有没有默认的配置可以不自动获取焦点,但是我失败了,没有默认的配置。于是只能通过代码来实现。

 	  在Quill初始化后,禁用掉,然后调用失去焦点方法。这里必须禁用,不然还是会获得焦点
 	  this.Quill.enable(false);
      this.Quill.blur();
      //一大推初始化代码。
      //等到完全初始化后,在调用enable方法,接触掉禁用,就可以实现不自动获取焦点了,从而解决了问题
       this.Quill.enable(true);
      

路由守卫

来自vue目标,进行拦截,如果没有权限,直接跳转到登录页
import router from './router'

import { Message } from 'element-ui'
import NProgress from 'nprogress' // progress bar
import 'nprogress/nprogress.css' // progress bar style
import { getToken, removeToken } from '@/utils/auth' // get token from cookie
import getPageTitle from '@/utils/get-page-title'
import { getUserInfo } from "@/api/user"



NProgress.configure({ showSpinner: false }) // NProgress Configuration

const whiteList = ['/login'] // no redirect whitelist

router.beforeEach(async(to, from, next) => {
    // start progress bar
    NProgress.start()

    // set page title
    document.title = getPageTitle(to.meta.title)

    // determine whether the user has logged in
    const hasToken = getToken()

    if (hasToken) {
        if (to.path === '/login') {
            // if is logged in, redirect to the home page
            next({ path: '/' })
            NProgress.done()
        } else {
            //发送请求,判断用户是否已经登录
            await getUserInfo().then(res => {
                console.log(res);
                if (res.data != null) {
                    next()
                } else {
                    next(`/login?redirect=${to.path}`)
                    removeToken();
                }
            })
        }
    } else {
        /* has no token*/

        if (whiteList.indexOf(to.path) !== -1) {
            // in the free login whitelist, go directly
            next()
        } else {
            // other pages that do not have permission to access are redirected to the login page.
            next(`/login?redirect=${to.path}`)
            NProgress.done()
        }
    }
})

router.afterEach(() => {
    // finish progress bar
    NProgress.done()
})
上一篇:大数据技术原理与应用之【NoSQL数据库】习题


下一篇:Linux-Task01:Linux简介