vue----第一个工程项目
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----第一个工程项目相关推荐
- 58 第一个工程项目(Celery)
上节的第一个Celery程序非常简单,实际的项目开发应该是模块化的,程序的功能分散在多个文件中,Celery也不例外.下面扩展第一个Celery程序. 新建myCeleryProj目录中新建__ini ...
- Vue 第一天学习 ---2018.06.28
Vue 第一天学习 ---2018.06.28 1.引包 2.学会控制元素.显示数据,基本框架建立 <title>Document</title> <script sr ...
- 每日三道前端面试题--vue 第一弹
每日三道面试题--vue 第一弹 1.对vue渐进式框架的理解 2.v-if 和v-show的区别 3.MVC.MVP和MVVM的区别 一.MVC 1.视图(View):用户界面. 2.控制器(Con ...
- Vue第一部分(2): 数据的渲染
插值表达式 数据绑定最常见的形式就是使用 {{值}} (双大括号)的文本插值: <div id="app"><h1>{{msg}}</h1>&l ...
- Vue第一部分(1):Vue简介以及第一个示例
Vue简介 Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的JavaScript框架.封装了原生的DOM操作,无需进行任何手动的DOM编码即可完成页面数据的渲染. MVVM模 ...
- 总结Vue第一天~简单介绍、基本知识、辅助函数和js数组的高阶函数
目录 vue中文官网 一.简单介绍: (1)vue.js :本质就是一个js 核心类库[跟咱使用的其他组件插件而安装他们]: ■ 安装方式: (2)小demo了解一下vue.js: (3)响应式: 二 ...
- Vue 第一天: 计算属性和观察者
计算属性和观察者 计算属性 模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的.在模板中放入太多的逻辑会让模板过重且难以维护.例如: <div id="example" ...
- 学习vue第一篇记录
首先,下载vue.js引入包里. 用到的文件可以从该网址引入:http://www.bootcdn.cn/vue/ 1.赋值 html: <div id="app" titl ...
- Vue — 第一天(极速入门)
基本介绍 vue是什么 目标:了解vue的一些基础概念. 官方网站: https://cn.vuejs.org/ vue是:渐进式javascript框架. 两组概念 (1)框架 库.只提供一些API ...
- Vue第一部分(6):Vue的生命周期
每个 Vue 实例在被创建时都要经过一系列的初始化过程 :创建实例,装载模板,渲染模板.销毁等.Vue为生命周期中的每个状态都设置了钩子函数(监听函数).当Vue实例处于不同的生命周期时,对应的函数就 ...
最新文章
- Windows 64位下为wampserver或phpstudy安装Redis扩展
- 为什么二进制保存的文件,打开仍然可以正常显示
- gRPC in ASP.NET Core 3.x -- Protocol Buffer, Go语言的例子(下)
- 前端学习(3226):回调形式的ref
- 一院士给博士生的一封信:每天工作12小时,这仅是一个下限!
- Qt文档阅读笔记-Qt Quick 3D - Simple Example解析
- C# 之 Excel 导入一列中既有汉字又有数字:数字可以正常导入,汉字导入为空
- 微信api中转站(用python搭建flask服务器)
- 全面对战LILO 和 GRUB
- iOS底层探索(十二)类的加载(中)
- WeiRuan DaBing
- 人脸识别之人脸关键点(仅供本人参考)
- 训练集样本不平衡问题对深度学习的影响
- 小确幸BBS论坛-1-前期准备
- 1139:整理药名(C C++)
- 【BZOJ4864】【BJWC2017】神秘物质 - Splay
- 计算机bios程序模拟器,怎么添加pcsx2 bios文件
- 动手学深度学习(tensorflow)---学习笔记整理(一、预备知识篇)
- 三个sata硬盘只能读取两个_两个SATA硬盘驱动器显示为可弹出
- 为了面试成功,社恐年轻人伪装“社牛”
热门文章
- asprise java_使用asprise进行图片验证码识别
- python中的string模块_有没有可能模仿Python中的string模块?
- map原理 java_RxJava的基本原理以及Map,flatMap的原理
- 【oracle】查看数据库最近执行了哪些sql语句
- 微信小程序 html modal,微信小程序参考微信设计规范做的modal模态框
- 计算机专业英语卷子,计算机专业英语A试卷.doc
- pgsql数据库默认配置事务类型_PostgreSQL数据库事务出现未知状态的处理方法
- CentOS7部署jar包
- android单选对话框代码,Android实现单选与多选对话框的代码
- linearlayout设置最大高度_一句话掌握一消建筑高度计算方法,先收藏!