vue实战总结

使用normalize.scss

/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */

/* Document
   ========================================================================== */

/**
 * 1. Correct the line height in all browsers.
 * 2. Prevent adjustments of font size after orientation changes in iOS.
 */

html {
  line-height: 1.15; /* 1 */
  -webkit-text-size-adjust: 100%; /* 2 */
}

/* Sections
   ========================================================================== */

/**
 * Remove the margin in all browsers.
 */

body {
  margin: 0;
}

/**
 * Render the `main` element consistently in IE.
 */

main {
  display: block;
}

/**
 * Correct the font size and margin on `h1` elements within `section` and
 * `article` contexts in Chrome, Firefox, and Safari.
 */

h1 {
  font-size: 2em;
  margin: 0.67em 0;
}

/* Grouping content
   ========================================================================== */

/**
 * 1. Add the correct box sizing in Firefox.
 * 2. Show the overflow in Edge and IE.
 */

hr {
  box-sizing: content-box; /* 1 */
  height: 0; /* 1 */
  overflow: visible; /* 2 */
}

/**
 * 1. Correct the inheritance and scaling of font size in all browsers.
 * 2. Correct the odd `em` font sizing in all browsers.
 */

pre {
  font-family: monospace, monospace; /* 1 */
  font-size: 1em; /* 2 */
}

/* Text-level semantics
   ========================================================================== */

/**
 * Remove the gray background on active links in IE 10.
 */

a {
  background-color: transparent;
}

/**
 * 1. Remove the bottom border in Chrome 57-
 * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
 */

abbr[title] {
  border-bottom: none; /* 1 */
  text-decoration: underline; /* 2 */
  text-decoration: underline dotted; /* 2 */
}

/**
 * Add the correct font weight in Chrome, Edge, and Safari.
 */

b,
strong {
  font-weight: bolder;
}

/**
 * 1. Correct the inheritance and scaling of font size in all browsers.
 * 2. Correct the odd `em` font sizing in all browsers.
 */

code,
kbd,
samp {
  font-family: monospace, monospace; /* 1 */
  font-size: 1em; /* 2 */
}

/**
 * Add the correct font size in all browsers.
 */

small {
  font-size: 80%;
}

/**
 * Prevent `sub` and `sup` elements from affecting the line height in
 * all browsers.
 */

sub,
sup {
  font-size: 75%;
  line-height: 0;
  position: relative;
  vertical-align: baseline;
}

sub {
  bottom: -0.25em;
}

sup {
  top: -0.5em;
}

/* Embedded content
   ========================================================================== */

/**
 * Remove the border on images inside links in IE 10.
 */

img {
  border-style: none;
}

/* Forms
   ========================================================================== */

/**
 * 1. Change the font styles in all browsers.
 * 2. Remove the margin in Firefox and Safari.
 */

button,
input,
optgroup,
select,
textarea {
  font-family: inherit; /* 1 */
  font-size: 100%; /* 1 */
  line-height: 1.15; /* 1 */
  margin: 0; /* 2 */
}

/**
 * Show the overflow in IE.
 * 1. Show the overflow in Edge.
 */

button,
input { /* 1 */
  overflow: visible;
}

/**
 * Remove the inheritance of text transform in Edge, Firefox, and IE.
 * 1. Remove the inheritance of text transform in Firefox.
 */

button,
select { /* 1 */
  text-transform: none;
}

/**
 * Correct the inability to style clickable types in iOS and Safari.
 */

button,
[type="button"],
[type="reset"],
[type="submit"] {
  -webkit-appearance: button;
}

/**
 * Remove the inner border and padding in Firefox.
 */

button::-moz-focus-inner,
[type="button"]::-moz-focus-inner,
[type="reset"]::-moz-focus-inner,
[type="submit"]::-moz-focus-inner {
  border-style: none;
  padding: 0;
}

/**
 * Restore the focus styles unset by the previous rule.
 */

button:-moz-focusring,
[type="button"]:-moz-focusring,
[type="reset"]:-moz-focusring,
[type="submit"]:-moz-focusring {
  outline: 1px dotted ButtonText;
}

/**
 * Correct the padding in Firefox.
 */

fieldset {
  padding: 0.35em 0.75em 0.625em;
}

/**
 * 1. Correct the text wrapping in Edge and IE.
 * 2. Correct the color inheritance from `fieldset` elements in IE.
 * 3. Remove the padding so developers are not caught out when they zero out
 *    `fieldset` elements in all browsers.
 */

legend {
  box-sizing: border-box; /* 1 */
  color: inherit; /* 2 */
  display: table; /* 1 */
  max-width: 100%; /* 1 */
  padding: 0; /* 3 */
  white-space: normal; /* 1 */
}

/**
 * Add the correct vertical alignment in Chrome, Firefox, and Opera.
 */

progress {
  vertical-align: baseline;
}

/**
 * Remove the default vertical scrollbar in IE 10+.
 */

textarea {
  overflow: auto;
}

/**
 * 1. Add the correct box sizing in IE 10.
 * 2. Remove the padding in IE 10.
 */

[type="checkbox"],
[type="radio"] {
  box-sizing: border-box; /* 1 */
  padding: 0; /* 2 */
}

/**
 * Correct the cursor style of increment and decrement buttons in Chrome.
 */

[type="number"]::-webkit-inner-spin-button,
[type="number"]::-webkit-outer-spin-button {
  height: auto;
}

/**
 * 1. Correct the odd appearance in Chrome and Safari.
 * 2. Correct the outline style in Safari.
 */

[type="search"] {
  -webkit-appearance: textfield; /* 1 */
  outline-offset: -2px; /* 2 */
}

/**
 * Remove the inner padding in Chrome and Safari on macOS.
 */

[type="search"]::-webkit-search-decoration {
  -webkit-appearance: none;
}

/**
 * 1. Correct the inability to style clickable types in iOS and Safari.
 * 2. Change font properties to `inherit` in Safari.
 */

::-webkit-file-upload-button {
  -webkit-appearance: button; /* 1 */
  font: inherit; /* 2 */
}

/* Interactive
   ========================================================================== */

/*
 * Add the correct display in Edge, IE 10+, and Firefox.
 */

details {
  display: block;
}

/*
 * Add the correct display in all browsers.
 */

summary {
  display: list-item;
}

/* Misc
   ========================================================================== */

/**
 * Add the correct display in IE 10+.
 */

template {
  display: none;
}

/**
 * Add the correct display in IE 10.
 */

[hidden] {
  display: none;
}

路由

获取路由列表

在这里插入图片描述

使用elementui

全局样式表
	elementui.scss:部分样式需要进行全局修改
全局组件
两种模式

在这里插入图片描述

compiler
runtime(默认)
修改指向文件,指向vue/dist/vue.js

config.resolve.alias.set('vue', 'vue/dist/vue.esm.js')
定义全局组件

在src目录下建立icons文件夹,建立index.js文件,在其中定义组件,再引入到main.js中,最后把花括号里面的内容抽离到一个vue文件中
在这里插入图片描述
index:

import Vue from 'vue'
import Svgicon from './Svgicon.vue'

Vue.component('svg-icon', Svgicon)

/**
 * require.context('./svg', false, /\.svg$/)参数:
 * 第一:目录
 * 第二:是否遍历子级目录
 * 第三:定义遍历文件规则
 */
const req = require.context('./svg', false, /\.svg$/)
const requireAll = requireContext => {
  return requireContext.keys().map(requireContext)
}

requireAll(req)


Svgicon:

<template>
    <svg :class="svgClass" aria-hidden="true">
        <use :xlink:href="iconName"></use>
    </svg>
</template>
<script>
import {reactive, ref, isRef, toRefs, onMounted, computed } from '@vue/composition-api'
export default {
  name: 'svgIcon',
  //接受父组件传值 
  props: {
    iconClass: {
      type: String,
      defauot: ''
    },
    className: {
      type: String,
      defauot: ''
    }
  },
  setup (props) {
    console.log(props.iconClass)
    const msg = ref('svgIcon')

    // computed监听
    const iconName = computed(() => `#icon-${props.iconClass}`)
    const svgClass = computed(() => {
      if (props.className) {
        return `svg-icon ${props.className}`
      } else {
        return 'svg-icon'
      }
    })
    return {
      msg,
      iconName, svgClass
    }
  }
}
</script>
<style lang="scss" scoped>

</style>

svg文件

在模板引入:

<svg :class="svgClass" aria-hidden="true">
        <use :xlink:href="name"></use>
    </svg>

解析文件:

/**
 * require.context('./svg', false, /\.svg$/)参数:
 * 第一:目录
 * 第二:是否遍历子级目录
 * 第三:定义遍历文件规则
 */
const req = require.context('./svg', false, /\.svg$/)
const requireAll = requireContext => {
  return requireContext.keys().map(requireContext)
}

requireAll(req)

在vue.config.js中依赖

chainWebpack:config => {
	const svgRule = config.module.rule('svg')
	    svgRule.uses.clear()
	    svgRule
	      .use('svg-sprite-loader')
	      .loader('svg-sprite-loader')
	      .options({
	        symbolId: 'icon-[name]',
	        include: ['./src/icons']
	      })
     }
修改color的时候要使用fill	
在router的meta对象中传入icon属性,在获取路由列表的时候获取该属性,并渲染到svg-icon组件中
//路由:
const routes = [
  {
    path: '/',
    redirect: 'login',
    hidden: true,
    meta: {
      name: '首页'
    }
  },
  {
    path: '/login',
    name: 'Login',
    hidden: true,
    meta: {
      name: '登录',
      icon: 'login'
    },
    component: () => import('../views/Login/index.vue')
  }
  ]

结合ElementUI菜单,获取路由列表,渲染导航

<template v-for="(routeItem,index) in routeList" >
                    <el-submenu :key="routeItem.id" :index="routeItem.path" v-if="!routeItem.hidden">
                    <!-- 一级菜单 -->
                    <template slot="title">
                        <svg-icon :iconClass="routeItem.meta.icon" className="console-svg"></svg-icon>
                        <span slot="title" class="">{{ routeItem.meta.name}}</span>
                    </template>
                    <!-- 子级菜单 -->
                    <el-menu-item v-for="(subItem, index) in routeItem.children" :key="subItem.id" :index="subItem.path">{{subItem.meta.name}}</el-menu-item>
                    </el-submenu>
                </template>

使用flex布局

router.beforeEach路由守卫

router/premit.js
参数:
next
to 要进入的页面
from 离开之前的页面(上一个)
函数:
next():一定要调用这个方法来resolve这个钩子,执行效果依赖next方法的调用参数

守卫或登录流程
检查token是否存在,从cookie中获取token,如果不存在,进行next跳转到登录页面。并且在跳转之前,要判断是否存在下一个页面(白名单判断),防止守卫进入死循环。:


 1. 直接进入index的时候,参数to被改变成“/index”,触发路由指向,就会在进行beforeEach
 2. 再一次next指向login,再次发生路由指向,再跑beforeEach,参数的头被改变成“/login”
 3. 白名单判断存在,直接执行next(),因为没有参数,所以不会再次beforeEach
使用fill改变svg颜色
fill:currentColor
color:red

currentColor也可以全局定义

父子组件传值
propdatas
watch
computed
默认get方法返回,监听到值得的变化就可以进行属性的计算并返回值或字符串
set方法 :值先通过get计算,再传给set

使用vuex

建立store.js

四个属性
getters
时候我们需要从 store 中的 state 中派生出一些状态,
Vuex 允许我们在 store 中定义“getter”(可以认为是 store 的计算属性)。
就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,
且只有当它的依赖值发生了改变才会被重新计算。
const getters = {
  teamId: state => state.teamId,
  userRole: state => state.userRole
}
state
Vuex 使用单一状态树——是的,用一个对象就包含了全部的应用层级状态。
至此它便作为一个“唯一数据源 (SSOT (opens new window))”而存在。
这也意味着,每个应用将仅仅包含一个 store 实例。
单一状态树让我们能够直接地定位任一特定的状态片段,在调试的过程中也能轻易地取得整个当前应用状态的快照。

每当 store.state.count 变化的时候, 都会重新求取计算属性,并且触发更新相关联的 DOM。
const state = {
  // token
  token: cookie.get('userToken') || '',
  userId: cookie.get('userId') || '',
  workId: cookie.get('workId') || ''
}
mutations
更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutation 非常类似于事件:
每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。
这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数:

你不能直接调用一个 mutation handler。这个选项更像是事件注册:
“当触发一个类型为 SET_TOKEN的 mutation 时,调用此函数。”
要唤醒一个 mutation handler,你需要以相应的 type 调用 store.commit 方法:
const mutations = {
  SET_TOKEN (state, value) {
    state.token = value
  }
}
store.commit(SET_TOKEN)
actions

Action 类似于 mutation,不同在于:

  • Action 提交的是 mutation,而不是直接变更状态。
  • Action 可以包含任意异步操作。

注册一个简单的 action:

const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment (state) {
      state.count++
    }
  },
  actions: {
    increment (context) {
      context.commit('increment')
    }
  }
})
Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,
因此你可以调用 context.commit 提交一个 mutation,
或者通过 context.state 和 context.getters 来获取 state 和 getters。
actions: {
  increment ({ commit }) {
    commit('increment')
  }
}

#分发 Action
Action 通过 store.dispatch 方法触发:

store.dispatch('increment')
通过vuex修改菜单的状态值,确定展开或收缩
在header获取状态值,点击并且修改(root.$store.comit())
,在Nav中使用computed监听状态值变化

并且在布局的index.vue中监听状态值,
当变化时,通过一个class(open或close)使index整体移动,并且过渡
modules模块管理状态数据
由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。
当应用变得非常复杂时,store 对象就有可能变得相当臃肿。

为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。
每个模块拥有自己的 state、mutation、action、getter、
甚至是嵌套子模块——从上至下进行同样方式的分割:

目录结构:
在这里插入图片描述

把各个属性提取出来定义,解决命名空间问题
命名空间
默认情况下,模块内部的 action、mutation 和 getter 
是注册在全局命名空间的——这样使得多个模块能够对同一 mutation 或 action 作出响应。

如果希望你的模块具有更高的封装度和复用性,
你可以通过添加 namespaced: true 的方式使其成为带命名空间的模块。
当模块被注册后,它的所有 getter、action 及 mutation 都会自动根据模块注册的路径调整命名。例子:
const store = new Vuex.Store({
  modules: {
    account: {
      namespaced: true,

      // 模块内容(module assets)
      state: () => ({ ... }), // 模块内的状态已经是嵌套的了,使用 `namespaced` 属性不会对其产生影响
      getters: {
        isAdmin () { ... } // -> getters['account/isAdmin']
      },
      actions: {
        login () { ... } // -> dispatch('account/login')
      },
      mutations: {
        login () { ... } // -> commit('account/login')
      },

      // 嵌套模块
      modules: {
        // 继承父模块的命名空间
        myPage: {
          state: () => ({ ... }),
          getters: {
            profile () { ... } // -> getters['account/profile']
          }
        },

        // 进一步嵌套命名空间
        posts: {
          namespaced: true,

          state: () => ({ ... }),
          getters: {
            popular () { ... } // -> getters['account/posts/popular']
          }
        }
      }
    }
  }
})

全局方法export install

在这里插入图片描述
注册global.js,存放全局方法
vue2.0:在这里插入图片描述
vue3.0:
在这里插入图片描述
可以通过重命名来区分命名空间

vue3.0封装接口

接口统一封装在api文件夹中,例子:
目录结构:
在这里插入图片描述

 api文件:

在这里插入图片描述
在vuex中的moudle调用:
在这里插入图片描述

自适应布局学习
rem:
1. rem单位

rem是一个灵活的、可扩展的单位,由浏览器转化像素并显示。与em单位不同,rem单位无论嵌套层级如何,都只相对于浏览器的根元素(HTML元素)的font-size。默认情况下,html元素的font-size为12px,所以:

1 rem = 12px

为了计算方便,通常可以将html的font-size设置成:

html{ font-size: 67.5% }

这种情况下:

1 rem = 10px

2.通过rem来实现响应式布局

rem单位都是相对于根元素html的font-size来决定大小的,根元素的font-size相当于提供了一个基准,当页面的size发生变化时,只需要改变font-size的值,那么以rem为固定单位的元素的大小也会发生响应的变化。

需要根据视图容器的大小,动态的改变font-size即可。

function refreshRem() {
    var docEl = doc.documentElement;
    var width = docEl.getBoundingClientRect().width;
    var rem = width / 10;
    docEl.style.fontSize = rem + 'px';
    flexible.rem = win.rem = rem;
}
win.addEventListener('resize', refreshRem);

上将视图容器分为10份,font-size用十分之一的宽度来表示,最后在header标签中执行这段代码,就可以动态定义font-size的大小,从而1rem在不同的视觉容器中表示不同的大小,用rem固定单位可以实现不同容器内布局的自适应。

3. rem2px和px2rem

如果在响应式布局中使用rem单位,那么存在一个单位换算的问题,rem2px表示从rem换算成px,这个就不说了,只要rem乘以相应的font-size中的大小,就能换算成px。更多的应用是px2rem,表示的是从px转化为rem。

比如给定的视觉稿为750px(物理像素),如果我们要将所有的布局单位都用rem来表示

一种比较方便的解决方法就是,在css中我们还是用px来表示元素的大小,最后编写完css代码之后,将css文件中的所有px单位,转化成rem单位。

px2rem的原理也很简单,重点在于预处理以px为单位的css文件,处理后将所有的px变成rem单位。可以通过两种方式来实现:

// webpack loader的形式:

npm install px2rem-loader
//在webpack的配置文件中:

module.exports = {
  // ...
  module: {
    rules: [{
      test: /\.css$/,
      use: [{
        loader: 'style-loader'
      }, {
        loader: 'css-loader'
      }, {
        loader: 'px2rem-loader',
        // options here
        options: {
          remUni: 75,
          remPrecision: 8
        }
      }]
    }]
  }
}
//webpack中使用postcss plugin

npm install postcss-loader
//在webpack的plugin中:

var px2rem = require('postcss-px2rem');

module.exports = {
  module: {
    loaders: [
      {
        test: /\.css$/,
        loader: "style-loader!css-loader!postcss-loader"
      }
    ]
  },
  postcss: function() {
    return [px2rem({remUnit: 75})];
  }
}

4.vue 中的 rem 布局

由于该项目使用vue3,所以总结vue3 中的用法

   //安装lib-flexible

npm install lib-flexible -S
    //引入lib-flexible

//在main.js中引入lib-flexible-->
import 'lib-flexible/flexible'S
pxtorem:将项目中css的px转成rem单位,免去计算烦恼 
1)安装postcss-pxtorem 
S
npm install postcss-pxtorem -S
// 配置postcss-pxtorem 


<!--package.json内,在postcss内添加-->
"postcss": {
    "plugins": {
      "autoprefixer": {},
      "postcss-pxtorem": {
        "rootValue": 75 // 设计稿宽度的1/10,
        "propList":['*'],
        // 需要做转化处理的属性,如`hight`、`width`、`margin`等,`*`表示全部
     }
    }
  }

注意:
1、pxtorem中,对于想忽略的px写成大写即可

5. rem 布局的缺点

通过rem单位,可以实现响应式的布局,特别是引入相应的postcss相关插件,免去了设计稿中的px到rem的计算。
rem单位在国外的一些网站也有使用,这里所说的rem来实现布局的缺点,或者说是小缺陷是:

在响应式布局中,必须通过js来动态控制根元素font-size的大小。
也就是说css样式和js代码有一定的耦合性。且必须将改变font-size的代码放在css样式之前

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值