vue的学习心得体会
第一章vue的介绍... 31.1vue的介绍... 31.1.1 什么是vue. 31.1.2 MVVM的概念... 31.2创建vue实例... 41.2.1引入vue.js. 41.2.2创建一个vue实例... 41.3vue的生命周期函数... 51.4 vue指令... 81.4.1 属性绑定指令v-bind. 81.4.2事件绑定属性v-...
- vue的介绍
1.1vue的介绍
1.1.1 什么是vue
Vue.js被定义为一个开发web界面的前端库,是一个非常轻量级的工具。本身具有响应式编程和组件化的特点。
在Vue中,一个核心的概念,就是让用户不再操作DOM元素,解放了用户的双手,让程序员可以更多的时间去关注业务逻辑。
1.1.2 MVVM的概念
MVVM是前端视图层的概念,主要关注于视图层分离,也就是说:MVVM把前端的视图层,分为了三部分 Model, View , ViewModel。
1.2创建vue实例
1.2.1引入vue.js
要使用vue,首先要引入它的js库。
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script> |
1.2.2创建一个vue实例
(1)首先我们需要在body里面id=”app”的div元素,这里是vue实例化后所控制的区域
(2)在<script></script>标签中实例化一个vue,其中el属性指向的是要操作的区域,data属性存放的是el要用到的数据。通过插值表达式{{msg}}很方便就能把数据渲染到页面上,不用手动去操作dom元素了。
<body> <div id="app"> <p>{{ msg }}</p> </div>
<script> var vm = new Vue({ el: '#app', data: { msg: '欢迎学习Vue' } }) </script> </body> |
1.3vue的生命周期函数
每个 Vue 实例在被创建时都要经过一系列的初始化过程。在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会。当我们在程序中要默认加载一些数据时候,则可以考虑使用生命周期函数。
我们可以用代码来演示各个函数在什么阶段开始执行(注意:在vue中methods要使用data的数据,必须加上this)
<div id="app"> <input type="button" value="修改msg" @click="msg='No'"> <h3 id="h3">{{ msg }}</h3> </div> <script> var vm = new Vue({ el: '#app', data: { msg: 'ok' }, methods: { show() { console.log('执行了show方法') } }, beforeCreate() { console.log("1:"+this.msg) this.show() }, created() { console.log("2:"+this.msg) this.show() }, beforeMount() { console.log("3:"+document.getElementById('h3').innerText) }, mounted() { console.log("4:"+document.getElementById('h3').innerText) }, beforeUpdate() { console.log('界面上元素的内容:' + document.getElementById('h3').innerText) console.log('data 中的 msg 数据是:' + this.msg) }, updated() { console.log('界面上元素的内容:' + document.getElementById('h3').innerText) console.log('data 中的 msg 数据是:' + this.msg) } }); </script> |
我们可以打开控制台观察到:
于是我们可以得出:
- beforeCreate 生命周期函数执行的时候,data 和 methods 中的 数据都还没有没初始化;
- 在 created中,data 和 methods 都已经被初始化好了。
- 在 beforeMount 执行的时候,尚未把模板渲染到页面中,只是之前写的一些模板字符串。
- 当执行完 mounted 就表示,实例已经被完全创建好了,此时,如果没有其它操作的话,这个实例,就静静的躺在我们的内存中,一动不动。
点击按钮进行修改msg的值,在控制台我们可以看到:
因此,我们可以得到:
当执行 beforeUpdate 的时候,页面中的显示的数据,还是旧的,此时data数据是最新的,页面尚未和最新的数据保持同步。updated 事件执行的时候,页面和data 数据已经保持同步了,都是最新的。
1.4 vue指令
指令 (Directives) 是带有 v- 前缀的特殊特性。指令的职责是,当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM。
1.4.1 属性绑定指令v-bind
主要是用来绑定元素的一些基本属性,比如我想绑定input元素的title属性,那么我们就可以使用v-bind属性来实现。(它也可以缩写为 :),这样我们就可以在方法中动态修改这个title属性。
<input type="button" value="按钮" v-bind:title="mytitle "> <input type="button" value="按钮" :title="mytitle ">//两者是一样的
<script> var vm = new Vue({ el: '#app', data: { mytitle: '这是一个自己定义的title' } }) </script> |
1.4.2事件绑定属性v-on
当我们想给元素添加触发的事件或者方法时,比如给button加上一个click事件,那么我们就需要使用v-on:click的指令,缩写(@click)
<input type="button" value="按钮" @click="show"> |
在vue中提供了methods属性,主要写一些方法,数据的操作逻辑。
var vm = new Vue({ el: '#app', data: { }, methods: { // 这个 methods属性中定义了当前Vue实例所有可用的方法 show: function () { alert('Hello') } } }) 它等同于document.getElementById(id).onclick = function(){ alert('Hello')} |
1.4.3数据的双向绑定v-model
Vue的核心就是实现了数据的双向绑定,前面我们知道了v-bind可以实现数据的绑定,但它是单向的,而v-model可以实现data的数据和表单元素的双向绑定,在开发中我们肯定需要拿到页面上的值去和后端进行交互,这时候便可以很方便的使用v-model。注意: v-model 只能运用在表单元素中。
<div id="app"> <h4>{{ msg }}</h4> <input type="text" style="width:100%;" v-model="msg"> </div>
var vm = new Vue({ el: '#app', data: { msg: '欢迎来到太平洋信用卡中心' }, methods: { } }); |
当你在input中输入内容时,差值表达式{{msg}}即data的值也是同步变化的。
1.4.4 v-for和key属性
v-for的指令主要的作用是遍历。
1.循环普通的数组
比如现在有个list数组,我需要在页面上遍历展示出来:
(1)第一种方法:
<div id="app"> <p>{{list[0]}}</p> <p>{{list[1]}}</p> <p>{{list[2]}}</p> <p>{{list[3]}}</p> <p>{{list[4]}}</p> </div>
<script> var vm = new Vue({ el: '#app', data: { list: [1, 2, 3, 4, 5, 6] } }); </script> |
(2)第二种使用v-for
<p v-for="(item, i) in list">索引值:{{i}} --- 每一项:{{item}}</p> |
2.循环对象数组
<div id="app"> <p v-for="(user, i) in list">Id:{{ user.id }} --- 名字:{{ user.name }} --- 索引:{{i}}</p> </div>
<script> var vm = new Vue({ el: '#app', data: { list: [ { id: 1, name: 'zs1' }, { id: 2, name: 'zs2' }, { id: 3, name: 'zs3' }, { id: 4, name: 'zs4' } ] }, methods: {} }); </script> |
3.循环对象
在遍历对象身上的键值对的时候,除了有val ,key在第三个位置还有一个索引。
<div id="app"> <p v-for="(val, key, i) in user">值是: {{ val }} --- 键是: {{key}} -- 索引: {{i}}</p> </div>
<script> var vm = new Vue({ el: '#app', data: { user: { id: 1, name: '小明', gender: '男' } }, methods: {} }); </script> |
4.key属性的使用
(1)v-for 循环的时候,key 属性只能使用 number获取string
(2) key 在使用的时候,必须使用 v-bind 属性绑定的形式,指定 key 的值
(3)在组件中,使用v-for循环的时候,或者在一些特殊情况中,如果 v-for 有问题,必须 在使用 v-for 的同时,指定 唯一的 字符串/数字 类型 :key 值
<div id="app"> <div> <label>Id: <input type="text" v-model="id"> </label> <label>Name: <input type="text" v-model="name"> </label> <input type="button" value="添加" @click="add"> </div> <p v-for="item in list" :key="item.id"> <input type="checkbox">{{item.id}} --- {{item.name}} </p> </div> <script> var vm = new Vue({ el: '#app', data: { id: '', name: '', list: [ { id: 1, name: '小交' }, { id: 2, name: '小通' }, { id: 3, name: '小银' }, { id: 4, name: '小行' } ] }, methods: { add() { this.list.unshift({ id: this.id, name: this.name }) } } }); |
1.4.5 v-if和v-show
v-if和v-show可以实现元素的显示和隐藏。
<div id="app"> <input type="button" value="toggle" @click="flag=!flag"> <h3 v-if="flag">这是用v-if控制的元素</h3> <h3 v-show="flag">这是用v-show控制的元素</h3> </div> <script> var vm = new Vue({ el: '#app', data: { flag: false } }); </script> |
两者的区别是:
(1)v-if 的特点:每次都会重新删除或创建元素
v-show 的特点: 每次不会重新进行DOM的删除和创建操作,只是切换了元素的 display:none 样式
(2)v-if 有较高的切换性能消耗
v-show 有较高的初始渲染消耗
(3)如果元素涉及到频繁的切换,最好不要使用 v-if, 而是推荐使用 v-show
如果元素可能永远也不会被显示出来被用户看到,则推荐使用 v-if
1.5过滤器
开发中我们有时候需要固定的参数格式,比如时间、邮箱等,一方面你可以使用验证函数,另一方面你可以使用vue提供的过滤器。Vue.js允许在表达式后添加过滤器,用管道符“|”表示。过滤器的本质是一个函数,接受管道符前面作为初始值,同时也能接受额外的参数,返回的值为经过处理后的输出值。多个过滤器可以进行串联。
<div id="app"> <p>{{msg}}</p> <p>{{msg | msgFormat}}</p> <p>{{msg | replaseMsg('招商')}}</p> <p>{{msg | replaseMsg('招商') | msgFormat}}</p> </div> <script> var vm = new Vue({ el: '#app', data: { msg: '交通银行信用卡中心' }, methods: {}, filters:{ msgFormat(value){ return value+"欢迎您!" }, replaseMsg(value,arg1){ return value.replace('交通',arg1) } } }); </script> |
1.6组件
为了解决代码复用问题,vue也有一套自己的组件系统,通过自定义的标签以及对原生HTML元素的拓展实现组件化。
1.6.1全局组件的注册
全局组件可以在可以在整个项目的任何地方使用。比如后面要说到的axios,route等。
(1)使用Vue.extend 来创建全局的Vue组件
var com1 = Vue.extend({ template: '<h3>这是使用 Vue.extend 创建的组件</h3>' }) |
通过 template 属性,指定了组件要展示的HTML结构,但此时只是通过组件构造器创建了一个组件,还需要将组件注册到应用中。
(2)使用 Vue.component('组件的名称', 创建出来的组件模板对象)
Vue.component('mycom1', com1) |
如果使用 Vue.component 定义全局组件的时候,组件名称使用了驼峰命名,则在引用组件的时候,需要把 大写的驼峰改为小写的字母,同时,两个单词之前,使用 - 链接;如果不使用驼峰,则直接拿名称来使用即可;
当然上述代码可以简化成:
Vue.component('mycom1', Vue.extend({ template: '<h3>这是使用 Vue.extend 创建的组件</h3>' })) |
再进一步我们也可以写成:
Vue.component('mycom1', { template: '<h3>这是使用 Vue.extend 创建的组件</h3>' }) |
整个使用方法代码如下:
<div id="app"> <mycom1></mycom1> </div> <script> var com1 = Vue.extend({ template: '<h3>这是使用 Vue.extend 创建的组件</h3>' }) Vue.component('mycom1', com1) var vm = new Vue({ el: '#app', data: {}, methods: {} }); </script> |
(3)使用这是通过 template 元素,在div控制的外部定义的组件结构
<div id="app"> <mycom3></mycom3> </div> <template id="tmpl"> <div> <h1>这是通过 template 元素,在外部定义的组件结构</h1> </div> </template> <script> Vue.component('mycom3', { template: '#tmpl' }) var vm = new Vue({ el: '#app', data: {}, methods: {} }); </script> |
1.6.2局部组件的注册
局部组件只能在被注册的组件中使用,而无法在其他组件中使用。而全局注册的组件可以在任何地方使用。
<div id="app"> <mycom3></mycom3> <login></login> </div> <div id="app2"> <mycom3></mycom3> <login></login> </div> <template id="tmp1"> <div> <h1>这是通过 template 元素,在外部定义的组件结构</h1> </div> </template> <template id="tmpl2"> <h1>这是私有的 login组件</h1> </template>
<script> Vue.component('mycom3', { template: '#tmp1' }) var vm = new Vue({ el: '#app', data: {}, methods: {} }); var vm2 = new Vue({ el: '#app2', data: {}, methods: {}, filters: {}, directives: {}, components: { // 定义实例内部私有组件的 login: { template: '#tmpl2' } }, }) </script> |
此时我们可以看到控制台报一个错
注意:
1. 组件可以有自己的 data 数据
2. 组件的 data 和 实例的 data 有点不一样,实例中的 data 可以为一个对象,但是组件中的 data 必须是一个方法
3. 组件中的 data 除了必须为一个方法之外,这个方法内部,还必须返回一个对象才行;
4. 组件中 的data 数据,使用方式,和实例中的 data 使用方式完全一样
1.6.3父组件向子组件传值
首先我们看一张图:
组件的作用域是孤立的,也就是说子组件是无法直接调用父组件的数据的,因此需要通过props将父组件的数据传递给子组件。
父组件,可以在引用子组件的时候,通过属性绑定(v-bind:)的形式, 把需要传递给子组件的数据,以属性绑定的形式,传递到子组件内部,供子组件使用;而子组件先在 props 数组中,定义一下,这样才能使用这个数据。
<div id="app"> <com1 v-bind:parentmsg="msg"></com1> </div>
<script> var vm = new Vue({ el: '#app', data: { msg: '父组件中的数据' }, methods: {}, components: { com1: { data() { return { } }, template: '<h1 >这是子组件 --- {{ parentmsg }}</h1>', props: ['parentmsg'], components: {} } } }); </script> |
1.6.4子组件向父组件传值
项目开发中肯定也有子组件向父组件传值的情况,比如:
如果我们想子组件调用父组件的方法,那么就需要事件绑定机制v-on,子组件就能够通过某些方式,来调用传递进去的这个方法了。即使用$emit()方法。这个方法可以传两个参数,第一个固定是父组件绑定的事件名,而第二个是自定义的,因此我们可以把子组件的的数据放到第二个参数上,实现子组件向父组件传值。
<div id="app"> <com2 @func="show"></com2> </div> <template id="tmpl"> <div> <h1>这是子组件</h1> <input type="button" value="触发父组件传递过来的 func 方法" @click="myclick"> </div> </template> <script> var com2 = { template: '#tmpl', data() { return { sonmsg: { name: '小头儿子', age: 6 } } }, methods: { myclick() { this.$emit('func', this.sonmsg) } } } // 创建 Vue 实例,得到 ViewModel var vm = new Vue({ el: '#app', data: { datamsgFormSon: null }, methods: { show(data) { console.log(data); this.datamsgFormSon = data } },
components: { com2: com2 } }); </script> |
控制台显示:
1.7通过ref获取dom元素
当你想动态去操作dom元素时,比如动态添加css样式,此时肯定要获取这个dom元素。
在vue中如果想获取dom元素,那么可以通过ref属性来获取。
<div id="app"> <input type="button" value="获取元素" @click="getElement" ref="mybtn"> <h3 id="myh3" ref="myh3">哈哈哈, 今天天气太好了!!!</h3> </div> <script> var vm = new Vue({ el: '#app', data: {}, methods: { getElement() { console.log("原生获取:"+document.getElementById('myh3').innerText) console.log("ref获取:"+this.$refs.myh3.innerText) } } }); |
1.8路由
vue常用于开发单页面应用,要想实现页面间的跳转和切换就要用到路由了。
推荐网址:http://www.cnblogs.com/avon/p/5943008.html
官方文档: https://router.vuejs.org/zh-cn/essentials/getting-started.html
1.8.1路由的基本使用
1. 导入 vue-router 组件类库;
2. 使用 router-link 组件来导航;
<router-link to="/login">登录</router-link> <router-link to="/register">注册</router-link> |
3. 使用 router-view 组件来显示匹配到的组件。
具体代码如下:
<div id="app"> <router-link to="/login" >登录</router-link> <router-link to="/register">注册</router-link> <router-view></router-view> </div>
<script> // 组件的模板对象 var login = { template: '<h1>登录组件</h1>' }
var register = { template: '<h1>注册组件</h1>' } var routerObj = new VueRouter({ routes: [ { path: '/', redirect: '/login' }, { path: '/login', component: login }, { path: '/register', component: register } ], }) var vm = new Vue({ el: '#app', data: {}, methods: {}, router: routerObj }); </script> |
routes路由匹配规则,每一条路由规则都是一个对象,它必须包含两个属性path和component。
1.8.2路由传参
之前我们说了父子组件的传值,当然有时候两个组件并不是父子关系,但是需要传递一些简单的参数时,比如我登录成功,我需要在某一个组件中使用账号信息,这时候可以用路由传参的方式快速解决问题。
1.通过$route.query
<div id="app"> <router-link to="/login?id=10&name=zs">登录</router-link> <router-link to="/register">注册</router-link> <router-view></router-view> </div> <script> var login = { template: '<h1>登录 --- {{ $route.query.id }} --- {{ $route.query.name }}</h1>', data(){ return { } }, created(){ // 组件的生命周期钩子函数 console.log(this.$route) console.log(this.$route.query.id) } } var register = { template: '<h1>注册</h1>' } var router = new VueRouter({ routes: [ { path: '/login', component: login }, { path: '/register', component: register } ] }) var vm = new Vue({ el: '#app', data: {}, methods: {}, router }); </script> |
可以看到控制台的打印信息如下:
我们可以看到route是一个json对象,而里面有query这个对象属性,而这个对象里面的参数就是我们需要传的值。同时我们还注意到里面有一个params这个对象,由此我们得到第二种路由传参的方式。
2.通过 $route.params
<div id="app"> <router-link to="/login/12/ls">登录</router-link> <router-link to="/register">注册</router-link> <router-view></router-view> </div> <script> var login = { template: '<h1>登录 --- {{ $route.params.id }} --- {{ $route.params.name }}</h1>', data(){ return { } }, created(){ console.log(this.$route.params.id) } } var register = { template: '<h1>注册</h1>' } var router = new VueRouter({ routes: [ { path: '/login/:id/:name', component: login }, { path: '/register', component: register } ] }) var vm = new Vue({ el: '#app', data: {}, methods: {}, // router: router router }); </script> |
注意,使用这种方式传参是需要在path中绑定参数的。
控制台也是可以拿到值。
1.8.3路由的嵌套
一般实际开发中,往往是有多级菜单的,此时就需要使用children来实现路由嵌套。具体用法如下:
<div id="app"> <router-link to="/account">Account</router-link> <router-view></router-view> </div> <template id="tmpl"> <div> <h1>这是 Account 组件</h1> <router-link to="/account/login">登录</router-link> <router-link to="/account/register">注册</router-link> <router-view></router-view> </div> </template> <script> var account = { template: '#tmpl' } var login = { template: '<h3>登录</h3>' } var register = { template: '<h3>注册</h3>' }
var router = new VueRouter({ routes: [ { path: '/account', component: account, children: [ { path: 'login', component: login }, { path: 'register', component: register } ] } ] }) var vm = new Vue({ el: '#app', data: {}, methods: {}, router }); </script> |
注意:使用 children 属性,实现子路由,同时,子路由的 path 前面,不要带 / ,否则永远以根路径开始请求,这样不方便我们用户去理解URL地址
1.9 axios
实际开发中免不了要和后端用异步进行交互,第一时间你可能会想到jquery的ajax,vue也可以集成jQuery,但是仅仅为了使用ajax就引入jQuery,会增加浏览器的响应速度,兼容性也不好。而vue2.0中有自己的一套方法axios。
推荐一个中文的api网址https://www.cnblogs.com/libin-1/p/6607945.html。
首先要使用这个插件,需要引入这个包。
<script src="https://unpkg.com/axios/dist/axios.min.js"></script> |
1.9.1get请求
执行get请求的语法格式如下:
// 向具有指定ID的用户发出请求 axios.get('/user?ID=12345') .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); });
// 也可以通过 params 对象传递参数 axios.get('/user', { params: { ID: 12345 } }) .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); });
|
Post请求的语法格式如下:
axios.post('/user', { firstName: 'Fred', lastName: 'Flintstone' }) .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); }); |
1.9.3拦截器
为了保证系统的安全性,一般后台都会进行token验证,所以前台发送的请求中需要把这个token带着,因此可以使用拦截器来实现。
//添加请求拦截器 axios.interceptors.request.use(function(config){ //在发送请求之前做某事 return config; },function(error){ //请求错误时做些事 return Promise.reject(error); });
//添加响应拦截器 axios.interceptors.response.use(function(response){ //对响应数据做些事 return response; },function(error){ //请求错误时做些事 return Promise.reject(error); });
|
第二章vue模块化开发项目
为了更好的用模块化的思想去开发项目,vue官方推荐用脚手架去进行开发。
2.1vue的脚手架搭建
Vue官方提供一个搭建脚手架的工具CLI。我们通过npm去安装vue,npm能和webpack等模块打包器配合使用。首先确保你安装了node.js。接下来开始搭建vue工程。
- (windows+R)npm install --global vue-cli 这里推荐用cnpm去安装,国内的淘宝镜像,下载包速度更快。
安装cnpm。(npm install -g cnpm --registry=https://registry.npm.taobao.org)
- vue init webpack my-project
它生成的目录结构是这样的。
build:存放webpack相关配置和脚本。
config:存放配置文件,用于区分开发环境、测试环境、线上环境。
src:项目源码及需要引用的资源文件。
static:不需要webpack处理的静态资源。
test:用于存放测试文件。
package.json:需要下载的依赖包。
- cd 这个文件夹,执行cnpm install;
- cnpm run dev。
一个简单的vue工程就搭建好了
2.2基于element-ui开发
为了更好更快的开发项目,有很多完美集成vue的前端ui库,这里推荐使用饿了么团队开发的适用于pc端的element-ui。
官网:http://element-cn.eleme.io/#/zh-CN
2.2.1安装element-ui
1.cnpm i element-ui –S
2.全局引入element-ui
在main.js中加入:
import ElementUI from 'element-ui'; import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI); |
或者我们也可以按需引入
import { Button } from 'element-ui'; Vue.component(Button.name, Button); |
2.2.2安装axios
1.cnpm install axios –S
2.在main.js中
import axios from 'axios'; import qs from 'qs';//这是将字符串转成json字符串 |
2.2.3vuex的使用
在项目中我们有时候会遇到两个组件不是子父组件的关系,这个时候我们传值就比较繁琐。
1. 运行 cnpm i vuex –S
2.可以在src下建一个store文件夹,在该文件夹下新建一个index.js
import Vue from 'vue' import vuex from 'vuex' Vue.use(vuex); export default new vuex.Store({ state:{ // 大家可以把 state 想象成 组件中的 data ,专门用来存储数据的 // 如果在 组件中,想要访问,store 中的数据,只能通过 this.$store.state.*** 来访问 }, mutations:{ //如果要操作 store 中的 state 值,只能通过 调用 mutations 提供的方法,才能操作对应的数据,不推荐直接操作 state 中的数据,因为 万一导致了数据的紊乱,不能快速定位到错误的原因,因为,每个组件都可能有操作数据的方法; } getters:{ //向外提供state里的数据 } }) |
a. state中的数据,不能直接修改,如果想要修改,必须通过 mutations
b. 如果组件想要直接 从 state 上获取数据: 需要 this.$store.state.***
c. 如果 组件,想要修改数据,必须使用 mutations 提供的方法,需要通过 this.$store.commit('方法的名称', 唯一的一个参数)
d. 如果 store 中 state 上的数据, 在对外提供的时候,需要做一层包装,那么 ,推荐使用 getters, 如果需要使用 getters ,则用 this.$store.getters.***
3.在main.js中
import store from './store'//使用vuex new Vue({ el: '#app', router, store, components: { App }, template: '<App/>' }) |
2.2.4登录权限
做后台项目,权限验证也是很重要的一个环节。我们需要根据不同的权限去动态生成路由。比如我们项目中有三个角色:员工、经理、管理员。
- 在route.js中,我们把不同权限的路由分别区分出来。核心代码如下:
//所有权限通用路由表 //如首页和登录页和一些不用权限的公用页面 export const constantRouterMap = [ //登录 {path: '/',component: Login}, {path:'/register',component:register}, {path: '/main',component: Main,name:'main', children:[//子路由 /*{path:'/home',component:Home}, {path:'/',component:Home},*/ {path:'/changePassword',component:ChangePassword},//修改密码 ] },
]
//异步挂载的路由 //动态需要根据权限加载的路由表 //manager:开发经理及以上 work员工 admin 管理员 export const asyncMagRouterMap = [ {path: '/main',component: Main,name:'main', children:[//子路由 {path:'/home',component:Home}, {path:'*',component:Home}, {path:'/logReport',component:LogReport,name:'LogReport'},// 这里设置,当前路由需要校验 //{path:'/logReport/:dateTime',component:LogReport,name:'LogReport'},// 这里设置,当前路由需要校验 {path: '/LaunchConference',component: LaunchConference}, {path: '/ConferencePreparation',component: ConferencePreparation}, {path: '/myMeetingReport',component: myMeetingReport}, {path: '/queryMeeting',component: QueryMeeting}, {path:'/reviewmeeting',component:reviewmeeting}, {path: '/StaffMeetingQuery',component: StaffMeetingQuery},//员工会议查询 {path:'/postManagement',component:postManagement},//会后管理 ] }, { path: '/404', component:ErrorPage}, { path: '*', redirect: '/404', hidden: true } ]; //员工 export const asyncWorkRouterMap = [ {path: '/main',component: Main,name:'main', children:[//子路由 {path:'/home',component:Home}, {path:'*',component:Home}, {path:'/logReport',component:LogReport,name:'LogReport'},// 这里设置,当前路由需要校验 {path: '/LaunchConference',component: LaunchConference}, {path: '/ConferencePreparation',component: ConferencePreparation}, {path: '/myMeetingReport',component: myMeetingReport}, {path: '/queryMeeting',component: QueryMeeting}, {path:'/postManagement',component:postManagement},//会后管理 ] }, { path: '/404', component:ErrorPage}, { path: '*', redirect: '/404', hidden: true } ]; //管理员 export const asyncAdminRouterMap = [ {path: '/main',component: Main,name:'main', children:[//子路由 {path:'*',component:CalendarManager}, {path:'/calendarManager', component: CalendarManager},//管理日历 {path:'/configWorkItem',component:workItemManager}, {path:'/configSysProject',component:sysProjectManager}, {path:'/configMapping',component:workItemMappingSysProjectManager} ] }, { path: '/404', component:ErrorPage}, { path: '*', redirect: '/404', hidden: true } ]; export default new Router({ routes: constantRouterMap }) |
注意事项:这里有一个需要非常注意的地方就是 404 页面一定要最后加载,如果放在constantRouterMap一同声明了404,后面的所以页面都会被拦截到404
- mian.js中,首先我们需要用到route的钩子函数(生命周期函数)router.beforeEach(to,from,next)
- to:router即将进入的路由对象
- from:当前导航即将离开的路由
- next:Function,进行管道中的一个钩子,如果执行完了,则导航的状态就是 confirmed (确认的);否则为false,终止导航。
router.beforeEach((to,from,next)=>{ console.log(to,from,next) var userInfo = JSON.parse(window.sessionStorage.getItem('session')) ;//获取浏览器缓存的用户信息 //console.log(userInfo.roleName) //var userInfo = store.stste.token if(userInfo){ //如果有就直接到首页咯 //if(userInfo.roleName) var roleName = userInfo.roleName switch (roleName){ case '管理员': store.dispatch('GenerateRoutes','admin').then(() => { router.addRoutes(store.state.addRouters) // 动态添加可访问路由表 }) /*store.dispatch('AdminRoutes').then(() => { router.addRoutes(store.state.addRouters) // 动态添加可访问路由表 })*/ store.commit("setIsMag",false) store.commit("setIsShow",false) store.commit("setIsAdmin",true) break; case '工程师': store.dispatch('GenerateRoutes','work').then(() => { router.addRoutes(store.state.addRouters) // 动态添加可访问路由表 }) /*store.dispatch('WorkRoutes').then(() => { router.addRoutes(store.state.addRouters) // 动态添加可访问路由表 })*/ store.commit("setIsAdmin",false) store.commit("setIsShow",false) store.commit("setIsMag",true) break; default: store.dispatch('GenerateRoutes','manager').then(() => { router.addRoutes(store.state.addRouters) // 动态添加可访问路由表 }) /*store.dispatch('MagRoutes').then(() => { router.addRoutes(store.state.addRouters) // 动态添加可访问路由表 })*/ store.commit("setIsAdmin",false) store.commit("setIsMag",true) store.commit("setIsShow",true) break; } next(); //next(); } else { if(to.path=='/' || to.path=='/register'){ //如果是登录页面路径,就直接next() next(); } else { //不然就跳转到登录; next('/'); } } }), |
- store.js中
import Vue from 'vue' import vuex from 'vuex' import {constantRouterMap,asyncMagRouterMap,asyncWorkRouterMap,asyncAdminRouterMap } from '../router'; Vue.use(vuex); export default new vuex.Store({ state:{ routers: constantRouterMap, addRouters: [] }, mutations:{ SET_ROUTERS(state, routers){//设置动态 静态路由转换的 state.addRouters = routers; state.routers = constantRouterMap.concat(routers); } }, actions:{ GenerateRoutes({ commit },data) { switch (data){ case "admin": commit('SET_ROUTERS', asyncAdminRouterMap); break; case "work": commit('SET_ROUTERS', asyncWorkRouterMap); break; default: commit('SET_ROUTERS', asyncMagRouterMap); break; } } } }) |
2.2.5封装子组件
子组件中一般不能有异步请求,子组件的数据都是通过父组件传来的。
下面通过在countUp.js封装一个计时器组件。
- 安装countUp.js
cnpm install countup.js |
- 新建一个VueCountUp.vue文件
|
- 在App.vue中使用该组件
|
2.3项目的打包
当vue项目完成后我们需要将它打包出来放到服务器下即可运行。
执行cnpm run build 命令,可以看到打包后生成的文件夹。
2.3.1静态资源路径不对
1在打包的时候可能会出现的问题。
控制台如下:
解决方法:找到config目录下的index.js,在如下图所示的地方加上一个点即可。
2.3.2图片加载不进来
这是因为在模块加载器的url加载器limt限制大小的关系。将build文件夹下更改一下限制。
更多推荐
所有评论(0)