组件的基本代码
Vue.component('ym-search', {
template: `
搜索
清空
搜索
高级搜索
{{item.name}}:{{item.value}}
`,
data() {
return {
searchHeight: '52px', // 搜索框的默认高度52
showHighBtn: false, // 是否显示“高级搜索”按钮
hideBtn: false, // 隐藏“搜索”按钮与“高级搜索”按钮
showResult: false, // 搜索完成后是否显示搜索结果
}
},
props: {
// 搜索元素的个数
itemNum: {
type: Number,
default: 1
},
// 搜索后要显示的结果集合
results: Array
},
watch: {
// 页面初始化时需要默认一些条件
results(val) {
this.$nextTick(()=>{
if((val.length > 0) && this.showHighBtn) {
this.showResult = true
}
})
}
},
mounted() {
// 根据搜索框的宽度以及搜索元素的宽度,计算是否显示“高级搜索”按钮
this.$nextTick(() => {
let wrapW = +window.getComputedStyle(this.$refs.searchWrap).width.replace('px', ''),
itemW = 322,
btnW = 180,
n = Math.floor((wrapW - btnW) / itemW)
if (this.itemNum > n) {
this.showHighBtn = true
if (this.results.length > 0) this.showResult = true
}
})
},
methods: {
// 清空
cleanAll() {
this.$emit('clear')
},
// 搜索
toSearch(tag) {
this.$emit('search')
this.$nextTick(() => {
// 如果是高级中的搜索按钮,点击后显示搜索内容
if (+tag === 1) {
if (this.results.length > 0) {
this.showResult = true
} else {
this.searchHeight = '52px'
this.hideBtn = false
}
}
})
},
showSearch() {
this.showResult = false
if (this.results.length > 0) {
this.searchHeight = 'auto'
this.hideBtn = true
}
},
// 显示高级搜索内容
toHighSearch() {
this.searchHeight = 'auto'
this.hideBtn = true
},
// 收起
slideUp() {
if (this.results.length > 0) {
this.showResult = true
} else {
this.searchHeight = '52px'
this.hideBtn = false
}
}
}
})
同时,也写入了全局混入
Vue.mixin({
data() {
return {
// 所有的搜索属性v-model集合
searchData: {},
// 搜索结果--用于展示
searchResults: [],
// 搜索属性请求数据集合
requestData: {},
}
},
methods: {
// 可在调用页面自定义toSearchBefore和toSearchAfter方法
toSearch() {
if(!!this.toSearchBefore) {
this.toSearchBefore.apply(this, arguments)
}
let {
results,
request
} = packageRequestAndResults(this.searchData)
this.searchResults = results
this.requestData = request
this.pageChange(1)
if(!!this.toSearchAfter) {
this.toSearchAfter.apply(this, arguments)
}
},
clearSearch() {
this.searchData = {}
this.requestData = {}
this.searchResults = []
}
}
})
上面代码中涉及到一个packageRequestAndResults
方法
// 根据searchBaseData和searchData组装显示results和请求数据request
function packageRequestAndResults(searchData) {
let results = [] // 搜索结果展示
let request = {} // 用于请求接口数据
Object.keys(searchData).forEach(k => {
let string_empty = Object.prototype.toString.apply(searchData[k]) === '[object String]' && searchData[k] === '',
array_empty = Object.prototype.toString.apply(searchData[k]) === '[object Array]' && searchData[k].length === 0
if (!string_empty && !array_empty && !!searchData[k]) {
let obj = searchBaseData[k],
name = ''
if (!!obj) {
if (obj.type === 'input') {
name = searchData[k]
request[k] = searchData[k]
} else if (obj.type === 'date') {
name = searchData[k][0] + ' ~ ' + searchData[k][1]
request['START' + k] = searchData[k][0]
request['END' + k] = searchData[k][1]
} else {
name = obj.getName(searchData[k])
request[k] = obj.getVal(searchData[k])
}
results.push({
name: obj.name,
value: name
})
}
}
})
return {
results,
request
}
}
上面有一个searchBaseData
,下面即将出场
页面使用
微信昵称
关注时间
身份
item-num必须与搜索item的个数一致,绑定results,clear,search无需改名,因为上面的mixins中已定义,除非不能满足需求,可重定义v-model的格式须是searchData.xxx,xxx为请求参数的key,如果是日期格式且key为STARTSUBSCRIBETIME和ENDSUBSCRIBETIME,需要去掉START和END,如果不是,下面再讲
下面重要环节,必须声明一个searchBaseData
对象,包含每个搜索item
let searchBaseData = {
// 如果显示与value一致,可直接指定type=input
KEYWORD_SEARCH: {
name: '微信昵称',
type: 'input'
},
// 如果请求key以'START'和'END'开头,可直接指定type=date,如果不是,则采用下面的方式
SUBSCRIBETIME: {
name: '关注时间',
type: 'date'
},
// 如果显示和value无规律,可指定getName和getVal
FCUSTOMERSTATUS: {
name: '身份',
getName(val) {
let arr = ['潜客', '车主', '关注', '会员']
return arr[+val]
},
getVal(val) {
return val
}
},
}
代码在此
END