• 社区项目前端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()
    })
    
  • 相关阅读:
    四叉树编码存储的实现
    窗体之间传递值的几种方法
    常见的六种排序算法实现
    OracleHelper类
    c#动态加载dll文件
    STL学习系列九:Map和multimap容器
    STL学习系列八:Set和multiset容器
    STL学习系列七:优先级队列priority_queue容器
    STL学习系列六:List容器
    STL学习系列五:Queue容器
  • 原文地址:https://www.cnblogs.com/chaoba/p/15895907.html
Copyright © 2020-2023  润新知