1、创建工程

vue init webpack hello-vue

安装依赖

# 进入工程目录
cd hello-vue
# 安装 vue-router
npm install vue-router --save-dev
# 安装 element-ui
npm i element-ui -S
# 安装 SASS 加载器
npm install sass-loader node-sass --save-dev
# 安装依赖
npm install

NPM 相关命令说明

  • npm install moduleName:安装模块到项目目录下
  • npm install -g moduleName:-g 的意思是将模块安装到全局,具体安装到磁盘哪个位置,要看 npm config prefix 的位置
  • npm install -save moduleName:--save 的意思是将模块安装到项目目录下,并在 package 文件的 dependencies 节点写入依赖,-S 为该命令的缩写
  • npm install -save-dev moduleName:--save-dev 的意思是将模块安装到项目目录下,并在 package 文件的 devDependencies 节点写入依赖,-D 为该命令的缩写

启动工程

npm run dev

  

  

第一个 ElementUI 页面 (登录页)

主流框架

iView

iview 是一个强大的基于 Vue 的 UI 库,有很多实用的基础组件比 elementui 的组件更丰富,主要服务于 PC 界面的中后台产品。使用单文件的 Vue 组件化开发模式 基于 npm + webpack + babel 开发,支持 ES2015 高质量、功能丰富 友好的 API ,自由灵活地使用空间。

  • 官网地址
  • Github
  • iview-admin

备注:属于前端主流框架,选型时可考虑使用,主要特点是移动端支持较多

ElementUI

Element 是饿了么前端开源维护的 Vue UI 组件库,组件齐全,基本涵盖后台所需的所有组件,文档讲解详细,例子也很丰富。主要用于开发 PC 端的页面,是一个质量比较高的 Vue UI 组件库。

  • 官网地址
  • Github
  • vue-element-admin

备注:属于前端主流框架,选型时可考虑使用,主要特点是桌面端支持较多

创建视图

创建首页视图

在 views 目录下创建一个名为 Main.vue 的视图组件;该组件在当前章节无任何作用,主要用于登录后展示登录成功的跳转效果;

<template><div>首页</div>
</template><script>export default {name: "Main"}
</script><style scoped></style>

创建登录页视图

在 views 目录下创建一个名为 Login.vue 的视图组件,其中 el-* 的元素为 ElementUI 组件;

<template><div><el-form ref="loginForm" :model="form" :rules="rules" label-width="80px" class="login-box"><h3 class="login-title">欢迎登录</h3><el-form-item label="账号" prop="username"><el-input type="text" placeholder="请输入账号" v-model="form.username"/></el-form-item><el-form-item label="密码" prop="password"><el-input type="password" placeholder="请输入密码" v-model="form.password"/></el-form-item><el-form-item><el-button type="primary" v-on:click="onSubmit('loginForm')">登录</el-button></el-form-item></el-form><el-dialogtitle="温馨提示":visible.sync="dialogVisible"width="30%":before-close="handleClose"><span>请输入账号和密码</span><span slot="footer" class="dialog-footer"><el-button type="primary" @click="dialogVisible = false">确 定</el-button></span></el-dialog></div>
</template><script>export default {name: "Login",data() {return {form: {username: '',password: ''},// 表单验证,需要在 el-form-item 元素中增加 prop 属性rules: {username: [{required: true, message: '账号不可为空', trigger: 'blur'}],password: [{required: true, message: '密码不可为空', trigger: 'blur'}]},// 对话框显示和隐藏dialogVisible: false}},methods: {onSubmit(formName) {// 为表单绑定验证功能this.$refs[formName].validate((valid) => {if (valid) {// 使用 vue-router 路由到指定页面,该方式称之为编程式导航this.$router.push("/main");} else {this.dialogVisible = true;return false;}});}}}
</script><style lang="scss" scoped>.login-box {border: 1px solid #DCDFE6;width: 350px;margin: 180px auto;padding: 35px 35px 15px 35px;border-radius: 5px;-webkit-border-radius: 5px;-moz-border-radius: 5px;box-shadow: 0 0 25px #909399;}.login-title {text-align: center;margin: 0 auto 40px auto;color: #303133;}
</style>

创建路由

在 router 目录下创建一个名为 index.js 的 vue-router 路由配置文件

import Vue from 'vue'
import Router from 'vue-router'import Login from "../views/Login"
import Main from '../views/Main'Vue.use(Router);export default new Router({routes: [{// 登录页path: '/login',name: 'Login',component: Login},{// 首页path: '/main',name: 'Main',component: Main}]
});

配置路由

修改入口代码

修改 main.js 入口代码

import Vue from 'vue'
import VueRouter from 'vue-router'
import router from './router'// 导入 ElementUI
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'import App from './App'// 安装路由
Vue.use(VueRouter);// 安装 ElementUI
Vue.use(ElementUI);new Vue({el: '#app',// 启用路由router,// 启用 ElementUIrender: h => h(App)
});

修改 App.vue 组件代码

<template><div id="app"><router-view/></div>
</template><script>export default {name: 'App',}
</script>

  

2、配置嵌套路由

什么是嵌套路由

嵌套路由又称子路由,在实际应用中,通常由多层嵌套的组件组合而成。同样地,URL 中各段动态路径也按某种结构对应嵌套的各层组件。

创建嵌套视图组件

用户信息组件

在 views/user 目录下创建一个名为 Profile.vue 的视图组件;该组件在当前章节无任何作用,主要用于展示嵌套效果;

<template><div>个人信息</div>
</template><script>export default {name: "UserProfile"}
</script><style scoped></style>

用户列表组件

在 views/user 目录下创建一个名为 List.vue 的视图组件;该组件在当前章节无任何作用,主要用于展示嵌套效果;

<template><div>用户列表</div>
</template><script>export default {name: "UserList"}
</script><style scoped></style>

  

配置嵌套路由

修改 router 目录下的 index.js 路由配置文件,代码如下:

import Vue from 'vue'
import Router from 'vue-router'import Login from "../views/Login"
import Main from '../views/Main'// 用于嵌套的路由组件
import UserProfile from '../views/user/Profile'
import UserList from '../views/user/List'Vue.use(Router);export default new Router({routes: [{// 登录页path: '/login',name: 'Login',component: Login},{// 首页path: '/main',name: 'Main',component: Main,// 配置嵌套路由children: [{path: '/user/profile', component: UserProfile},{path: '/user/list', component: UserList},]}]
});

  说明:主要在路由配置中增加了 children 数组配置,用于在该组件下设置嵌套路由

修改首页视图

接着上一节的代码,我们修改 Main.vue 视图组件,此处使用了 ElementUI 布局容器组件,代码如下:

<template><div><el-container><el-aside width="200px"><el-menu :default-openeds="['1']"><el-submenu index="1"><template slot="title"><i class="el-icon-caret-right"></i>用户管理</template><el-menu-item-group><el-menu-item index="1-1"><router-link to="/user/profile">个人信息</router-link></el-menu-item><el-menu-item index="1-2"><router-link to="/user/list">用户列表</router-link></el-menu-item></el-menu-item-group></el-submenu><el-submenu index="2"><template slot="title"><i class="el-icon-caret-right"></i>内容管理</template><el-menu-item-group><el-menu-item index="2-1">分类管理</el-menu-item><el-menu-item index="2-2">内容列表</el-menu-item></el-menu-item-group></el-submenu></el-menu></el-aside><el-container><el-header style="text-align: right; font-size: 12px"><el-dropdown><i class="el-icon-setting" style="margin-right: 15px"></i><el-dropdown-menu slot="dropdown"><el-dropdown-item>个人信息</el-dropdown-item><el-dropdown-item>退出登录</el-dropdown-item></el-dropdown-menu></el-dropdown><span>Lusifer</span></el-header><el-main><router-view /></el-main></el-container></el-container></div>
</template><script>export default {name: "Main"}
</script><style scoped lang="scss">.el-header {background-color: #B3C0D1;color: #333;line-height: 60px;}.el-aside {color: #333;}
</style>

说明:

  • 在 <el-main> 元素中配置了 <router-view /> 用于展示嵌套路由
  • 主要使用 <router-link to="/user/profile">个人信息</router-link> 展示嵌套路由内容

3、参数传递

概述

我们经常需要把某种模式匹配到的所有路由,全都映射到同个组件。例如,我们有一个 User 组件,对于所有 ID 各不相同的用户,都要使用这个组件来渲染。此时我们就需要传递参数了;

使用路径匹配的方式

修改路由配置

{path: '/user/profile/:id', name:'UserProfile', component: UserProfile}

  说明:主要是在 path 属性中增加了 :id 这样的占位符

传递参数

router-link

<router-link :to="{name: 'UserProfile', params: {id: 1}}">个人信息</router-link>

说明:此时我们将 to 改为了 :to,是为了将这一属性当成对象使用,注意 router-link 中的 name 属性名称 一定要和 路由中的 name 属性名称 匹配,因为这样 Vue 才能找到对应的路由路径;

代码方式

this.$router.push({ name: 'UserProfile', params: {id: 1}});  

接收参数

在目标组件中使用

{{ $route.params.id }}  

使用 props 的方式

修改路由配置

{path: '/user/profile/:id', name:'UserProfile', component: UserProfile, props: true}

  说明:主要增加了 props: true 属性

传递参数

同上

接收参数

为目标组件增加 props 属性,代码如下:

 export default {props: ['id'],name: "UserProfile"}

模板中使用

{{ id }}

  

4、组件重定向

配置重定向

修改路由配置

{path: '/main',name: 'Main',component: Main
},
{path: '/goHome',redirect: '/main'
}

  说明:这里定义了两个路径,一个是 /main ,一个是 /goHome,其中 /goHome 重定向到了 /main 路径,由此可以看出重定向不需要定义组件;

重定向到组件

设置对应路径即可

<router-link to="/goHome">回到首页</router-link>

  

带参数的重定向

修改路由配置

{// 首页path: '/main/:username',name: 'Main',component: Main},{path: '/goHome/:username',redirect: '/main/:username'
}  

重定向到组件

<router-link to="/goHome/Lusifer">回到首页</router-link>

  

5、路由模式与 404

路由模式

路由模式有两种

  • hash:路径带 # 符号,如 http://localhost/#/login
  • history:路径不带 # 符号,如 http://localhost/login

修改路由配置,代码如下:

export default new Router({mode: 'history',routes: []
});

处理 404

创建一个名为 NotFound.vue 的视图组件,代码如下:

<template><div>页面不存在,请重试!</div>
</template><script>export default {name: "NotFount"}
</script><style scoped></style>

修改路由配置,代码如下:

    {path: '*',component: NotFound}

  

6、路由钩子与异步请求

路由中的钩子函数

  • beforeRouteEnter:在进入路由前执行
  • beforeRouteLeave:在离开路由前执行

案例代码如下:

export default {props: ['id'],name: "UserProfile",beforeRouteEnter: (to, from, next) => {console.log("准备进入个人信息页");next();},beforeRouteLeave: (to, from, next) => {console.log("准备离开个人信息页");next();}}

参数说明:

  • to:路由将要跳转的路径信息
  • from:路径跳转前的路径信息
  • next:路由的控制参数
    • next() 跳入下一个页面
    • next('/path') 改变路由的跳转方向,使其跳到另一个路由
    • next(false) 返回原来的页面
    • next((vm)=>{}) 仅在 beforeRouteEnter 中可用,vm 是组件实例

在钩子函数中使用异步请求

安装 Axios

npm install axios -s

引用 Axios(修改main.js)

import axios from 'axios'
Vue.prototype.axios = axios;

在 beforeRouteEnter 中进行异步请求,案例代码如下:

  export default {props: ['id'],name: "UserProfile",beforeRouteEnter: (to, from, next) => {console.log("准备进入个人信息页");// 注意,一定要在 next 中请求,因为该方法调用时 Vue 实例还没有创建,此时无法获取到 this 对象,在这里使用官方提供的回调函数拿到当前实例next(vm => {vm.getData();});},beforeRouteLeave: (to, from, next) => {console.log("准备离开个人信息页");next();},methods: {getData: function () {this.axios({method: 'get',url: 'http://localhost:8080/data.json'}).then(function (repos) {console.log(repos);}).catch(function (error) {console.log(error);});}}}

  

Vuex 快速入门

简介

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

目标

继续之前 vue-router 章节做的案例项目,我们通过完善登录功能将用户信息保存至 Vuex 中来体会它的作用;

安装

在项目根目录执行如下命令来安装 Vuex

判断用户是否登录

我们利用路由钩子 beforeEach 来判断用户是否登录,期间会用到 sessionStorage 存储功能

修改 Login.vue

在表单验证成功方法内增加如下代码:

// 设置用户登录成功
sessionStorage.setItem('isLogin', 'true');

修改 main.js

利用路由钩子 beforeEach 方法判断用户是否成功登录,关键代码如下:

// 在跳转前执行
router.beforeEach((to, form, next) => {// 获取用户登录状态let isLogin = sessionStorage.getItem('isLogin');// 注销if (to.path == '/logout') {// 清空sessionStorage.clear();// 跳转到登录next({path: '/login'});}// 如果请求的是登录页else if (to.path == '/login') {if (isLogin != null) {// 跳转到首页next({path: '/main'});}}// 如果为非登录状态else if (isLogin == null) {// 跳转到登录页next({path: '/login'});}// 下一个路由next();
});

配置 vuex

创建 Vuex 配置文件

在 src 目录下创建一个名为 store 的目录并新建一个名为 index.js 文件用来配置 Vuex,代码如下:

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex);// 全局 state 对象,用于保存所有组件的公共数据
const state = {// 定义一个 user 对象// 在组件中是通过 this.$store.state.user 来获取user: {username: ''}
};// 实时监听 state 值的最新状态,注意这里的 getters 可以理解为计算属性
const getters = {// 在组件中是通过 this.$store.getters.getUser 来获取,页面上使用{{$store.getters.getUser.username}}来获取getUser(state) {return state.user;}
};// 定义改变 state 初始值的方法,这里是唯一可以改变 state 的地方,缺点是只能同步执行
const mutations = {// 在组件中是通过 this.$store.commit('updateUser', user); 方法来调用 mutationsupdateUser(state, user) {state.user = user;}
};// 定义触发 mutations 里函数的方法,可以异步执行 mutations 里的函数
const actions = {// 在组件中是通过 this.$store.dispatch('asyncUpdateUser', user); 来调用 actionsasyncUpdateUser(context, user) {context.commit('updateUser', user);}
};export default new Vuex.Store({state,getters,mutations,actions
});

修改 main.js 增加刚才配置的 store/index.js,关键代码如下:

import Vue from 'vue'
import Vuex from 'vuex'
import store from './store'Vue.use(Vuex);new Vue({el: '#app',store
});

解决浏览器刷新后 Vuex 数据消失问题

问题描述

Vuex 的状态存储是响应式的,当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。但是有一个问题就是:vuex 的存储的数据只是在页面的中,相当于我们定义的全局变量,刷新之后,里边的数据就会恢复到初始化状态。但是这个情况有时候并不是我们所希望的。

解决方案

监听页面是否刷新,如果页面刷新了,将 state 对象存入到 sessionStorage 中。页面打开之后,判断 sessionStorage 中是否存在 state 对象,如果存在,则说明页面是被刷新过的,将 sessionStorage 中存的数据取出来给 vuex 中的 state 赋值。如果不存在,说明是第一次打开,则取 vuex 中定义的 state 初始值。

修改代码

在 App.vue 中增加监听刷新事件

 export default {name: 'App',mounted() {window.addEventListener('unload', this.saveState);},methods: {saveState() {sessionStorage.setItem('state', JSON.stringify(this.$store.state));}}}

修改 store/index.js 中的 state

const state = sessionStorage.getItem('state') ? JSON.parse(sessionStorage.getItem('state')) : {user: {username: ''}
}; 

模块化

由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割

创建 user 模块

在 store 目录下创建一个名为 modules 的目录并创建一个名为 user.js 的文件,代码如下:

const user = {// 因为模块化了,所以解决刷新问题的代码需要改造一下state: sessionStorage.getItem('userState') ? JSON.parse(sessionStorage.getItem('userState')) : {user: {username: ''}},getters: {getUser(state) {return state.user;}},mutations: {updateUser(state, user) {state.user = user;}},actions: {asyncUpdateUser(context, user) {context.commit('updateUser', user);}}
};export default user;

修改 store/index.js

import Vue from 'vue'
import Vuex from 'vuex'import user from './modules/user'Vue.use(Vuex);export default new Vuex.Store({modules: {// this.$store.state.useruser}
});

备注:由于组件中使用的是 getters 和 actions 处理,所以调用代码不变

修改 App.vue

 export default {name: 'App',mounted() {window.addEventListener('unload', this.saveState);},methods: {saveState() {// 模块化后,调用 state 的代码修改为 this.$store.state.user(需要定位到user这个对象)sessionStorage.setItem('userState', JSON.stringify(this.$store.state.user));}}}

  

转载于:https://www.cnblogs.com/yanxiaoge/p/11104586.html

vue----第一个工程项目相关推荐

  1. 58 第一个工程项目(Celery)

    上节的第一个Celery程序非常简单,实际的项目开发应该是模块化的,程序的功能分散在多个文件中,Celery也不例外.下面扩展第一个Celery程序. 新建myCeleryProj目录中新建__ini ...

  2. Vue 第一天学习 ---2018.06.28

    Vue  第一天学习 ---2018.06.28 1.引包 2.学会控制元素.显示数据,基本框架建立 <title>Document</title> <script sr ...

  3. 每日三道前端面试题--vue 第一弹

    每日三道面试题--vue 第一弹 1.对vue渐进式框架的理解 2.v-if 和v-show的区别 3.MVC.MVP和MVVM的区别 一.MVC 1.视图(View):用户界面. 2.控制器(Con ...

  4. Vue第一部分(2): 数据的渲染

    插值表达式 数据绑定最常见的形式就是使用 {{值}} (双大括号)的文本插值: <div id="app"><h1>{{msg}}</h1>&l ...

  5. Vue第一部分(1):Vue简介以及第一个示例

    Vue简介 Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的JavaScript框架.封装了原生的DOM操作,无需进行任何手动的DOM编码即可完成页面数据的渲染. MVVM模 ...

  6. 总结Vue第一天~简单介绍、基本知识、辅助函数和js数组的高阶函数

    目录 vue中文官网 一.简单介绍: (1)vue.js :本质就是一个js 核心类库[跟咱使用的其他组件插件而安装他们]: ■ 安装方式: (2)小demo了解一下vue.js: (3)响应式: 二 ...

  7. Vue 第一天: 计算属性和观察者

    计算属性和观察者 计算属性 模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的.在模板中放入太多的逻辑会让模板过重且难以维护.例如: <div id="example" ...

  8. 学习vue第一篇记录

    首先,下载vue.js引入包里. 用到的文件可以从该网址引入:http://www.bootcdn.cn/vue/ 1.赋值 html: <div id="app" titl ...

  9. Vue — 第一天(极速入门)

    基本介绍 vue是什么 目标:了解vue的一些基础概念. 官方网站: https://cn.vuejs.org/ vue是:渐进式javascript框架. 两组概念 (1)框架 库.只提供一些API ...

  10. Vue第一部分(6):Vue的生命周期

    每个 Vue 实例在被创建时都要经过一系列的初始化过程 :创建实例,装载模板,渲染模板.销毁等.Vue为生命周期中的每个状态都设置了钩子函数(监听函数).当Vue实例处于不同的生命周期时,对应的函数就 ...

最新文章

  1. Windows 64位下为wampserver或phpstudy安装Redis扩展
  2. 为什么二进制保存的文件,打开仍然可以正常显示
  3. gRPC in ASP.NET Core 3.x -- Protocol Buffer, Go语言的例子(下)
  4. 前端学习(3226):回调形式的ref
  5. 一院士给博士生的一封信:每天工作12小时,这仅是一个下限!
  6. Qt文档阅读笔记-Qt Quick 3D - Simple Example解析
  7. C# 之 Excel 导入一列中既有汉字又有数字:数字可以正常导入,汉字导入为空
  8. 微信api中转站(用python搭建flask服务器)
  9. 全面对战LILO 和 GRUB
  10. iOS底层探索(十二)类的加载(中)
  11. WeiRuan DaBing
  12. 人脸识别之人脸关键点(仅供本人参考)
  13. 训练集样本不平衡问题对深度学习的影响
  14. 小确幸BBS论坛-1-前期准备
  15. 1139:整理药名(C C++)
  16. 【BZOJ4864】【BJWC2017】神秘物质 - Splay
  17. 计算机bios程序模拟器,怎么添加pcsx2 bios文件
  18. 动手学深度学习(tensorflow)---学习笔记整理(一、预备知识篇)
  19. 三个sata硬盘只能读取两个_两个SATA硬盘驱动器显示为可弹出
  20. 为了面试成功,社恐年轻人伪装“社牛”

热门文章

  1. asprise java_使用asprise进行图片验证码识别
  2. python中的string模块_有没有可能模仿Python中的string模块?
  3. map原理 java_RxJava的基本原理以及Map,flatMap的原理
  4. 【oracle】查看数据库最近执行了哪些sql语句
  5. 微信小程序 html modal,微信小程序参考微信设计规范做的modal模态框
  6. 计算机专业英语卷子,计算机专业英语A试卷.doc
  7. pgsql数据库默认配置事务类型_PostgreSQL数据库事务出现未知状态的处理方法
  8. CentOS7部署jar包
  9. android单选对话框代码,Android实现单选与多选对话框的代码
  10. linearlayout设置最大高度_一句话掌握一消建筑高度计算方法,先收藏!