vue列表点到详情
1、routes里面设置id
{path:"/carrier-show/:id",component:CarrierShow},
2、设置列表router-link
<router-link v-for="item in carrierList" :key="item.id" :to="'/carrier-show/' + item.id"">
<div class="item-title line-2-overflow">{{item.title}}</div>
</router-link>
3、列表设置data
export default {
data(){
return {
carrierList: [],
labels: []
}
},
created(){
// this.$http.get('http://jsonplaceholder.typicode.com/posts')
this.$http.get('/json/carrierListShow/carrierList.json')
.then(res =>{
this.carrierList = res.body.list;
},(error) =>{
console.log("失败提示为:" + error)
})
}
}
4、详情
获取地址栏id、通过filter筛选对应列表传过来的id,如果对应就赋值
export default {
data(){
return {
id: this.$route.params.id,
list: [],
flag: false
}
},
created(){
//this.$http.get('http://jsonplaceholder.typicode.com/posts/' + this.id)
this.$http.get('/json/carrierListShow/carrierShow.json')
.then(function(data){
this.list = data.body;
console.log("地址栏中的id: " + this.id)
})
},
computed:{
showList: function(){
let self = this;
console.log(this.list)
return self.list.filter(function(ele){
return ele.id == self.id
})
}
}
}
1、点击菜单展示隐藏-----与------点击菜单外地方隐藏菜单
<div v-on:click="toggle()" class="drop-entry"><i class="iconfont icon-sandian"></i></div>
<div v-show="isShow" class="drop-down J_drop_down">
<router-link to="/" class="drop-item">首页</router-link>
<router-link to="personal" class="drop-item">个人中心</router-link>
</div>
data() {
return {
isShow : false
}
},
mounted() {
let _this = this;
document.addEventListener("click",function(e){
//console.log(e.target)
// 下面这句代码是获取 点击的区域是否包含你的菜单,如果包含就返回true,说明点击的是菜单以外,不包含就返回false则为菜单以内
let flag = e.target.contains(document.getElementsByClassName("J_drop_down")[0])
if(!flag) return;
_this.isShow = false;
//注意,这里不能直接this.isShow = !this.isShow; 要_this
})
},
methods: {
toggle: function(){
this.isShow = !this.isShow; //改变data状态达到显示隐藏
},
goToPrev: function(){
this.$router.go(-1) //返回上一浏览页面
}
}
<style>.drop-down{display: none}</style>
2、contains
在Java语言中,contains可以用于判断str1是否包含str2
原生JS中是有contains方法的
但它并不是字符串方法,,仅用于判断DOM元素的包含关系,参数是Element类型
若要在JS中判断俩字符串的包含关系,用indexOf()
3、v-if v-show
v-if
是真实的条件渲染,因为它会确保条件块在切换当中适当地销毁与重建条件块内的事件监听器和子组件。v-if
也是惰性的:如果在初始渲染时条件为假,则什么也不做——在条件第一次变为真时才开始局部编译(编译会被缓存起来)。
相比之下,v-show
简单得多——元素始终被编译并保留,只是简单地基于 CSS 切换。
一般来说,v-if
有更高的切换消耗而v-show
有更高的初始渲染消耗。因此,如果需要频繁切换使用v-show
较好,如果在运行时条件不大可能改变则使用v-if
较好。
4、created mounted
created:在模板渲染成html前调用,即通常初始化某些属性值,然后再渲染成视图。
mounted:在模板渲染成html后调用,通常是初始化页面完成后,再对html的dom节点进行一些需要的操作。
通常created使用的次数多,而mounted通常是在一些插件的使用或者组件的使用中进行操作,比如插件chart.js的使用: var ctx = document.getElementById(ID);通常会有这一步,而如果你写入组件中,你会发现在created中无法对chart进行一些初始化配置,一定要等这个html渲染完后才可以进行,那么mounted就是不二之选
5、Tab切换
方法一: 实现二级路由(三级路由同理)实现 不是返回真正的上一页面,而是上一组件
//先导入
import MapWrap from './components/Carrier/MapWrap/MapWrap.vue'
import MapTravel from './components/Carrier/MapWrap/MapTravel.vue'
import MapMating from './components/Carrier/MapWrap/MapMating.vue'
//配置路径
{path:"/map",component:MapWrap,redirect:"/map-travel",children:[
{path:"/map-travel",component:MapTravel},
{path:"/map-mating",component:MapMating}
]}
//模块
<template>
<section>
<ul>
<router-link to="map-travel" tag="li"><span>出行情况</span></router-link>
<router-link to="map-mating" tag="li"><span>配套情况</span></router-link>
</ul>
<div class="tab-block active">
<router-view></router-view>
</div>
</section>
</template>
搞定,但是如果此刻还有返回上一页的按钮的话就要使用tab切换的方式,这样返回就会返回组件,
而不是返回真正的上一页面。所以就要换一种tab切换方法
返回上一页也可以用 this.$router.go(-1)
<a href="javascript:history.back(-1)" class="nav-bar-left"></a>
如果按照以上方法,会导致地址栏后暴露路由,显然不是我们想要的,我想要的只是一个内部的tab切换
方法二: Tab切换之------------------v-show展示
(本方法:tab对应的选项卡只是普通文本,多用于展示性组件)
(地址路由不会展示在地址栏中,所以如果返回上一页,就可以返回真正的上一页而不是上一路由)
<ul>
<li class="li-tab" v-for="(item,index) in tabsParam"
@click="toggleTabs(index)"
:class="{active:index===nowIndex}">{{item}}
</li>
</ul>
<!--切换项组件-->
<search v-show="nowIndex===0"></search>
<location v-show="nowIndex===1"></location>
data() {
return {
tabsParam:['搜索','地址'],
nowIndex: 0,
isShow: false
}
},
methods: {
//切换tab项
toggleTabs(index){
this.nowIndex = index;
}
}
以上方法已经实现tab切换,但是这不是一个组件写法。所以准备封装
Tab切换组件封装
地址栏中无路由名字,并且是一个tab封装组件
效果图:
需求
- 简易版
tab对应的选项卡只是普通文本,多用于展示性组件 - 复杂版
tab对应的选项卡包括表格,按钮,图标,表单等多种元素,包括数据交互、与父组件的通信等 - 性能优化
切换tab时,缓存组件
方案
- Prop
父组件向子组件传递参数
tabList(tabs标题列表)、tabIndex(当前的tab序号) - 自定义事件
切换tab事件 - slot
内容分发 - 动态组件
keep-alive:如果把切换出去的组件保留在内存中,可以保留它的状态或避免重新渲染
复杂化
如果是第一种需求,可以不必自己写组件,UI框架中现有的功能完全可以满足需求。
如果是第二种需求,一般没有完全合适的UI组件,而本例是一种解决方案。
- 封装tab公共部分
- tab对应的内容区域使用slot内容分发
- ajax请求数据等操作是在分发内容组件中执行的
- 钩子函数activated
通过activated监听组件是否激活
实现
新建组件
main.js或者路由文件里面引入并注册
import MyTab from './components/Tab/MyTab.vue'
import EnterpriseUser from './components/Tab/UserTab/EnterpriseUser.vue'
import GovernmentPark from './components/Tab/UserTab/GovernmentPark.vue'
{path:"/my-tab",component:MyTab},
{path:"/enterprise-user",name:"enterprise-user",component:EnterpriseUser},
{path:"/government-park",component:GovernmentPark},
应用组件,如在index页面中(或者其他页面)
<my-tab :tabList="tabList" :tabIndex="tabIndex" @changeTab="changeTab">
<keep-alive>
<component :is="currentContent"></component>
</keep-alive>
</my-tab>
import MyTab from './Tab/MyTab'
import EnterpriseUser from './Tab/UserTab/EnterpriseUser'
import GovernmentPark from './Tab/UserTab/GovernmentPark'
export default {
data() {
return {
tabIndex: 0,
currentContent: 'enterprise-user',
tabList: [
{
index: 0,
name: '企业用户',
component: 'enterprise-user'
},
{
index: 1,
name: '政府园区',
component: 'government-park'
}
]
},
components: {
'my-tab': MyTab,
'enterprise-user': EnterpriseUser,
'government-park': GovernmentPark
},
methods: {
// 切换选项卡
changeTab: function (tab) {
this.tabIndex = tab.index
this.currentContent = tab.component
}
}
}
搞定收工!
6、列表渲染动态数据
首先,vue3.x静态json需要放在publice文件夹下
列表页
data(){
return {
carrierList: [],
labels: []
}
},
created(){
/* 请求http资源 jsonplaceholder
this.$http.get('http://jsonplaceholder.typicode.com/posts')
.then(function(data){
console.log(data)
this.carrierList = data.body.slice(0,10) //获取前面10条数据
})
*/
//请求本地json资源
this.$http.get('json/carrierListShow/carrierList.json')
.then(res =>{
this.carrierList = res.body.list;
},(error) =>{
console.log("失败提示为:" + error)
})
}
n、错误信息
错误信息1:少了个s
[Vue warn]: Unknown custom element: <nav-bar> - did you register the component correctly? For recursive components, make sure to provide the "name" option.
found in
---> <WinnewsShow>
<App> at src/App.vue
<Root>
因为component少了个s
错误信息2:少了个逗号“”,“”
Unexpected token, expected "," (54:1) 52 | 'nav-bar': NavBar 53 | } > 54 | data(){ | ^ 55 | return { 56 | 57 | }
因为component少了个逗号“”,“”
错误信息3: 图片未找到而报错,引用地址出错
Module not found: Error: Can't resolve './resources/images/logo.png'
错误信息4:标签错误也会导致显示组件出错
[Vue warn]: Unknown custom element: <sectiion> - did you register the component correctly? For recursive components, make sure to provide the "name" option.
found in
---> <Register> at src/components/Personal/Register.vue
<App> at src/App.vue
<Root>
<sectiion class="form-section"></sectiion>
应该为<section class="form-sectiion"></section>
错误提示5: 检查组件名字是否写对
`F:\hvzhao-mobile\i.hvzhao\src\components\Winnews\WinNewsHeader.vue` does not match the corresponding path on disk `WinNews`.
组件,不能和html标签重复
vue报错 Do not use built-in or reserved HTML elements as component id:header
组件,不能和html标签重复
header组件,h5新标签重复
Do not use built-in or reserved HTML elements as component id:header
由于在模板需要插入到 DOM 中,所以模板中的标签名必须能够被 DOM 正确地解析。主要有三种情况:
一是完全不合法的标签名,例如 </>;
二是与 HTML 元素重名会产生不确定的行为,例如使用 input 做组件名不会解析到自定义组件,使用 button 在 Chrome 上正常但在 IE 上不正常;
三是与 Vue 保留的 slot、partial、component 重名,因为会优先以本身的意义解析,从而产生非预期的结果。
vue 请求json路径报错,404
vue-resource.esm.js?5a4b:1082 GET http://192.168.1.133:9999/json/newsShow/newsShow.json 404 (Not Found)