Vue组件框架(ElementUI+Axios+Vuex)
比如导航栏,可以把他封装起来,再其他位置进行使用新建组件标签查看样式组件化开发扩展因为ElementUI比较成熟的是基于Vue2.x的版本,所以我们这里创建一个Vue2的项目来演示ElementUI切换到工程文件目录下,命令新建文件,选择2.0版本进行创建vue create 项目名创建完毕后加入工程创建一个组件基础内容,可以直接嵌入使用不过这样有个缺点,就是内容只能在卡片内部进行使用,无法被调用
Vue基础语法回顾
历史什么的就不多说了,直接看MVVM
MVVM作为一种思想
如何使用?
快速开始Vue
在页面中导入Vue的依赖
你可以在浏览器新标签页中打开它,跟着例子学习一些基础用法。或者你也可以创建一个 .html 文件,然后通过如下方式引入 Vue:
这个类似JDK
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
或者是
这个类似JRE
<!-- 生产环境版本,优化了尺寸和速度 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
导入方式不光这几种,还有npm安装的方式,前期先用这种方式学习
DIV标签绑定数据
<div id="app">
{{ message }}
</div>
JS代码对数据进行双向绑定
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
})
此时页面是可以成功显示Hello Vue!的,但是这不是特别重要,毕竟可以CV
Vscode中快速开始
把目录文件夹直接拖进Vscode,就可以很方便的生成工程
新建文件
先装一个神奇小插件 open in browser ,安装之后可以在浏览器把你的静态网页打开
把前面的div代码导入,alt+b就可以把网页一键打开
这里只做演示,详细的可以看下面的连接,具体的语法以及案例可以看这一篇
Vue基础语法
组件化开发
组件化开发前言
比如导航栏,可以把他封装起来,再其他位置进行使用
NPM的使用
实际上就是前端版Maven
Vue Cli的使用
不需要从0去写项目,这样更快
安装命令
npm install -g @vue/cli
-g代表全局安装
打开代码所在的目录,运行一下命令
创建vue项目,命令回车
vue create 项目名
这里有几个选项
选择最后一个,手动选择特性,回车
选择语言版本
选择功能特性,空格选中和取消,一个bable就行
选择特性 3.0版本即可
选择依赖位置记录方式,一般是json
是否需要快照,给个N就行
目录生成,并且可以找到文件夹
把文件夹拖入Vscode,就可以进行编辑了
也可以通过npm run dev运行起来
测试运行以及一些坑
这里注意,npm run dev是vue 2.0 版本的启动命令,如果是3.0版本的,是要用别的命令:npm run serve
如图,npm run dev是启动不了的
运行npm run serve
我遇到的启动问题:
组件示例
前面提到了,组件就是对之前内容进行了封装
可以进行引入,把相应的自定义标签引入到目标位置上
这里组件的注册是局部注册,而我们后期引入的El标签是全局注册的
自定义一个标签
新建组件标签
查看样式
组件化开发扩展
ElementUI
v-for中的key
这个后面会用到
组件化开发过程中,如果不加这个唯一的key,是会报错的
例如
自定义单一组件传值(重要)
因为ElementUI比较成熟的是基于Vue2.x的版本,所以我们这里创建一个Vue2的项目来演示ElementUI
切换到工程文件目录下,命令新建文件,选择2.0版本进行创建
vue create 项目名
创建完毕后加入工程
创建一个组件
基础内容,可以直接嵌入使用
不过这样有个缺点,就是内容只能在卡片内部进行使用,无法被调用卡片的页面进行获取
这里Vue提供了一个属性,供外界调用者对数据进行处理
props:[属性1:value1,属性2:value2,......]
就像这样,现在title的值由外界调用他的页面来决定内容
来到调用他的页面,对内容进行赋值
刷新,就可以看到外界调用者对其进行了赋值,属性可以直接渲染上去
可以多个属性…
数据就都上来了
自定义组件批量赋值(重要)
比如说我有许多行数据,要用v-for指令循环出来内容
那还是以刚刚的那个自定义标签为例
在调用页面,提前准备好数据列表
修改自定义标签的调用
测试一下
根据不同的数据进行处理
回到卡片内部本身
可以根据外部的值,就做出不同的响应
每次弹窗的内容都不一样
极端情况
回到调用页面来看,我们引入多个卡片的自定义标签
兄弟卡片之间无法传值,至少目前是无法做到的
后面有VueX可以一定程度上解决问题
ElementUI起步
因为这个也是基于Vue的,所以版本也是要适配
由于我是用Vue2的项目,所以El也要用2.0的版本
安装El的依赖
npm i element-ui -S
可以看到,依赖已经进来了
全局注册
因为EL的组件在整个工程中都要进行引入,所以我们要在js内部把组件进行全局注册,同时引入EL的css样式
回到main.js中
引入如下内容
在 main.js 中写入以下内容:
import Vue from 'vue';
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import App from './App.vue';
Vue.use(ElementUI);
new Vue({
el: '#app',
render: h => h(App)
});
改好之后的样子
现在就可以引入了,回到el官网,找一个标签,以列表为例
里面自带数据,可以渲染上去
自定义好一个标签,把代码块复制进去,当然,直接引入也行,但是那样就会比较臃肿
数据渲染
看不懂数据属性没关系,官网的最下面已经解释清楚了,拖到最下面就可以看到属性的解释
注意项
注意,如果是Vue2的版本的话,那么每个<template> </template>
标签内部只能有一个根标签,多个标签会冲突
这个也好解决,就是套个div就行
<template>
<div>
el或者其他标签
</div>
</template>
第三方图标
Awesome图标库官网
先安装 npm install font-awesome
再到main.js中引入样式就可以使用了
import 'font-awesome/css/font-awesome.min.css'
Axios
就是ajax嘛,Axios就是基于ajax的网络请求框架
Axios起步
Axios官网
安装指令
npm install axios
在命令行里面进行输入,就可以看到package.json中就已经有axios的依赖上来了
有了依赖之后就要进行导入操作,来到main.js中进行全局导入。
一个一个页面进行导入当然也是可以,但是太麻烦
局部导入
全局导入
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import axios from 'axios'
Vue.config.productionTip = false
Vue.prototype.$axios = axios // 将请求模块挂载到实例模型上
new Vue({
router,
render: h => h(App)
}).$mount('#app')
在页面中或者组件使用
this.$axios.get(url)
.then((data) => {
console.log(data)
})
发送网络请求
Get请求语法
axios.get(url?key=value&key2=value2).then(
function(response){
响应成功时运行的函数,response对象为结果对象
},
function(err){
响应失败时运行的函数,err对象为报错对象
}
)
Post请求语法
注意,这里对象的装载方法是{属性:值}
axios.post(url,{key:value&key2:value2}).then(
function(response){
响应成功时运行的函数,response对象为结果对象
},
function(err){
响应失败时运行的函数,err对象为报错对象
}
)
总结:
Axios在发送请求的时候,会自动把请求内容转换为Json
Axios实战应用
生命周期函数(钩子函数)
Vue的生命周期包括了开始创建、初始化数据、编译模版、挂载Dom -> 渲染、更新 -> 渲染、卸载 等⼀系列过程,称这是Vue的⽣命周期,而这每个周期都会对应有一个函数,当到达这些周期时,就会运行相应函数体中的内容。具体可以看这个文章,Vue生命周期
created函数
以创建时的created函数为例。它在页面组件被创建的时候,就会自动执行created函数内的内容。
注意,生命周期函数不应该放入methods中,应与data保持平级关系。
测试一下,刷新页面可以看到控制台输出,也就是这个组件一被创建的时候就会发起请求
mounted函数
依旧是与data、created函数平级,并且是在被挂载(渲染)时才会触发
看一下控制台,非常滴好用
还有一些其他的生命周期函数,就不多赘述了
自定义函数
在自定义方法体内去定义一些请求等等,规定按钮触发等等。
跨域问题
简单请求
解决方案,在请求头内部加入允许访问的字段
除了简单请求以外的就是非简单请求
非简单请求
跨域后端解决方案
或者在Controller类上方加@CrossOrigin也完全可以
到这,跨域就算弄完了
数据绑定(重要)
Vue整合Axios
在此之前,我们学习一下Vue整合,把公共路径抽取出来,统一的请求的公共路径
在main.js中,全局导入Axios之后,加入公共前缀
axios.defaults.baseURL="http://localhost:8889"//确定公共请求前缀
更正一下,图上URL写错了,应该是这样注意
具体内容绑定
我们前面拿到了数据,现在就需要把数据放在data里面,把数据放进表格中
表格如何绑定返回的数据呢?
修改prop属性
请求写法
老款写法
这里涉及到一个js数据作用域的问题,会导致this.data访问不到,定性为undefined,因为作用域不在一起,那这个时候更改request对象的写法为箭头函数:
这里会自动拼接,然后赋值就可以了
注意:如果拿不到数据就用response.data.data来拿数据,这种拿取方式是因为没封装
this.$axios.get('/common/getIpList').then((response)=>{
this.tableData=response.data.data;
})
图上的response.data是错的,实际上response.data来拿数据是报错,我懒得改了,大家当this.tableData=response.data.data
来看就行
完整内容
再进行测试,数据就都上来了
VueRouter
VueRouter安装
VueRouter是干什么的?
vue-router 就是路由,地址栏输什么,到什么页面,而且vue-router可以通过html5的history实现单页面应用,不刷新跳转,你切地址,只是页面上的组件的切换,不必再整个页面进行刷新,所有的页面都在一个html上,只有组件在不断变化,达到页面切换的效果。另外vue-router还可以实现页面间传参等其他功能。
这里选择的是Vue2.x,所以选用的VueRouter也选择对应的3.x版本
官网:https://router.vuejs.org/zh/
因为我们安装的时候如果用 npm install vue-router 的话就会默认安装最新版本,所以我们要自己指定安装版本
npm install vue-router@3
安装完成
在main.js中注册VueRouter
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
创建路由组件并实现跳转
在项目中components下定义 Discover.vue、Friends.vue、My.vue 三个组件,将来要使用 vue-router 来控制它们的展示与切换
可以使用 <router-link>
标签来声明路由链接,并使用 <router-view>
标签来声明路由占位符。示例
代码如下:
但是光有这些还不够,还无法完成跳转,比如<router-link to="/discover">
的/discover,路径还没有进行指定,所以,要统一在一个文件中对路径进行指定
<router-link>
负责跳转
<router-view>
负责占位,点击之后的内容在这个占位标签内进行显示
<div id="app">
<!-- 声明路由链接 -->
<router-link to="/discover">发现音乐</router-link>
<router-link to="/friends">我的音乐</router-link>
<router-link to="/product">关注</router-link>
<!-- 声明路由占位标签 -->
<router-view></router-view>
</div>
路由配置(重要)
一般来说,项目中会创建一个路由文件,把组件的跳转路径指定起来
这样引入+指定跳转路径,就可以完成路由的设置
import VueRouter from 'vue-router'
import Vue from 'vue'
import Discover from '@/components/Discover.vue'
import Friends from '@/components/Friends.vue'
import My from '@/components/My.vue' //将VueRouter设置为Vue的插件
Vue.use(VueRouter)
const router = new VueRouter({ // 指定hash属性与组件的对应关系
routes: [
{ path: '/discover', component: Discover },
{ path: '/friends', component: Friends },
{ path: '/my', component: My },
]
})
//导出 router文件,为了后续挂载使用
export default router
挂载路由模块
在main.js中导入并挂载router(挂载的刚刚的export default router)
import Vue from 'vue'
import App from './App.vue'
import VueRouter from 'vue-router'
import router from './router'
Vue.use(VueRouter)
Vue.config.productionTip = false
new Vue({
render: h => h(App),
router:router
}).$mount('#app')
被框选的是新加入的内容
到上面就算配置完毕了,就可以开始使用了
测试
回到主页面,点击就可以发现,不需要刷新页面就可以完成页面跳转了
点击就可以完成页面内容的切换
URL也会动态的根据标签内容进行切换
同时,在切换下一个组件的过程中,上一个组件就会随之销毁
路由重定向
路由重定向指的是:用户在访问地址 A 的时候,强制用户跳转到地址 C ,从而展示特定的组件页面。
通过路由规则的 redirect 属性,指定一个新的路由地址,可以很方便地设置路由的重定向:
比如我们默认开启的界面,希望有一个默认的页面做显示
在index.js中加入配置
const router = new VueRouter({ // 指定hash属性与组件的对应关系
routes: [
// 当用户访问 / 时,跳转到 /discover
{ path: '/', redirect: '/discover'},
{ path: '/discover', component: Discover },
{ path: '/friends', component: Friends },
{ path: '/my', component: My },
{ path: '/product', component: Product },
]
})
嵌套路由(子路由)
既然可以在页面中使用 <router-link>
标签进行组件开启,那么我就可以,在被打开的组件页面中再打开一个页面。
在 Discover.vue 组件中,声明 toplist和 playlist的子路由链接以及子路由占位符。示例代码如下:
<template>
<div>
<h1>发现音乐</h1>
<!-- 子路由链接 -->
<router-link to="/discover/toplist">推荐</router-link>
<router-link to="/discover/playlist">歌单</router-link>
<hr>
<!-- 占位不能少 -->
<router-view></router-view>
</div>
</template>
在 src/router/index.js 路由模块中,导入需要的组件, 并使用 children 属性声明子路由规则:
const router = new VueRouter({ // 指定hash属性与组件的对应关系
routes: [
// 当用户访问 / 时,跳转到 /discover
{ path: '/', redirect: '/discover'},
{ // 传统组件配置
path: '/discover',
component: Discover,
// 通过children属性,嵌套声明子路由
children: [
{path:"toplist",component:TopList},
{path:"playlist",component:PlayList},
]
},
{ path: '/friends', component: Friends },
{ path: '/my', component: My },
{ path: '/product', component: Product },
]
})
不难发现,这种子组件写法和全路径写是等价的
也就是
{ // 传统组件配置
path: '/discover',
component: Discover,
// 通过children属性,嵌套声明子路由
children: [
{path:"toplist",component:TopList},
{path:"playlist",component:PlayList},
]
},
等价于
{ path: '/discover/toplist', component: TopList },
动态路由
思考:有如下 3 个路由链接:
<router-link to="/product/1">商品1</router-link>
<router-link to="/product/2">商品2</router-link>
<router-link to="/product/3">商品3</router-link>
三个产品链接,三个页面,复用性太差,不可能为每个商品都写一个页面
这时就有了动态路由的概念
动态路由指的是:把 Hash 地址中可变的部分定义为参数项,从而提高路由规则的复用性。在 vue-router 中使用英文的冒号(:)来定义路由的参数项。示例代码如下:
这样改完,之前的
<router-link to="/product/1">商品1</router-link>
<router-link to="/product/2">商品2</router-link>
<router-link to="/product/3">商品3</router-link>
这三种请求都会匹配到Product这个组件下
{ path: '/product/:id',component:Product }
但是我跳转了之后,我需要知道是第几个商品,也就是知道跳转的id
通过动态路由匹配的方式渲染出来的组件中,可以使用 $route.params 对象访问到动态匹配的参数值,
比如在商品详情组件的内部,根据id值,请求不同的商品数据。
路由配置
这样我就可以在页面获取值了
点击页面就会进行跳转,并且带着id
**简便方式:**为了简化路由参数的获取形式,vue-router 允许在路由规则中开启 props 传参。示例代码如下:
在配置里修改,允许带着参数
{ path: '/product/:id',component: Product, props: true }
回到组件页面
就可以完成数据修改
编程式导航
这个一般是整个页面跳转要用,在方法内进行的跳转
this.$router.push('/注册的页面组件')
导航守卫
导航守卫可以控制路由的访问权限。示意图如下:
全局导航守卫会拦截每个路由规则,从而对每个路由进行访问权限的控制。
类似后端的拦截器,如果没登录就想去后台,肯定要拦截
你可以使用 router.beforeEach 注册一个全局前置守卫:
to:去哪里
from:从哪来
next:控制让不让去跳
VueX状态管理
出现背景
核心思想是把数据抽出来到一个单一的地方,大家去那拿数据
也就是帮助组件之间去共享数据
默认下载最新版本
npm install vuex@next
同样的,VueX也是对应不同的Vue版本
VueX3对应Vue2.x版本
VueX4对应Vue3.x版本
下面以VueX3来演示
npm install vuex@3
状态管理
快速开始
新建一个工程Vue2.x对应VueX 3.x
一般VueX相关的内容都会放在store文件夹下
文件内容
回到主配置文件,main.js
页面读取数据
如果我们想修改状态,就要去通过触发mutation中的方法进行修改
直接接触公共值是接触不到的
this.$store.commit("mutation里面的方法名",参数)
读取数据的简化版本
这个写法是针对差值表达式比较友好的版本,但同时也要设置一下
State(状态)
所有的数据都可以定义到状态里面去 把组件需要共享的数据放入state里面
也就是说,不可以直接去更改数据,类似于java的封装,把数据隐藏起来,需要修改的时候,调用方法才能进行修改
MockJS
模拟数据
需要用的时候引入,不需要的时候删掉就可以了
快速开始
npm install mockjs
一般mock文件放在mock文件夹下方
//引入mockjs
import Mock from 'mockjs'
//设置延迟时间
// Mock.setup({
// timeout: 4000
// })
//使用mockjs模拟数据
Mock.mock(RegExp('/product/search.*'), {
"ret":0,
"data":
{ key : value,
"mtime": "@datetime",//随机生成日期时间
"score|1-800": 1,//随机生成1-800的数字
"rank|1-100": 1,//随机生成1-100的数字
"stars|1-5": 1,//随机生成1-5的数字
"nickname": "@cname",//随机生成中文名字
//生成图片
"img":"@image('200x100', '#ffcc33', '#FFF', 'png', 'Fast Mock')"
}
});
怎么去用?
核心方法
更多推荐
所有评论(0)