Vue前端路由
路由
本质就是对应关系
路由分为:
- 前端路由:根据不同的用户事件,显示不同的网页内容
用户事件<=>事件处理函数
- 后端路由:根据不同的用户URL请求,返回不同的内容
URL请求地址<=>服务器资源
简易前端路由
<div id="app">
<a href="#/zhuye">主页</a>
<a href="#/keji">科技</a>
<a href="#/caijing">财经</a>
<a href="#/yule">娱乐</a>
<component :is="componentName"></component>
</div>
<script type="text/javascript">
const zhuye = {
template: `<h1>主页信息</h1>`
}
const keji = {
template: `<h1>科技信息</h1>`
}
const caijing = {
template: `<h1>财经信息</h1>`
}
const yule = {
template: `<h1>娱乐信息</h1>`
}
const vm = new Vue({
el: "#app",
data: {
componentName: 'zhuye'
},
components: {
"zhuye": zhuye,
"keji": keji,
"caijing": caijing,
"yule": yule
}
})
window.onhashchange = function () {
console.log(location.hash);
switch (location.hash.slice(1)) {
case '/zhuye':
vm.componentName = 'zhuye'
break
case '/keji':
vm.componentName = 'keji'
break
case '/caijing':
vm.componentName = 'caijing'
break
case '/yule':
vm.componentName = 'yule'
break
}
}
</script>
vue-router的基本使用
- 引入相关的库文件
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
- 添加路由链接
<router-link to="/user">User</router-link>
<router-link to="/register">Register</router-link>
- 添加路由填充位
<router-view></router-view>
- 定义路由组件
var User = {
template: `<div>User</div>`
}
var Register = {
template: `<div>Register</div>`
}
- 配置路由规则并创建路由实例
var router = new VueRouter({
routes: [
{
path: '/user', component: User
},
{
path: '/register', component: Register
}
]
})
- 把路由挂载带Vue根实例中
router: router
路由重定向
改变了url地址
{
path: '/', redirect: '/user'
}
嵌套路由
<div id="app">
<router-link to="/user">User</router-link>
<router-link to="/register">Register</router-link>
<router-view></router-view>
</div>
<script type="text/javascript">
var User = {
template: `<div>User</div>`
}
var tab1 = {
template: `<div>tab1</div>`
}
var tab2 = {
template: `<div>tab2</div>`
}
var Register = {
template: `<div>
<h1>Register 组件</h1>
<hr/>
<router-link to="/register/tab1">tab1</router-link>
<router-link to="/register/tab2">tab2</router-link>
<router-view></router-view>
</div>`
}
var router = new VueRouter({
routes: [
{
path: '/', redirect: '/user'
},
{
path: '/user', component: User
},
{
path: '/register', component: Register,children:[
{path: '/register/tab1', component: tab1},
{path: '/register/tab2', component: tab2}
]
}
]
})
const vm = new Vue({
el: "#app",
data: {},
router: router
})
</script>
动态路由匹配
{path: '/:tab', component: tab},
var tab = {
template: `<div>{{$route.params.tab}}</div>`
}
路由组件传递参数
如果使用$router.params.xx的话耦合度太高,必须解耦
- props的值为布尔类型
{path: '/register/:tab', component: tab, props: true}
var tab = {
props: ['tab'],
template: `
<div>{{ tab }}</div>`
}
- props的值为对象类型
{path: '/register/:tab', component: tab, props: {username: 'lisi', age: 12}}
var tab = {
props: ['username', 'age'],
template: `
<div>{{ username + age }}</div>`
}
命名路由
为了更方便的表示路由的路径,可以给路由规则起一个别名,即为“命名路由”
<router-link :to="{name:'user',params:{id:123}}">User</router-link>
{
// 命名路由
name:'user',
path: '/user', component: User
}
编程式导航
- 跳转
var User = {
template: `
<div>
<button @click="goRegister">跳转到注册页面</button>
</div>`,
methods: {
goRegister() {
this.$router.push('/register');
}
}
}
- 回退
var Register = {
template: `
<div>
<h1>Register 组件</h1>
<hr/>
<router-link to="/register/tab1">tab1</router-link>
<router-link to="/register/tab2">tab2</router-link>
<router-view></router-view>
<button @click="goBack">回退</button>
</div>`, methods: {
goBack: function () {
this.$router.go(-1)
}
}
}
vue-router案例
<style type="text/css">
html,
body,
#app {
margin: 0;
padding: 0px;
height: 100%;
}
.header {
height: 50px;
background-color: #545c64;
line-height: 50px;
text-align: center;
font-size: 24px;
color: #fff;
}
.footer {
height: 40px;
line-height: 40px;
background-color: #888;
position: absolute;
bottom: 0;
width: 100%;
text-align: center;
color: #fff;
}
.main {
display: flex;
position: absolute;
top: 50px;
bottom: 40px;
width: 100%;
}
.content {
flex: 1;
text-align: center;
height: 100%;
}
.left {
flex: 0 0 20%;
background-color: #545c64;
}
.left a {
color: white;
text-decoration: none;
}
.right {
margin: 5px;
}
.btns {
width: 100%;
height: 35px;
line-height: 35px;
background-color: #f5f5f5;
text-align: left;
padding-left: 10px;
box-sizing: border-box;
}
button {
height: 30px;
background-color: #ecf5ff;
border: 1px solid lightskyblue;
font-size: 12px;
padding: 0 20px;
}
.main-content {
margin-top: 10px;
}
ul {
margin: 0;
padding: 0;
list-style: none;
}
ul li {
height: 45px;
line-height: 45px;
background-color: #a0a0a0;
color: #fff;
cursor: pointer;
border-bottom: 1px solid #fff;
}
table {
width: 100%;
border-collapse: collapse;
}
td,
th {
border: 1px solid #eee;
line-height: 35px;
font-size: 12px;
}
th {
background-color: #ddd;
}
</style>
</head>
<body>
<div id="app">
<router-view></router-view>
</div>
<script type="text/javascript">
const App = {
template: `<div>
<header class="header">传智后台管理系统</header>
<div class="main">
<div class="content left">
<ul>
<li><router-link to="/users">用户管理</router-link></li>
<li><router-link to="/rights">权限管理 </router-link></li>
<li><router-link to="/goods">商品管理</router-link></li>
<li><router-link to="/orders">订单管理</router-link></li>
<li><router-link to="/settings">系统设置</router-link></li>
</ul>
</div>
<div class="content right"><div class="main-content"><router-view></router-view></div></div>
</div>
<footer class="footer">版权信息</footer>
</div>`
}
const Users = {
data() {
return {
userList: [
{id: 1, name: '张三', age: 17},
{id: 2, name: '李四', age: 15},
{id: 3, name: '王五', age: 13},
{id: 4, name: '赵六', age: 12}
]
}
},
template: `
<div>
<h3>用户管理区域</h3>
<table>
<thead>
<tr>
<th>编号</th>
<th>姓名</th>
<th>年龄</th>
<th>详情</th>
</tr>
</thead>
<tbody>
<tr :key="index" v-for="(item,index) in userList">
<td>{{ item.id }}</td>
<td>{{ item.name }}</td>
<td>{{ item.age }}</td>
<td><a href="javascript:;" @click="goUser(item.id)">详情</a></td>
</tr>
</tbody>
</table>
</div>`, methods: {
goUser(id) {
this.$router.push('/userInfo/' + id);
}
}
}
const userInfo = {
props: ["id"],
template: `
<div>
<h2>用户详情页</h2>
<div>用户id为:{{ id }}</div>
<button @click="goBack">back</button>
</div>`, methods: {
goBack: function () {
this.$router.go(-1)
}
}
}
const Rights = {
template: `<div>
<h3>权限管理区域</h3>
</div>`
}
const Goods = {
template: `<div>
<h3>商品管理区域</h3>
</div>`
}
const Orders = {
template: `<div>
<h3>订单管理区域</h3>
</div>`
}
const Settings = {
template: `<div>
<h3>系统设置区域</h3>
</div>`
}
const router = new VueRouter({
routes: [
{
path: '/', redirect: '/users', component: App, children: [
{
path: '/users', component: Users
},
{
path: '/userInfo/:id', component: userInfo, props: true
},
{
path: '/rights', component: Rights
},
{
path: '/goods', component: Goods
},
{
path: '/orders', component: Orders
}, {
path: '/settings', component: Settings
}
]
}
]
})
const vm = new Vue({
el: "#app",
router: router
})
</script>
前端工程化
模块化概述
传统开发模式的主要问题
①命名冲突
②文件依赖
模块化就是把单独的一个功能封装到一个模块中,模块之间相互隔离,但是可以通过特定的接口公开内部成员,也可以依赖别的模块
模块化的好处:方便代码的重用,从而提升开发效率,并且方便后期的维护
- 浏览器端模块化规范
1、AMD,例:Require.js
2、CMD,例:Sea.js
- 服务器端模块化规范
CommonJS
- 大一统的模块化规范-ES6规范化(统一了浏览器端和服务器端的模块化开发规范)
①每个js文件都是一个独立的模块
②导入模块成员使用import关键字
③暴露模块成员使用export关键字
当前Web开发面临的困境
- 文件依赖关系错综复杂
- 静态资源请求效率低
- 模块化支持不友好
- …
webpack是一个流行的前端项目构建工具,提供友好的模块化支持
webpack的基本使用
流程
- 创建项目空白目录,并运行npm init -y命令,初始化包管理配置文件package.json
- 新建src源代码目录
- 新建src->index.html首页
- 初始化首页基本的结构
<ul>
<li>这是第1个li</li>
<li>这是第2个li</li>
<li>这是第3个li</li>
<li>这是第4个li</li>
<li>这是第5个li</li>
<li>这是第6个li</li>
<li>这是第7个li</li>
<li>这是第8个li</li>
<li>这是第9个li</li>
</ul>
-
运行npm install jquery -s命令,安装jQuery
-
通过模块化的形式,实现列表隔行变色效果(存在JavaScript的兼容性问题,必须使用webpack来打包项目)
-
运行 npm install webpack webpack-cli -D命令,安装webpack相关的包
-
在项目根目录下,创建名为webpack.config.js的webpack配置文件
-
在webpack的配置文件中,初始化基本配置
const path = require('path')
module.exports = {
// 编译模式
mode: 'development', // development production
entry: path.join(__dirname, './src/index.js'),
output: {
path: path.join(__dirname, './dist'), // 输出文件的存放路径
filename: 'bundle.js' // 输出文件的名称
}
}
import $ from 'jquery'
$(function() {
$('li:odd').css('backgroundColor', 'blue')
$('li:even').css('backgroundColor', 'lightblue')
})
- 在package.json配置文件中的scripts节点下,新增dev脚本
"dependencies": {
"jquery": "^3.5.1"
},
"devDependencies": {
"webpack": "^5.1.3",
"webpack-cli": "^4.1.0"
}
配置打包的入口和出口
- 打包的入口文件为src->index.js
- 打包的输出文件为dist->main.js
指定入口出口
const path = require('path')
module.exports = {
mode: 'development',
//入口
entry: path.join(__dirname, './src/index.js'),
output: {
//出口
path: path.join(__dirname, './dist'),
filename: 'bundle.js'
}
}
配置webpack的自动打包功能
- npm install webpack-dev-server -D,安装打包工具
- 修改package.json
"dev": "webpack-dev-server"
访问http://localhost:8080/bundle.js就可以看到bundle.js文件,注意:bundle.js存放在内存中,而不是硬盘上,所以项目里看不到
现在修改index.js,页面会相应变化
配置html-webpack-plugin生成预览页面
- 运行npm install html-webpack-plugin -D
- 修改webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin')
const htmlPlugin = new HtmlWebpackPlugin({
template: './src/index.html',
filename: 'index.html'
})
plugins: [htmlPlugin]
Vue单文件组件
- template
- script
- style
<template>
<div><h1>这是App根组件</h1></div>
</template>
<script>
export default {
data() {
return {};
}
}
</script>
<style scoped>
h1 {
color: red;
}
</style>
webpack中配置vue组件的加载器
- 运行 npm i vue-loader vue-template-compiler -D
- 配置webpack.config.js
const VueLoaderPlugin = require('vue-loader/lib/plugin')
module.exports = {
plugins: [htmlPlugin, new VueLoaderPlugin()],
module: {
rules:
[
{test: /\.vue$/, use: 'vue-loader'}
]
}
}
在webpack项目中使用vue
-
使用命令npm i vue -s
-
编写index.js
import Vue from 'vue'
import App from './components/App.vue'
const vm = new Vue({
el: '#app',
render: h => h(App)
})
- 编写index.html
<div id="app"></div>
webpack打包发布
"build": "webpack -p"
Vue脚手架的基本用法
安装包
- npm install -g @vue/cli
创建vue项目
- vue create xxx
Vue脚手架项目结构分析
- node_modules=》依赖包目录
- public=>静态资源目录
- src=>组件源码目录
- babel.config.js=》babel配置文件
Vue脚手架的自定义配置
通过package.json配置项目
"vue": {
"devServer": {
"port": 8888,
"open": true
}
通过vue.config.js配置项目
module.exports = {
devServer: {
port: 8888
}
}
Element-UI的基本使用
- 安装
npm i element-ui -S
- main.js导入
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
- App.Vue编写
<el-row>
<el-button>默认按钮</el-button>
<el-button type="primary">主要按钮</el-button>
<el-button type="success">成功按钮</el-button>
<el-button type="info">信息按钮</el-button>
<el-button type="warning">警告按钮</el-button>
<el-button type="danger">危险按钮</el-button>
</el-row>