赞
踩
有的时候,我们可能也会用到 queryString
<select v-model="sort">
<option value="desc">从高到低</option>
<option value="asc">从低到高</option>
</select>
我们可以通过路由对象 $route 的 query 属性来获取 queryString
...
computed: {
sort: {
get() {
return this.$route.query.sort || 'desc';
}
}
}
...
有的时候,我们可能需要用到编程的方式来导航(跳转),而不是点击链接。如:当 sort
发生改变的时候跳转
... computed: { sort: { get() { return this.$route.query.sort || 'desc'; }, set(newVal) { this.$router.push({ name: 'home', query: { sort: newVal } }); } } } ...
我们对商品进行排序:最好不要用内部状态
处理这件事,因为如果分享链接,无法保留分享前的状态。
所以最好的方式是用路由跳转
。
我们可以用watch
监听sort
数据变化
\app\src\views\Home.vue
<template> <div> <h2>商品列表</h2> <select v-model="sort"> <option value="desc">从高到低</option> <option value="asc">从低到高</option> </select> <ul class="item-list"> <li class="head"> <span>名称</span> <span>价格</span> <span>操作</span> </li> <li v-for="item of items" :key="item.id"> <span> <router-link :to='"/view/" + item.id'>{{item.name}}</router-link> </span> <span>{{item.price|RMB}}</span> <span> <button>添加到购物车</button> </span> </li> </ul> </div> </template> <script> import * as apis from '@/apis' import {RMB} from "@/filters/RMB"; export default { name: "Home", data() { return { sort: 'desc', items: [] } }, async created() { let rs = await apis.getItems(); this.items = rs.data; }, // 局部过滤器引入,挂载到filters filters: { RMB }, watch: { // 监听sort数据变化 sort() { console.log('......') } } } </script> <style> ul { margin: 0; padding: 0; } li { list-style: none; } .item-list li { padding: 10px; display: flex; justify-content: space-between; height: 30px; line-height: 30px; border-bottom: 1px dotted #333; } .item-list li.head { font-weight: bold; } .item-list li span { min-width: 200px; } </style>
参考:https://https://github.com/6xiaoDi/blog-vue-Novice/tree/a1.82
Branch: branch05commit description:a1.82(example01-1——
watch
监听sort
数据变化)tag:a1.82
或者绑定change
事件 => 就没必要进行双向绑定,直接用v-bind
了。
\app\src\views\Home.vue
<template> <div> <h2>商品列表</h2> <select @change="changeSort" :value="sort"> <option value="desc">从高到低</option> <option value="asc">从低到高</option> </select> <ul class="item-list"> <li class="head"> <span>名称</span> <span>价格</span> <span>操作</span> </li> <li v-for="item of items" :key="item.id"> <span> <router-link :to='"/view/" + item.id'>{{item.name}}</router-link> </span> <span>{{item.price|RMB}}</span> <span> <button>添加到购物车</button> </span> </li> </ul> </div> </template> <script> import * as apis from '@/apis' import {RMB} from "@/filters/RMB"; export default { name: "Home", data() { return { sort: 'desc', items: [] } }, async created() { let rs = await apis.getItems(); this.items = rs.data; }, // 局部过滤器引入,挂载到filters filters: { RMB }, // watch: { // // 监听sort数据变化 // sort() { // console.log('......') // } // } methods: { changeSort({target: {value}}) { this.$router.push('/?sort=' + value) } } } </script> <style> ul { margin: 0; padding: 0; } li { list-style: none; } .item-list li { padding: 10px; display: flex; justify-content: space-between; height: 30px; line-height: 30px; border-bottom: 1px dotted #333; } .item-list li.head { font-weight: bold; } .item-list li span { min-width: 200px; } </style>
参考:https://https://github.com/6xiaoDi/blog-vue-Novice/tree/a1.83
Branch: branch05commit description:a1.83(example01-2——绑定
change
事件监听sort
数据变化)tag:a1.83
路由配置还可以给路由起名字(和给组件起名称一样),方便去复用。
\app\src\router\index.js
import Vue from 'vue'; import VueRouter from 'vue-router'; import Home from '@/views/Home'; import About from '@/views/About'; import Detail from '@/views/Detail'; Vue.use(VueRouter); let router = new VueRouter({ mode: 'history', routes: [ { path: '/', name: 'home', component: Home }, { path: '/about', name: 'about', component: About }, { path: '/view/:id', name: 'view', component: Detail } ] }); export default router;
router-link :to='"/view/" + item.id'
拼(字符串)路由跳转的url
易出错,可以用(路由)对象去描述
这个对象会自动解析成url
格式
name
属性就是对应我们要跳转的页面路由的name
params
属性配置就是后面参数了 => item.id
router-link :to="{name: 'view', params: {id: item.id}}"
this.$router.push
=> 配置对象 =>
name
属性就是对应我们要跳转的页面路由的name
query
其实就是queryString将其赋值给sort
\app\src\views\Home.vue
<template> <div> <h2>商品列表</h2> <select @change="changeSort" :value="sort"> <option value="desc">从高到低</option> <option value="asc">从低到高</option> </select> <ul class="item-list"> <li class="head"> <span>名称</span> <span>价格</span> <span>操作</span> </li> <li v-for="item of items" :key="item.id"> <span> <router-link :to="{name: 'view', params: {id: item.id}}">{{item.name}}</router-link> </span> <span>{{item.price|RMB}}</span> <span> <button>添加到购物车</button> </span> </li> </ul> </div> </template> <script> import * as apis from '@/apis' import {RMB} from "@/filters/RMB"; export default { name: "Home", data() { return { sort: 'desc', items: [] } }, async created() { let rs = await apis.getItems(); this.items = rs.data; }, // 局部过滤器引入,挂载到filters filters: { RMB }, // watch: { // // 监听sort数据变化 // sort() { // console.log('......') // } // } methods: { changeSort({target: {value}}) { this.$router.push({ name: 'home', query: { sort: value } }); } } } </script> <style> ul { margin: 0; padding: 0; } li { list-style: none; } .item-list li { padding: 10px; display: flex; justify-content: space-between; height: 30px; line-height: 30px; border-bottom: 1px dotted #333; } .item-list li.head { font-weight: bold; } .item-list li span { min-width: 200px; } </style>
router-link
成功生成 正确的href
发现问题:页面未发生任何渲染
参考:https://https://github.com/6xiaoDi/blog-vue-Novice/tree/a1.84
Branch: branch05commit description:a1.84(example01-3——路由配置名称可复用但出了问题)
tag:a1.84
为了提高性能,增强路由组件的复用,当路由切换(页面跳转
)使用的是同一个组件的时候,则会复用该路由组件,而不是销毁重建,这个时候,我们就需要通过 watch 或者 路由相关的生命周期函数来处理切换路由导致的变化。
所以上面的例子,我们始终还在Home
路由(组件)上,所以为了节省性能,Home
组件是不会销毁重建的,而是复用。这个时候我们再监听sort
的变化是没有任何用的,因为仅仅是地址栏发生了变化,数据实际没有变化。
所以实际上我们应该监听 $route
,它代表当前匹配的路由对象,地址发生了变化,它必然会变化。
如果切换的路由复用了组件,这个时候,我们可以使用 watch 监听 $route(当前路由匹配的对象必然改变)
watch: {
$route(to, from) {
console.log('$route');
}
}
to
: 改变之后的 $route 对象from
: 改变之前的 $route 对象但是我们可以使用 vue-router 提供路由守卫 (路由有关的生命周期函数)来处理路由有关的业务逻辑
我们可以打印看看$route(to, from)
中的参数。
\app\src\views\Home.vue
watch: {
$route(to, from) {
console.log(from);
console.log(to);
}
},
进入页面后的query
为空,我们切换从低到高
。
再切换到从高到低
参考:https://https://github.com/6xiaoDi/blog-vue-Novice/tree/a1.85
Branch: branch05commit description:a1.85(example02-1——打印看看
$route(to, from)
中的参数)tag:a1.85
监听$route,发生变化,重新发请求即可,后端有排序的接口,这里我们直接调用即可,我们改一下之前封装的接口即可。
\app\src\apis\index.js
import axios from 'axios' import URLS from './URLS' // export async function getItems() { export async function getItems(sort) { let rs = await axios({ url: URLS.ITEMS + '?sort=' + sort // url: URLS.ITEMS }); return rs; } export async function getItem(id) { let rs = await axios({ url: URLS.ITEM + '/' + id }); return rs; }
实际上我们把sort
定义在data
中,我们是从url
中获取的,我们实际在watch
的时候需要更新它。
并且页面一开始加载出来的时候,做初始化。
\app\src\views\Home.vue
<template> <div> <h2>商品列表</h2> <select @change="changeSort" :value="sort"> <option value="desc">从高到低</option> <option value="asc">从低到高</option> </select> <ul class="item-list"> <li class="head"> <span>名称</span> <span>价格</span> <span>操作</span> </li> <li v-for="item of items" :key="item.id"> <span> <router-link :to="{name: 'view', params: {id: item.id}}">{{item.name}}</router-link> </span> <span>{{item.price|RMB}}</span> <span> <button>添加到购物车</button> </span> </li> </ul> </div> </template> <script> import * as apis from '@/apis' import {RMB} from "@/filters/RMB"; export default { name: "Home", data() { return { sort: 'desc', items: [] } }, async created() { this.sort = this.$route.query.sort || 'desc'; let rs = await apis.getItems(this.sort); this.items = rs.data; }, // 局部过滤器引入,挂载到filters filters: { RMB }, watch: { async $route(to, from) { this.sort = this.$route.query.sort || 'desc'; let rs = await apis.getItems(this.sort); this.items = rs.data; } }, methods: { changeSort({target: {value}}) { this.$router.push({ name: 'home', query: { sort: value } }); } } } </script> <style> ul { margin: 0; padding: 0; } li { list-style: none; } .item-list li { padding: 10px; display: flex; justify-content: space-between; height: 30px; line-height: 30px; border-bottom: 1px dotted #333; } .item-list li.head { font-weight: bold; } .item-list li span { min-width: 200px; } </style>
参考:https://https://github.com/6xiaoDi/blog-vue-Novice/tree/a1.86
Branch: branch05commit description:a1.86(example02-2——实现排序切换)
tag:a1.86
有冗余代码极为相似,得优化一下。 => 封装
\app\src\views\Home.vue
<template> <div> <h2>商品列表</h2> <select @change="changeSort" :value="sort"> <option value="desc">从高到低</option> <option value="asc">从低到高</option> </select> <ul class="item-list"> <li class="head"> <span>名称</span> <span>价格</span> <span>操作</span> </li> <li v-for="item of items" :key="item.id"> <span> <router-link :to="{name: 'view', params: {id: item.id}}">{{item.name}}</router-link> </span> <span>{{item.price|RMB}}</span> <span> <button>添加到购物车</button> </span> </li> </ul> </div> </template> <script> import * as apis from '@/apis' import {RMB} from "@/filters/RMB"; export default { name: "Home", data() { return { sort: 'desc', items: [] } }, async created() { this.getItems(); }, // 局部过滤器引入,挂载到filters filters: { RMB }, watch: { async $route(to, from) { this.getItems(); } }, methods: { changeSort({target: {value}}) { this.$router.push({ name: 'home', query: { sort: value } }); }, async getItems() { this.sort = this.$route.query.sort || 'desc'; let rs = await apis.getItems(this.sort); this.items = rs.data; } } } </script> <style> ul { margin: 0; padding: 0; } li { list-style: none; } .item-list li { padding: 10px; display: flex; justify-content: space-between; height: 30px; line-height: 30px; border-bottom: 1px dotted #333; } .item-list li.head { font-weight: bold; } .item-list li span { min-width: 200px; } </style>
参考:https://https://github.com/6xiaoDi/blog-vue-Novice/tree/a1.87
Branch: branch05commit description:a1.87(example02-3——实现排序切换-代码优化)
tag:a1.87
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。