Vue 进阶
-
动态路由 + 路由传参 + 路由接参
- 案例: 移动端常见的: 分类 -》 列表 -》 详情 -》 购物车
-
引入组件库
-
组件库就是可以快速帮助我们实现样式布局和基本逻辑
-
组件库 vs ui 库
- 组件库指的是有组件构成的类库
- ui 库更多偏向的的是样式: sui
-
类型
说明:Vue 的组件库很多,我这边列举的是比较流行的
-
pc 端 【 后台管理系统 】
-
element-ui 饿了吗前端开发团队完成
-
iview
-
-
移动端
- Mint-ui
-
-
组件库安装
-
安装方式
-
全局引入: 将组件库中所有组件都引入项目,这样会增大项目体积
-
$ yarn add element-ui -D
-
在 main.js 中引入: import ElmentUI from ‘element-ui’
-
在 main.js 中使用 Vue.use 注册插件
- Vue.use( ElementUI )
-
-
-
-
import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import ElementUI from "element-ui";
Vue.use(ElementUI);
Vue.config.productionTip = false;
new Vue({
render: h => h(App),
router //在根实例中注入路由
}).$mount("#app");
-
按需引入: 只将我们需要的组件引入进来
- $ yarn add element-ui
- $ yarn add babel-plugin-component -D 帮助我们做按需引入的第三方模块
main.js
import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import { Button } from "element-ui";
// Vue.use( ElementUI )
Vue.use(Button);
Vue.config.productionTip = false;
new Vue({
render: h => h(App),
router //在根实例中注入路由
}).$mount("#app");
babel.config.js
module.exports = {
presets: ["@vue/app"],
plugins: [
[
"component",
{
libraryName: "element-ui",
styleLibraryName: "theme-chalk"
}
]
]
};
注意: 项目配置文件修改了,我们必须重启项目
测试组件库是否引入成功
多试几个组件库,多用几个
猫眼电影—案例演示
-
Vue 项目配置反向代理,实现跨域
-
Vue cli3 webpack配置放在node_modules 中,也就是说我们不能直接更改,Vue提供了一个叫做vue.config.js的文件,没来作为webpack的覆盖配置文件,也可以说是vue项目的配置文件
-
vue.config.js 文件是放在项目 根目录 中
-
vue.config.js 文件是webpack配置文件,webpack底层就是node.js
- 使用的是common.js规范
-
vue.config.js 文件
module.exports = {
devServer: {
proxy: {
//一对键值对就是一个反向代理的配置
"/index.php": {
target: "http://www.qinqin.net", //目标源就是你要跨域的目标
ws: true,
changeOrigin: true //修改目标源为我们当前的源
}
}
}
};
注意 修改配置文件,项目要重启 【 特别注意 】
- 下载 axios 模块
import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import axios from "axios"; //
import { Button, TabPane, Tabs } from "element-ui";
Vue.prototype.$https = axios; //
// Vue.use( ElementUI )
Vue.use(Button);
Vue.use(TabPane);
Vue.use(Tabs);
Vue.config.productionTip = false;
new Vue({
render: h => h(App),
router //在根实例中注入路由
}).$mount("#app");
- 向猫眼发送数据请求,并进行布局
category 文件夹> index.vue
<template>
<article>
<div>
<el-button class="button">返回</el-button>
<el-tabs :tab-position="tabPosition">
<el-tab-pane
:label=" category.name"
v-for="category in categorys"
:key="category.cid"
>
<section v-for="floor in category.floors" :key="floor.name">
<h3>{{ floor.name}}</h3>
<section class="elementbox">
<router-link
:to="{ //利用 :to进行传参
name:'list',
params:{
id:ele.api_cid
},
query:{
cid:ele.api_cid
}
}"
v-for="ele in floor.list"
:key="ele.api_cid"
class="element"
>
<div class="imgbox">
<img :src="ele.img" alt />
</div>
<p>{{ ele.name }}</p>
</router-link>
</section>
</section>
</el-tab-pane>
</el-tabs>
</div>
</article>
</template>
<script>
import api from "../../api";
export default {
name: "Category",
data() {
return {
tabPosition: "**left**",
categorys: null
};
},
created() {
//methods和data已经初始化,常用于操作数据,发起ajax请求
this.$https({
url: api.category,
params: {
r: "class/category",
type: 1
}
}).then(res => {
console.log(res.data.data.data);
this.categorys = res.data.data.data;
});
}
};
</script>
<style lang="stylus" scoped>
.button {
position: fixed;
top: 40px;
right: 40px;
}
h3 {
text-align: left;
}
.imgbox {
padding: 10px;
img {
width: 80px;
height: 80px;
}
}
.elementbox {
display: flex;
flex-wrap: wrap;
}
</style>
- 在 src 下面创建 list 文件夹> index.vue,进行 axios 数据请求(用 this.$route.query.cid 进行接参),再进行渲染数据
<template>
<div class="list-items">
<ul>
<li v-for="item in lists" :key="item.id">
<div class="img-box">
<img :src=" item.pic " alt="" />
</div>
<div class="content-box">
<h4>{{ item.d_title }}</h4>
<div class="shop-info-box">
<div class="price-box">
<span> 天猫价:¥{{ item.yuanjia }} </span>
<span> 售后加:¥{{ item.jiage }} </span>
</div>
<div class="number-box">
<span> 已售 {{ item.xiaoliang }} 件 </span>
<span> {{ item.quan_jine }} 元券 </span>
</div>
</div>
</div>
</li>
</ul>
</div>
</template>
<script>
import api from "../../api";
export default {
name: "List",
data() {
return {
lists: null
};
},
created() {
//methods和data已经初始化,常用于操作数据,发起ajax请求
this.$https({
url: api.category,
params: {
r: "class/cyajaxsub",
page: 1,
cid: this.$route.query.cid,
px: "t"
}
})
.then(res => {
console.log("张浩雨: created -> res", res.data.data.content);
this.lists = res.data.data.content;
})
.catch(err => console.log(err));
}
};
</script>
<style lang="stylus">
.list-items
height 100%
ul
padding 10px
width 100%
height 100%
li
width 100%
display flex
margin-bottom 10px
.img-box
width 126px
height 126px
margin-right 12px
img
width 100%
height 100%
</style>
路由传参
1. 在router-link组件的to属性上进行
```html
<router-link
:to = "{
name: 'list',
params: {
id: ele.api_cid
},
query: {
cid: ele.api_cid
}
}"
>
<img :src = " ele.img " alt="">
<span> {{ ele.name }} </span>
</router-link>
```
2. 通过编程式导航来完成
路由接参
- 通过 this.$route就可以将路由路径中的数据接收到,这个就是路由接参
动态路由组件
- 当url发生改变时,对应的组件是不变的,也就是共用了同一个组件,那么这就是动态路由组件
- 编程式导航
编程式的导航
- 除了使用 创建 a 标签来定义导航链接,我们还可以借助 router 的实例方法,通过编写代码来实现。
router.push(location, onComplete?, onAbort?)
注意:在 Vue 实例内部,你可以通过 r o u t e r 访 问 路 由 实 例 。 因 此 你 可 以 调 用 < f o n t > t h i s . router 访问路由实例。因此你可以调用 <font>this. router访问路由实例。因此你可以调用<font>this.router.push。
-
想要导航到不同的 URL,则使用 router.push 方法。这个方法会向 history 栈添加一个新的记录,所以,当用户点击浏览器后退按钮时,则回到之前的 URL。
-
当你点击 时,这个方法会在内部调用,所以说,点击 等同于调用 router.push(…)。
声明式 编程式 < router-link :to="…"> router.push(…)
该方法的参数可以是一个字符串路径,或者一个描述地址的对象。例如:
// 字符串
router.push("home");
// 对象
router.push({ path: "home" });
// 命名的路由
router.push({ name: "user", params: { userId: "123" } });
// 带查询参数,变成 /register?plan=private
router.push({ path: "register", query: { plan: "private" } });
注意:如果提供了 path,params 会被忽略,上述例子中的 query 并不属于这种情况。取而代之的是下面例子的做法,你需要提供路由的 name 或手写完整的带有参数的 path:
const userId = "123";
router.push({ name: "user", params: { userId } }); // -> /user/123
router.push({ path: `/user/${userId}` }); // -> /user/123
// 这里的 params 不生效
router.push({ path: "/user", params: { userId } }); // -> /user
同样的规则也适用于 router-link 组件的 to 属性。
router.replace(location, onComplete?, onAbort?)
跟 router.push 很像,唯一的不同就是,它不会向 history 添加新记录,而是跟它的方法名一样 —— 替换掉当前的 history 记录。
声明式 | 编程式 |
---|---|
< router-link :to="…" replace> | router.replace(…) |
router.go(n)
这个方法的参数是一个整数,意思是在 history 记录中向前或者后退多少步,类似 window.history.go(n)。
// 在浏览器记录中前进一步,等同于 history.forward()
router.go(1);
// 后退一步记录,等同于 history.back()
router.go(-1);
// 前进 3 步记录
router.go(3);
// 如果 history 记录不够用,那就默默地失败呗
router.go(-100);
router.go(100);
- push()
- replace()
- go()
- push vs replace
- replace 不会将我们的页面跳转放入历史记录,效果是返回2层
- push 会将我们的页面跳转放入历史记录,效果返回一层
- 如果我们给组件身上添加原生事件,那么我们需要加一个修饰符 native
<el-button type="primary" @click.native="goLogin"> 登录 </el-button>