vue知识点的整理

本文详细介绍了Vue.js的核心知识,从创建实例到深入理解模板语法、指令、组件系统,涵盖计算属性、响应式原理、生命周期和路由管理。还探讨了Vue CLI的使用、单页面应用、模块化、AJAX技术,并讨论了Vuex状态管理和实际项目案例。此外,文章还涵盖了UI组件库的使用和登录权限业务的实现。
摘要由CSDN通过智能技术生成

Vue

官网 中文版本

渐进式 JavaScript 框架

Vue 不支持 IE8 及以下版本,因为 Vue 使用了 IE8 无法模拟的 ECMAScript 5 特性(Object.defineProperty())。

版本:Vue 2.x

创建实例

// mvvm 
const vm = new Vue({
      el: '#app', // element - View,
      data: { // 数据 - Model
        message: 'hello'
      },
      methods: { // 方法
        
      },
      computed: { // 计算属性
        
      }
    })

说明:在创建 Vue 实例时,会将 data、methods、computed 中定义的数据/方法/计算值直接挂载到 Vue 对象实例下,可以使用 e l 获 取 到 元 素 D O M 节 点 、 el 获取到元素DOM节点、 elDOMdata 获取到整个的 data 对象。注意:在 Vue 对象实例下,已有很多以 _ 或 $ 开头的属性,在 data 中自定义的数据最好不要以 _ 或 $ 开头,如果定义的 data 数据中有以 _ 或 $ 开头的则不会自动被挂载到 Vue 实例下,如果需要访问到这些属性,使用 $data 去获取对应属性的使用。

模板语法

插值

{{ 文本插值 }}

“Mustache”语法,说明,在 {{ }} 内部所书写的是 JavaScript 的表达式,在标签的属性中不能使用 {{ }} 绑定属性值(如果需要动态绑定属性值,使用 v-bind)

指令

指令 (Directives) 是在标签中带有 v- 前缀的特殊属性,这些属性有特定的含义,能够直接被 Vue 实例所解析。

v-html

渲染 HTML 文本(不建议轻易使用,可能导致 XSS 攻击,除非所渲染的内容是完全可信的)

v-text

渲染纯文本

v-bind

动态绑定属性值,可简写为 :

v-on

绑定事件,可简写为 @

修饰符:

  • .prevent ---- 阻止默认行为
  • .stop ---- 阻止事件传播
  • .enter ---- 回车键
  • .ctrl ---- ctrl 控制键,例如:@keydown.ctrl.enter=“sendMessage”
条件渲染指令
v-if

指令属性值表示条件,切换元素显示/隐藏时,操作的是 DOM 树的结构:显示时向 DOM 树中添加节点,隐藏时从 DOM 树中删除节点

v-else-if
v-else

v-else 指令没有属性值

v-show

切换元素显示/隐藏时,操作的是节点的 CSS 样式(display):显示时将 display: none; 删除,隐藏时添加 display: none;

v-if 与 v-show 的区别:
  • 操作 DOM 树还是 CSS 样式
  • 一般来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。
使用 key 管理元素

Vue 会尽可能高效地渲染元素,通常会复用已有元素(就地复用策略)而不是从头开始渲染。这么做除了使 Vue 变得非常快之外,还有其它一些好处。这样也不总是符合实际需求,所以 Vue 为你提供了一种方式来表达“这两个元素是完全独立的,不要复用它们”。只需添加一个具有唯一值的 key attribute 即可

列表渲染指令
v-for

v-for="(item, index) in arrayOrObject" 或 v-for="(item, index) of arrayOrObject"

通常在使用 v-for 实现列表渲染时,需要动态绑定 key 属性,key 值应该唯一,不要使用 index 作为 key 值绑定

通常是使用 v-for 来实现数组的列表渲染

数组变异(变更)方法:

  • pop()
  • push()
  • shift()
  • unshift()
  • splice(index, howmany, replace)
  • sort()
  • reverse()

在 Vue 中,调用上述数组的7个方法实现数组更新时,页面也会响应式更新,如果调用了非上述的方法(原数组本身未受影响),那可以使用替换数组的方式来实现页面响应式更新,如:

vm.list = vm.list.filter(item => item.id > 1)
v-once

只渲染元素和组件一次。随后的重新渲染,元素/组件及其所有的子节点将被视为静态内容并跳过。

v-pre

跳过这个元素和它的子元素的编译过程。

v-cloak

和 CSS 规则如 [v-cloak] { display: none } 一起用时,这个指令可以隐藏未编译的 Mustache 标签直到实例准备完毕,(作用:避免出现编译前后页面节点的闪烁效果)

v-model

通常用于表单元素的数据双向绑定

语法糖

v-model 在内部为不同的输入元素使用不同的 property 并抛出不同的事件:

  • text 和 textarea 元素使用 value property 和 input 事件;
  • checkbox 和 radio 使用 checked property 和 change 事件;
  • select 字段将 value 作为 prop 并将 change 作为事件。
v-slot

用于使用插槽

<template v-slot:subtitle>
    
</template>

计算属性、侦听属性

计算属性

通常是根据已有的数据,计算出新的数据,一般都是使用到计算属性的 getter(很少用到 setter)

new Vue({
    data: {
        message: 'hello'
    },
    computed: { // 计算属性
        reverseMsg() { // 属性 getter 的简写
            return this.message.split('').reverse().join('')
        },
        reverseMsg2: { // 与 reverseMsg() 书写等价
            get() { // getter
                return this.message.split('').reverse().join('')
            }
        }
    }
})

计算属性的值是会被缓存的,当依赖项不改变时,会一直使用缓存的数据,依赖项发生改变时,会重新计算 computed 属性的值并继续缓存。

计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值。

computed vs method

计算属性会被缓存,而方法不会被缓存,通常计算属性效率会比方法更高

侦听属性

watch

监听到数据变化后执行对应的任务

computed vs watch
  • computed 有缓存,watch 无缓存
  • computed 计算属性中不能执行异步操作,而 watch 中可以执行异步操作
  • computed 通常是由一个或多个数据的变化,生成一个新的数据,而 watch 通常是监听一个数据的变化,可能引起一个或多个其它数据的变化

Class 与 Style 绑定

在将 v-bind 用于 classstyle 时,Vue.js 做了专门的增强。表达式结果的类型除了字符串之外,还可以是对象或数组。

对于 style 的绑定,更推荐使用对象的方式绑定。使用对象时,将 css 属性名的短横线全名规范改为驼峰全名规范来使用。

组件系统

在 Vue 里,一个组件本质上是一个拥有预定义选项的一个 Vue 实例。

组件是可被复用的 Vue 实例

组件定义

选项对象:

{
    template: ``// 布局结构
    data() { return {} }, // 数据
    methods: {},
    computed: {},
    watch: {}
}

组件定义时,data 必须是函数的结构,在函数体内部返回一个普通对象。

(面试)data 必须是函数的原因:如果使用普通对象,当组件被复用时,多个组件对象实例引用到同一个数据对象,当其中某一个组件实例对 data 数据作修改时,其它组件实例也会同时受影响,这与实际业务不符。使用函数,每创建一个组件实例时,都返回新的 data 对象数据,多个组件实例间 data 是独立开的,当修改组件实例中的数据时,其它组件实例不受影响,与实际相符。

在 template 中定义布局结构时,必须保存所有的布局使用 单个根元素 包裹起来

组件注册

全局注册
Vue.component('组件名称', 选项对象)

全局注册的组件,在所有的 Vue 实例或其它组件中,都可以使用到

局部注册
{
    components: {
        组件名称: 选项对象
    }
}

在组件或 Vue 实例的选项对象中,添加 components 字段,来局部注册子组件

局部注册的组件,只在注册它的父组件内部可以使用到

组件使用

将组件名称作为自定义标签名称使用。

规范:如果组件名称是使用驼峰命名规范,则在作为自定义标签名使用时,转换为短横线命名规范(各单词之间使用 短横线 分隔,所有单词小写)

插槽

用作于内容分发,在父组件中可以向子组件传递布局结构的内容。

组件通信

父子通信

  • 父传子:通过属性的方式传递数据 ---- prop。
  • 子传父:使用事件的方式传递数据。在父组件中使用子组件时,绑定一个自定义事件(@customEvent),在子组件中需要传递数据时,触发对应的事件执行( this.$emit(事件名称, 需要传递的数据) ) 并传递相应数据(相当于传递的数据是携带在 $event 对象中传递给父组件的) 即可。

跨组件通信

  • 将组件关系转换为一系列的父子关系(会增加中间组件的处理负担)
  • event bus (事件总线):创建一个全局的 Vue() 实例(可以将该 Vue() 实例添加到 Vue.prototype 中,这样就可以在各组件实例中调用到了 ),在需要接收数据的组件中使用 $on() 方法注册一个自定义事件,在需要传递数据的组件中使用 $emit() 方法去触发对应事件的执行并传递数据。
  • vuex
Prop

父组件向子组件传递数据时,可使用 prop ( 属性 ) 的方式。在组件的选项对象中,使用 props 来定义组件可接收到的属性,props 可取数组和对象的结构。数组中每个元素通常是所能接收属性的属性名称,对象通常是对属性做校验使用。

组件中的属性应该是只读的(不要修改组件接收到的属性值)

响应式原理

底层使用到 Object.defineProperty() 方法,对数据劫持,在各数据的 getter/setter 方法中添加额外的操作,以实现响应式动作。

虚拟 DOM:

<div :title="divTitle" id="title" class="title">
    <h1 class="title">
        {{ title }}
    </h1>
    <h2 class="subtitle">
        副标题
    </h2>
</div>

{
    tag: 'div',
    props: {
        title: data.divTitle,
        id: 'title',
        className: 'title'
    },
    children: [
        {
            tag: 'h1',
           	props: {
                className: 'title'
            },
            children: [data.title]
        },
        {
            tag: 'h2',
           	props: {
                className: 'subtitle'
            },
            children: ['副标题']
        }
    ]
}

当数据被修改后,在内存中存在修改前后的两个对象,Vue 会将数据修改前后的两个对象进行比较(diff 算法),找出两个对象不同的部分,将不同部分的内容重新渲染到真实的 DOM 树中。

Vue 推荐在绝大多数情况下使用模板来创建你的 HTML。然而在一些场景中,你真的需要 JavaScript 的完全编程的能力。这时你可以用渲染函数,它比模板更接近编译器。

渲染函数 – render()

function render (createElement) {
	return createElement(tag, props, children)
}

createElement() 函数的主要作用是用作于创建 虚拟元素 节点,用于在虚拟 DOM 中的处理。

生命周期

生命周期指的是 Vue 实例或组件从创建到最终销毁所经历的整个过程。

生命周期各阶段中,如果需要执行用户额外添加的操作,Vue 提供了一些 生命周期钩子函数 来执行额外的操作。

create 阶段(创建)

  • beforeCreate()
  • created() – 一般页面初始化渲染所使用到的数据如果需要从后端接口中获取,则在 created() 方法中发起 ajax 请求去获取数据。

mount 阶段 (挂载)

注意 mounted 不会保证所有的子组件也都一起被挂载。如果你希望等到整个视图都渲染完毕,可以在 mounted 内部使用 vm.$nextTick(callback)

  • beforeMount()
  • mounted() – 在 mounted() 方法中,可获取到挂载的 DOM 节点

vm.$nextTick(callback) 方法:将 callback 回调函数的执行延迟到下一次 DOM 更新之后执行

update 阶段(更新)

当 data / props 数据发生改变时,进入 update 阶段。注意,在 update 阶段的生命周期钩子函数中不要再次修改数据,否则会导致死循环内存溢出。

  • beforeUpdate()
  • updated()

destroy 阶段(销毁)

  • beforeDestroy()
  • destroyed()

过滤器

vue.js 中允许用户自定义过滤器,过滤器主要的作用是文本格式化。它可以用在 {{}} 插值语法和 v-bind 绑定属性的表达式中

全局定义、局部定义:

// 全局
Vue.filter(过滤器名称, 处理函数)

// 局部定义,在组件的选项对象中:
{
    filters: {
        过滤器名称: 处理函数
    }
}

在 {{}} 或是 v-bind 表达式中使用过滤器时,利用 | 管道运算符连接过滤器名称。例如:{{ prod.price | money }},<custom-component v-bind:price="prod.price | money">

Vue CLI

安装

$ npm install -g @vue/cli
# OR
$ yarn global add @vue/cli

安装后测试是否能够看到版本信息:

$ vue --version

如果不能看到版本信息,报告 vue 不是内部外部命令之类的异常,则可能需要重新配置环境变量。

如果是 npm 安装的 @vue/cli,在环境变量中,path 内是否有 C:\Users\<你的用户名>\AppData\Roaming\npm

如果是 yarn 安装的 @vue/cli,在环境变量中,path 内是否有 C:\Users\<你的用户名>\AppData\Local\Yarn\bin

添加对应的环境变量 path 值后,重启命令行工具,再测试 vue --version

单文件组件

文件后缀名为 .vue,文件内容结构:

<template>
    <!-- 组件视图布局 -->
</template>

<script>
	// 组件选项对象
    export default {
        name: 'ComponentName'
    }
</script>

<style lang="scss" scoped>
	/* 布局结构中使用到的样式 */
</style>

在 VS code 中,如果需要查看单文件组件时,代码有高亮效果,需要安装 vetur 扩展程序

使用 @vue/cli 创建项目

推荐先使用 cmd 命令行工具运行 vue 命令

$ vue create <project-name>

创建项目时,先选择项目中需要添加的特性。然后创建项目目录,安装依赖。

项目创建完毕后,进入项目目录,运行:

$ npm run serve
# OR
$ yarn serve

package.json

npm scripts

{
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint"
  }
}

serve – 是开发环境使用到的任务:npm run serve,启动任务后,会在本地启动一个 web server (webpack-dev-server)。

build – 构建,是生产环境使用到的任务。运行 npm run build 后,默认会在项目根目录下生成 dist 目录,dist 目录中放置的就是用于部署(发布上线)的代码。

lint – lint 工具,检测语法规范

别名

@ - 代表 src 目录

SPA - 单页面应用程序

模块化

AMD - require.js define() / require()

CMD - sea.js

CommonJS - NodeJS module.exports / require

ES6 Module - import/export

AJAX

原生 ajax

  1. 创建 XMLHttpRequest 对象
  2. 初始化,xhr.open(method, url, async)
  3. 发送请求,xhr.send(querystring),如果要像表单一样 POST 数据,则需要在 send() 调用前去调用 xhr.setRequestHeader(‘Content-Type: application/x-www-form-urlencoded’) 设置请求头
  4. 监听,处理响应 xhr.onreadystatechange = function() {}
    • xhr.readyState – 就绪状态码(当前请求到达哪个阶段),4 – 请求处理完毕,响应就绪
    • xhr.status – HTTP 状态码,2xx
    • xhr.responseText – 响应文本 JSON

Promise

它允许你为异步操作的成功和失败分别绑定相应的处理方法(handlers)。 这让异步方法可以像同步方法那样返回值,但并不是立即返回最终执行结果,而是一个能代表未来出现的结果的promise对象

三种状态:

  • pending - 初始化、等待
  • fulfilled - 成功
  • rejected - 失败

使用:

new Promise((resolve, reject) => {
    setTimeout(() => {
        if (Math.random() > 0.5) {
            resolve('success') // 将状态修改为 fulfilled 状态
        } else {
            reject('fail') // 将状态修改为 rejected 状态
        }
    }, 1000)
})
    .then((successData) => {
		console.log(successData)
    })
	.catch((err) => {
		console.log(err)
    })
	.finally()

async / await (ES7)

await 等待的是一个 Promise 对象返回的异步结果。await 只能用在 async 所修改的 function 中。

await 表达式会暂停当前 async function 的执行,等待 Promise 处理完成。若 Promise 正常处理(fulfilled),其回调的resolve函数参数作为 await 表达式的值,继续执行 async function

Fetch API

Fetch API 提供了一个获取资源的接口(包括跨域请求)。

发送请求或者获取资源,需要使用 fetch() 方法。

fetch() 必须接受一个参数 url ——资源的路径。无论请求成功与否,它都返回一个 Promise 对象,resolve 对应请求的 Response 响应对象,还需要借助 Response 对象的 json() 方法来获取响应流中的数据。

axios

中文文档

Vue-Router

Vue Router 是 Vue.js 官方的路由管理器。它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌。

前端路由

hash 模式

通过地址 URL 中 #hash 值的变化监测来实现页面的切换效果。在 URL 地址中当 hash 值改变时,会触发 window.onhashchange 事件的执行,在事件处理程序中,可以实现组件切换。在 hash 模式中,URL 中会有一个 # 号标识

history 模式

利用 H5 中 history 对象新增的 pushState() 、replaceState() 方法来实现向历史记录中添加访问历史(这种添加访问历史的操作也不会向服务器发起新的请求),当添加/删除访问历史时,会触发 window.onpopstate 事件的执行,在事件处理程序中可以实现组件切换操作。在 history 模式中,URL 和请求服务器端的资源 URL 是一致的(没有多余的 #)。但 history 要用好,通常还需要服务器端 webserver 中配合做一些配置。

使用

安装

$ npm install vue-router --save
# 或
$ yarn add vue-router

创建 VueRouter 实例

import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from './views/home'
// 使用插件,全局注册了 RouterLink 与 RouterView 两个组件
Vue.use(VueRouter)
// 创建 VueRouter 对象
const router = new VueRouter({
  mode: 'hash', // hash / history
  routes: [ // 路由表配置
    {
      path: '/home',
      component: Home
    }
  ]
})
// 导出
export default router

关联 Vue 实例

import Vue from 'vue'
import router from './router'

new Vue({
  router,
  render: h => h(App)
}).$mount()

这步操作是在 main.js 中完成

两个组件

<router-link>

超级链接,<router-link to="">

<router-view>

路由视图,用于渲染页面组件(其实相当于是占位符,当URL访问地址改变时,会在 <router-view> 位置渲染出对应的页面组件)

路由重定向

new VueRouter({
    routes: [
        {
            path: '/',
            redirect: '/home' // 重定向
        }
    ]
})

路由元信息

在路由定义时,添加 meta 的属性来定义路由元信息。

meta 作用:携带在开发过程中需要使用到的额外数据(和路由有关)

组件注入

在 Vue 根实例中注入 router 后,每个子组件中都被注入了 $router 与 $route 属性

  • $router 代表的是 VueRouter 的实例
  • $route 代表当前激活的路由(现在正在访问的路由)

命名视图

一个页面中可以使用多个 <router-view /> 组件,在使用多个该组件时,通常需要给各组件取 name 属性(命名视图),在一个路由中,不同的命名视图中渲染不同的路由组件,可以:

{
    path: '/home',
    name: 'home',
    components: {
        header: SearchBar,
        footer: Tabbar,
        default: Home
    }
}

嵌套路由

动态路由匹配

动态路径参数:是在路由路径后使用 : 定义的参数结构,如:/category/sub/:id

在组件中获取到路由中传递的动态路径参数值:$route 属性。在 $route 的 params 中保存了动态路径参数值

编程式导航

除了使用 <router-link> 创建 a 标签来定义导航链接,我们还可以借助 router 的实例方法,通过编写代码来实现。

  • r o u t e r . p u s h ( u r l ) − − 点 击 ‘ < r o u t e r − l i n k : t o = " " > ‘ 等 同 于 调 用 ‘ router.push(url) -- 点击 `<router-link :to="">` 等同于调用 ` router.push(url)<routerlink:to="">router.push(…)`
    • 说明:url 可以是字符串,也可以是对象。当是对象结构时,对象中可取的属性有:{path: '路径字符串'}{path: '路径', query: {查询字符串表示的对象}}{name: '命名路由名称', params: {动态路径参数表示的对象}}{name: '', query: {}}
    • 通过路由进行参数传递时,有动态路径参数与查询字符串参数两种方式。动态路径参数(/:id/:user)与 params 相关,而查询字符串参数(?key=value&key=value&key=value)与 query 相关
    • 如果提供了 pathparams 会被忽略

导航守卫

就是在路由切换过程中提供了一些钩子函数,供我们在切换过程中执行额外的业务逻辑。

全局

  • beforeEach() – 全局前置守卫,可以在全局前置守卫中判断用户的登录、权限逻辑
const router = new VueRouter({ ... })

router.beforeEach((to, from, next) => {
  // ...
  // to:去哪儿,要切换跳转到的路由
  // from:从哪儿来,是在切换跳转前的路由
  // next:函数,下一步
  // 注意,在导航守卫中通常都需要调用 next() 函数进入下一步解析执行。
  // 如果没有调用 next() 则中断路由解析过程。但最好每次都显式调用 next()
  // next() 在调用时:
  // next() -- 表示继续下一步正常的解析流程
  // next(false) -- 中断路由解析
  // next(urlString|urlObject) -- 下一步跳转到另一个导航中
  // next(error) -- error 是 Error 对象,终止导航,error 错误信息会被传递到 router.onError()
  // 对于 next() 函数的调用,确保在任何给定的导航守卫中都被严格调用一次,如果被调用了多次,则要么不执行,要么报错
})

  • beforeResolve() – 全局解析守卫
  • afterEach() – 全局后置钩子:钩子不会接受 next 函数也不会改变导航本身

路由独享

  • beforeEnter() – 在路由配置上直接定义

组件

  • beforeRouteEnter()
  • beforeRouteUpdate()
  • beforeRouteLeave()
const Foo = {
  template: `...`,
  beforeRouteEnter (to, from, next) {
    // 在渲染该组件的对应路由被 confirm 前调用
    // 不!能!获取组件实例 `this`
    // 因为当守卫执行前,组件实例还没被创建
  },
  beforeRouteUpdate (to, from, next) {
    // 在当前路由改变,但是该组件被复用时调用
    // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
    // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
    // 可以访问组件实例 `this`
  },
  beforeRouteLeave (to, from, next) {
    // 导航离开该组件的对应路由时调用
    // 可以访问组件实例 `this`
  }
}

Vuex

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

这种方式也是解决组件通信时所用到的一种方式。

全局的用户状态数据管理、全局语言选择、全局主题设置、换肤、购物车等功能可以使用 vuex 来实现管理。

概念

store – 仓库,采用集中式存储

state – 用于存储状态的对象(统一的将需要管理的所有组件的状态存放到 state 中)

mutation – 方法,用于同步更新状态(修改数据)。mutation 是唯一可以更新状态的地方。不能包含异步更新状态的动作。mutation 方法的调用不能直接调用,而是需要使用 store.commit(type, payload) 来提交 mutation(相当于就是调用 mutation 方法)。type 表示的是 mutation 类型(就是mutation方法名称),payload 表示有效载荷,就是在调用 mutation 方法时需要传递的额外数据。

action – 方法,用于更新状态(可同步,也可以异步),但在 action 中不能直接更新状态,而是需要通过提交 mutation 来更新状态的。

getter – 是 store 中关于 state 的派生数据,相当于就是组件中的 计算属性

module – 模块,可以将所有组件的状态管理分类,形成一个个独立的小的模块,然后组合成完整的功能模块。每个模块中都有自己的 state、getter、mutation、action,甚至于还可以有自己的子模块。

使用

安装

$ npm i vuex --save
# 或
$ yarn add vuex

创建 Store 对象实例

// 引入 Vue
import Vue from 'vue'
// 引入 vuex
import Vuex from 'vuex'

// 使用
Vue.use(Vuex)

// 创建 Store 对象实例
const store = new Vuex.Store({
  state: { // 状态、数据
    todos: []
  },
  mutations: {
    // 添加新待办事项
    addTodoItem(state, title) {
      state.todos.unshift({
        id: Math.random(),
        title,
        completed: false
      })
    }
  }
})

// 导出
export default store

关联 Vue 实例

import Vue from 'vue'
import store from './store'

new Vue({
  store,
  render: h => h(App)
}).$mount()

命名空间

默认情况下,所有 module 下定义的 action/mutation/getter都注册在全局命名空间下,当维护的模块较多时,可能会出现 action/mutation/getter 中命名冲突的问题,我们可以使用 namespace 命名空间(名字空间)来解决。

{
  modules: {
    user: {
      namespaced: true, // 启用命名空间
      state: {},
      getters: {}, // getters中的各属性就需要添加 'user' 命名空间前缀访问
      mutations: {}, // mutations中的各属性就需要添加 'user' 命名空间前缀访问
      actions:{ login(){} }
    }
  }  
}

例如在组件中使用到 action 中的 login() 时:

// 1. 
{
    created() {
        this.$store.dispatch('user/login')
    }
}
// 2.
import { mapActions } from 'vuex'
{
    careated() {
        this['user/login']()
    },
    methods: {
        ...mapActions(['user/login'])
    }
}
// 3.
import { mapActions } from 'vuex'
{
    careated() {
        this.login()
    },
    methods: {
        ...mapActions('user', ['login'])
    }
}
// 4.
import { createNamespacedHelpers } from 'vuex'
const { mapActions } = createNamespacedHelpers('user')
{
    careated() {
        this.login()
    },
    methods: {
        ...mapActions(['login'])
    }
}

课堂项目案例

电商–移动端

首页

分类

列表

详情

购物车

我的

登录

注册

UI组件库

移动端:vantmint-ui

PC端:Element-UIiview

使用

安装

$ npm i vant -S
# 或
$ yarn add vant

按需引入

$ npm i babel-plugin-import -D

安装 babel 插件:babel-plugin-import 。安装好插件后,修改 babel 的配置文件:

// babel.config.js 文件
module.exports = {
  presets: [
    '@vue/cli-plugin-babel/preset'
  ],
  plugins: [
    ['import', {
      libraryName: 'vant',
      libraryDirectory: 'es',
      style: true
    }, 'vant']
  ]
}

安装好 babel-plugin-import 后,一定要修改配置文件

登录权限业务

用户登录状态信息是利用 vuex 来实现管理

登录流程:

  • 进入登录页面,填写用户名密码信息,提交登录
  • 由于登录通常是异步任务(发 ajax 请求后端 api 接口),分发 store 的 action 方法来实现登录,并保存登录状态信息到 store 中(在 action 中 commit mutation 来实现保存)。在 action 中将用户登录成功或失败的信息返回登录页面
  • 在登录页面中,根据用户登录成功或失败的信息,跳转页面

权限控制:

结合 vue-router 的导航守卫来实现,用到了全局前置守卫: router.beforeEach((to, from, next) => {})。

判断流程:

  • 判断要切换到的路由是否需要登录权限
  • 如果需要登录的权限
    • 判断用户是否已登录
    • 如果已登录,则继续下一步解析
    • 如果用户未登录,则跳转到登录页面,完成登录流程
  • 如果不需要登录的权限,则继续下一步解析
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值