1、文字超出部分…显示
overflow:hidden;/*超出部分隐藏*/
text-overflow:ellipsis;/*超出部分显示...*/
white-space:nowrap;/*文本强制一行显示*/
2、文字超出部分换行显示
flex-wrap:wrap;/*拆行*/
white-space:normal;/*文本强制换行*/
word-wrap:break-word;/*单词最后不分割*/
/*换行*//**/
word-break:break-all;/* 内容到达宽度自动换行,如果最后一个单词长,难么会分割显示 */
word-wrap:break-word;/* 内容到达宽度自动换行,如果最后一个单词过长,不会分割,会到下一行*/
text-align:justify/*文本水平对齐方式、两端对齐效果*/
text-justify:newspaper;/* 通过增加或减少字母之间的空格来对齐文本,来实现两端对齐 */
3、点击某个点亮
<view class="left-item" v-for="(item,i) in leftList" :key="i" @click="activeLive(i)">
<view :class="['text', activeNum===i?'active':'']">{{item.cat_name}}</view>
<view :style="{heighr:wh+'px'}"></view>
</view>
data() {
return{
activeNum:0,
wh:0
}
},
methods: {
activeLive(i) {
this.activeNum = i
}
}
&.active{
background-color: #eeee;
}
4、搜索框吸顶
/*给搜索框父级*/
position: sticky;
top: 0;
z-index: 999;
5、点击选项卡,右侧滚动条不置顶
<scroll-view scroll-y class="right" :style="{height: wh + 'px'}" :scroll-top="scrollTop">
//右侧滚动条动态添加 :scroll-top
</scroll-view>
//scrollTop: 0,
//左侧选项卡点击事件
//activeLive(i) {this.scrollTop = this.scrollTop === 0 ? 0.5 : 0}
6、输入框的防抖一次写入过多
//data中定义 timer:null, keywords:'',
//methods:
input(e) {
clearTimeout(this.timer)
this.timer = setTimeout(()=>{
this.keywords = e
},500)
}
//防抖
let timer = null
function debounce(fn,delay) {
clearTimeout(timer)
timer = setTimeout(()=>{
console.log('防抖')
},500)
}
//节流
let valid = true
if(!valid) return
valid = false
setTimeout(()=>{
console.log('函数节流')
valid = true
},500)
7、商品列表思路
·商品列表页
1.发起请求获取数据,需要传参
2.参数通过onload(value)获取参数
3.通过async await获取数据,然后渲染数据
4.上拉加载数据
判断 pagenum页数*pagesize页量>total,大于就return,不再执行
5-判断isload真假 ,真就说明数据还在请求,直接return,不执行下面的页数++等
先在page.js中的style设置"onReachBottomDistance": 100
让页数pagenum++
最后重新发起数据请求
重写请求方法,使数据 this.goodsList = [...this.goodsList,...res.message.goods]
5.节流防止一直下拉,数据还在请求、用户就一直下拉
data() 中定义 isload:false
methods中,请求发送之前赋值为true this.isload = true,数据请求发送完成 赋值为false
this.isloading = true
const {data:res} = await this.$myRequest({
url: '/api/public/v1/goods/search',
data: this.goodsListParams,
})
this.isloading = false
6下拉刷新数据
在page.js中开启 "enablePullDownRefresh": true,
调用方法onPullDownRefresh(),让某些重要数据重新赋值
页数、总量、数据列表、isload、重新发起请求并且传入停止的刷新的函数
this.getGoodsList(() => {uni.stopPullDownRefresh()}),再重写请求方法传入参数
getGoodsList(cb) {cb&&cb()}//这种方法很贴切,不用写setTimeout设置时间来关闭刷新图标
<template>
<view>
<view class="goodlist-box">
<view class="goodlist-item" v-for="(item,i) in goodsList" :key="i" @click="gotoGoodDetail(item)">
<my-goodlist :goodsList="item"></my-goodlist>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
isloading: false,
goodsListParams:{
query: '',
cid: '',
pagenum: 1,
pagesize: 10
},
goodsList:[],
total:0,
defaultpg:'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1212681992,4124630859&fm=26&gp=0.jpg'
};
},
onLoad(value) {
console.log(value)
this.goodsListParams.cid = value.cid || ''
this.goodsListParams.query = value.query || ''
this.getGoodsList()
},
methods: {
async getGoodsList(cb) {
this.isloading = true
const {data:res} = await this.$myRequest({
url: '/api/public/v1/goods/search',
data: this.goodsListParams,
})
this.isloading = false
cb&&cb()
this.goodsList = [...this.goodsList,...res.message.goods]
this.total = res.message.total
},
gotoGoodDetail(item) {
uni.navigateTo({
url: '/subpkg/goods_detail/goods_detail?goods_id=' + item.goods_id
})
}
},
// 上拉加载
onReachBottom() {
if(this.goodsListParams.pagenum * this.goodsListParams.pagesize > this.total) {
return uni.showToast({
title:'我到底啦'
})
}
//如果isloading为true,说明在请求数据,则后面代码不执行
if(this.isloading) return
this.goodsListParams.pagenum++
this.getGoodsList()
},
// 下拉刷新
onPullDownRefresh() {
this.goodsListParams.pagenum = 1
this.total = 0
this.isloading = false
this.goodsList = []
this.getGoodsList(() => {uni.stopPullDownRefresh()})
}
}
</script>
8、搜索页面思路
- 使用uni-ui布局搜索框,输入内容时input方法可以获取输入的内容-keyword,对用户输入时做节流功能,防止用户快速一直输入一直输出结果
- 发起查询请求,请求参数是输入内容 keyword,得到结果searchList之后书写ui框架进行渲染,渲染之后进行美化,点击对应的列表能进行跳转到商品列表,传入参数item,uni.navigator({url:’’})进行跳转到商品列表
- 若没有搜索词,那么需要让searchlist重置为空,在请求数据之前,return出去
- 将搜索框输入的关键字保存到searchHistoryList中,通过set方法让获取的值不会重复,set得到的是对象,需要通过Array.from转为数组,通过computed计算属性使searchHistoryList能反转,让最近的搜索排在前面,最后将得到的searchHistoryList,通过JSON.stringify保存到本地Storage中
uni.setStorageSync('keyword', JSON.stringify(this.historylist))
- 在onload需要获取本地保存的searchHistoryList,这个值有为空的可能,
this.searchHistoryList = JSON.parse(uni.getStorageSync('keyword')||'')
,需要将本地Storage中字符串形式保存的key:value转为JSON对象格式
<template> <view> <view class="search"> <uni-search-bar :cancelButton="none" :radius="100" @input="input" ></uni-search-bar> </view> <view class="response" v-if="queryList.length!==0"> <view class="search-text" v-for="(item,i) in queryList" :key="i" @click="gotoGoodsList(item)"> <text>{{item.goods_name}}</text> <uni-icons type="arrowright" size="18" ></uni-icons> </view> </view> <view class="history-box" v-else> <view class="history-delete"> <text>搜索历史</text> <uni-icons class="trash" type="trash" size="18" @click="deleteList"></uni-icons> </view> <view class="history-list"> <!-- <view class="" v-for="(item, i) in historys" :key="i"> <uni-tag :text="item" @click="gotoTag(item)"></uni-tag> </view> --> <uni-tag :text="item" @click="gotoTag(item)" v-for="(item, i) in historys" :key="i"></uni-tag> </view> </view> </view></template><script> export default { data() { return { timer: null, // 关键词 keyword:'', // 搜索结果列表 queryList:[], // 历史记录列表 historylist:[] }; }, // 获取本地保存的搜索记录 onLoad() { // 一定要 || '', 不然刚进来的用户没有记录就会报错 this.historylist = JSON.parse(uni.getStorageSync('keyword') || ''); }, computed:{ // 对搜索记录list进行反转,最后搜索的在最前面 historys() { return [...this.historylist].reverse() } }, methods: { // 防抖,防止用户快速输入 input(e) { // console.log(e) clearTimeout(this.timer) this.timer = setTimeout(()=>{ this.keyword = e console.log(this.keyword) this.getQueryList() },500) }, // 删除历史记录信息 deleteList() { this.historylist = [] uni.setStorageSync('keyword', '') }, // 跳转到商品列表页面 gotoTag(item) { uni.navigateTo({ url:'/subpkg/goods_list/goods_list?query=' + item }) }, // 获取推荐查询 async getQueryList() { // 判断关键词是否为空 if(this.keyword == '') { return this.queryList = [] } const {data:res} = await this.$myRequest({ url: '/api/public/v1/goods/qsearch', method: 'GET', data:{query: this.keyword} }) console.log(res.message) this.queryList = res.message // 获取到数据之后,在进行保存方法 this.saveSearchHistory() }, // 存储数据 saveSearchHistory() { // this.historylist.unshift(this.keyword) // 使用set方法,只能获取单一值,不会重复 const res = new Set(this.historylist) res.delete(this.keyword) res.add(this.keyword) console.log('res:',res) console.log(typeof res) this.historylist = Array.from(res) // 将搜索框输入的关键词,以JSON字符串形式保存在Storage中 uni.setStorageSync('keyword', JSON.stringify(this.historylist)) }, // 跳转到商品详情页面 gotoGoodsList(item) { uni.navigateTo({ url:'/subpkg/goods_detail/goods_detail?goods_id=' + item.goods_id }) }, } }</script><style lang="scss">.search{ position: sticky; top: 0; z-index: 999; background-color: #C00000;}.search-text{ display: flex; justify-content: space-between; align-items: center; padding: 15px; text{ overflow:hidden;/*超出部分隐藏*/ text-overflow:ellipsis;/*超出部分显示...*/ white-space:nowrap;/*文本强制一行显示*/ font-size: 14px; color: #424242; }}.history-delete{ display: flex; justify-content: space-between; align-items: center; padding: 5px 10px; border-bottom: 1px solid #efefef; text{ font-size: 14px; }}.history-list{ padding: 5px; display: flex; flex-wrap: wrap; .uni-tag{ margin-right: 8px; margin-top: 8px; }}</style>
9、商品详情加入购物车逻辑
- 点击加入购物车按钮,购物车图标数量增加
- 通过uni-ui插件,导入购物车uni-goods-nav,再经过2个点击事件,click、buttonclick
- 使用vuex来管理购物车数据,在cart.js的mutations中写一个判断方法addToCart(state,goods),传入(state,goods)2个参数,用来判断点击的这件商品是否在购物车中,没有则把该商品push到购物车得到cart数组,存在则让count++
- 在商品详情页面的buttonclick事件中,先判断点击的是index==0的加入购物车按钮,再调用mutations的判断方法addToCart(goods),并且定义参数对象-goods,参数goods需要定义6个数据
- 在cart.js中定义计算属性getters,定义total函数使用forEach函数计算购物车的数量
- 在商品详情页面, 使用普通函数的形式定义的 watch 侦听器,在页面首次加载后不会被调用 , 使用对象的形式来定义 watch 侦听器 ,immediate:true
// cart.js// 初始化 cart.JSexport default { // 开启当前模块的命名空间 namespaced: true, // 模块的state数据 state: () => ({ // 购物车的数组,用来存储购物车中每个商品的信息对象 // 每个商品的信息对象,都包含6个属性: // { goods_id, goods_name, goods_price, goods_count, goods_small_logo, goods_state } cart: JSON.parse(uni.getStorageSync('cart')||'[]')// 持久化到本地数据Storage }), // 模块的mutations 方法 mutations: { addToCart(state, goods) { // 根据提交的商品id,查询购物车是否存在商品,如果不存在,则添加到购物车,如果存在,则数量加一 // find()方法存在返回该数组,不存在返回undefined const findResult = state.cart.find(x => x.goods_id === goods.goods_id) if(!findResult) { state.cart.push(goods) } else { findResult.goods_count++ } uni.setStorageSync('cart', JSON.stringify(state.cart)) // this.commit('m_cart/saveToStorage') }, // saveToStorage(state) { // uni.setStorageSync('cart', JSON.stringify(state.cart)) // } }, // 模块的getters属性 getters: { // 计算购物车的数量 total(state) { let num = 0 state.cart.forEach(goods => num += goods.goods_count) return num } }, // 模块的actions方法 actions: { }}// goods_detail.jsbuttonClick(v) { // console.log(v) if(v.index == 0) { const goods = { goods_id: this.goodsDetailList.goods_id, goods_name: this.goodsDetailList.goods_name, goods_price: this.goodsDetailList.goods_price, goods_count: 1, goods_small_logo: this.goodsDetailList.goods_small_logo, goods_state: true } this.addToCart(goods) }}watch: { total: { handler(newVal) { const findResult = this.options.find(x => x.text === '购物车') if (findResult) { // 3. 动态为购物车按钮的 info 属性赋值 findResult.info = newVal } }, immediate: true }},
10、购物车商品radio图标勾选状态
在cart.vue中,在使用子组件my-goodslist中绑定自定义点击事件,
@radio-change="radioChange"
在子组件my-goodslist.vue中,给radio绑定点击事件
@click=radioChangemd
在vuex的store/cart.js中定义操作购物车状态信息的方法
updataGoodsState
<view v-for="(goods,i) in cart" :key='i'> <my-goodlist :goodsList="goods" :showRadio="true" @radio-change="radioChange"> </my-goodlist></view>radioChange(e) { console.log(e)}// 子组件的参数会传递给父组件,e就变成对象有2个key-value<radio v-if="showRadio" :checked="goodsList.goods_state" color="#C00000" @click="radioChange"/>radioChangemd() { this.$emit('radio-change', { goods_id: this.goods_id, goods_state: !this.goods_state })}// goods只是形参updataGoodsState(state,goods) { const findResult = state.cart.find(x => x.goods_id === goods.goods_id) if(findResult) { findResult.goods_state = goods.goods_state } //将更新的信息cart缓存到本地 uni.setStorageSync('cart', JSON.stringify(state.cart))}
11、JSON.stringify() 、JSON.parse()
json.stringify()是将JavaScript对象转换为字符串,json.parse()是将JavaScript字符串转为对象
1.localStorage/sessionStorage默认只能存储字符串,而实际开发中,我们存储的数据多为对象类型,那么就可以:在存储时利用json.stringify()将对象转为字符串,在取出缓存利用json.parse()转回对象即可
//uniapp中uni.setStorageSync('keyword', JSON.stringify(this.history))this.history = JSON.parse(uni.getStirageSync('keyword'))//js中function setLocalStorage(key,val){ window.localStorage.setItem(key, JSON.stringify(val))}function getLocalStorage(key){ let val= JSON.parse(window.localStorage.getItem('keyword')) return val}setLocalStorage('keyword', [12,122])
2.实现对象深拷贝
//深拷贝function deepClone(data) { let _data = JSON.stringify(data) let dataClone = JSON.parse(_data) return dataClone}//测试let arr = [1,2,3]let _arr = deepClone(arr)arr[1] = 4console.log(arr, _arr)//[1,4,3] [1,2,3]
12、JSON.stringify()、toString()
虽然两者都可以将目标转为字符串,但是本质还是有区别的
let arr = [1,2,3]JSON.stringify(arr) // '[1,2,3]'arr.toString(arr) // 1,2,3
13、数组常用
13.1、forEach() 不改原数组
forEach():方法对数组的每个元素执行一次callback操作,callback可以接受3个参数;第一个value(必要)——数组中当前正在处理的元素,第二个index(可选)——数组当前正在处理元素的索引,第三个array(可选)——当前处理的数组。thisArg(可选),当执行回调函数callback时,用作this的值。
语法:array.forEach(callback(value,index,array), thisArg)
// 循环数组进行累加function sum(arr) { var s = 0; arr.forEach(function(value,index,array) { // arr.forEach(value => { s += value }) ES6语法 s += value }) return s}
13.2、filter() 不改原数组
filter():方法会创建一个新数组,它包含所有通过实现测试的所有元素,如果没有则返回空数组。callback用来测试数组的每个元素的函数,返回true就通过,保留新数组,false就不保留在新数组。callback接受三个参数:第一个element——数组中当前正在处理的元素,第二个index(可选)——当前正在处理元素的索引,第三个array(可选)——当前的数组
语法:arr.filter(callback(element, index, array), thisArg)
var fruits = ['apple', 'banana', 'grapes', 'mango', 'orange'];const result = fruits.filter(x => x==='apple') // ['apple']// 删除最后一个元素function fliter(array) { return array.filter((val,index,arr) => { return index !== arr.length-1 // 当前测试的索引不等于最后一个则为true,添加到新数组中 })}
13.3、find() 不改原数组
find():方法返回数组中满足测试函数的第一个元素的值、否则返回undefined,描述:对数组中的每一个元素进行测试执行一次callback函数,直至结果为true,返回这个元素的值。
语法: arr.find(callback(element,index,array), thisArg)
var inventory = [ {name: 'apples', quantity: 2}, {name: 'bananas', quantity: 0}, {name: 'cherries', quantity: 5}];function finds(inventory) { return inventory.find(vlaue => { return value.name === 'apples' })}// {name: 'apples', quantity: 2}
13.4、slice() 不改原数组
slice():方法会返回一个被提取的新数组。不会改变原有数组,接受2个参数;第一个start(可选),开始位置包含,第二个end(结束),结束位置不包含。截取到的元素会添加到新数组中,未截取到的会丢弃相当于删除。
语法:array.slice(begin,end)
// 删除数组中的最后元素const array = ['demo', 'love', 'drive', 'dance', 'foreach']const array2 = array.slice(0, -1) // 截取第0个到最后一个,最后一个不包括console.log(array2) // ['demo', 'love', 'drive', 'dance'] function delete(arr) { return arr.slice(0, -1)}
13.5、splice() 改原数组
splice():方法会删除或者修改数组,会改变原数组。第一个参数:start从0开始计数,如果是负数则表示倒数第几位,第二个参数:deleteCount,删除的个数,如果为0,则不删除,第三个参数:item,表示需要添加进的内容
语法:arr.splice(start,deleteCount,item)
const months = ['Jan', 'March', 'April', 'June'];months.splice(1, 0, "Feb");console.log(months);// ["Jan", "Feb", "March", "April", "June"]
13.6、unshift() 改原数组
unshift():会修改原数组,方法将一个或者多个元素添加到数组的开头,并且会返回数组的新长度。
语法:arr.unshift(element)
// 在数组前面添加元素,不改变原数组const months = ['Jan', 'March', 'April', 'June']const new_array = months.slice(0)new_array.unshift('item')// ['item', 'Jan', 'March', 'April', 'June']
13.7、push() 改原数组
push():会修改原数组,方法将一个或者多个元素添加到数组的结尾,并且返回数组的新长度。
语法:arr.push(element)
const months = ['Jan', 'March', 'April', 'June']months.push('item')// ['Jan', 'March', 'April', 'June', 'item']
13.8、concat() 不改原数组
concat():方法用于合并两个或者多个数组,不会更改原数组,会返回一个新数组
语法:var new_array = old_array.concat(value_array)
// 合并的必须是数组var array = ['a', 'b', 'c']var array2 = ['d'].concat(array)// array2:['d', 'a', 'b', 'c']var array3 = array.concat(['d'])// array3:['a', 'b', 'c', 'd']function concat(arrat,item) { return [item].concat(array)}
13.9、indexOf()
indexOf():方法返回在数组中可以找到的一个给定元素的第一个索引,如果不存在则返回-1。参数一:需要查找的元素,参数二:索引值
语法:arr.indexOf(item,index)
var arr = ['a', 'b', 'c']arr.indexOf('a') // 0
13.91、reducer()
reducer():方法对数组中的每个元素执行一个提供的reduce函数,将结果汇总为单个的返回值。
Accumulator:累加器 CurrentVlaue:当前值 CurrentIndex:当前索引 Array:数组
InitialValue:累加器的初始值,如果没有就用数组中的第一个元素
语法:arr.reduce(callback(accumulator,currentValue,index,array), initialValue)
回调函数第一次执行时,
accumulator
和currentValue
的取值有两种情况:如果调用reduce()
时提供了initialValue
,accumulator
取值为initialValue
,currentValue
取数组中的第一个值;如果没有提供initialValue
,那么accumulator
取数组中的第一个值,currentValue
取数组中的第二个值。
[0, 1, 2, 3, 4].reduce((accumulator, currentValue, currentIndex, array) => { return accumulator + currentValue}, 10)// 20
13.92、flat()
flat():方法会按照一个可指定的深度递归遍历数组,将所有元素与遍历到的子数组中的元素合并为一个新数组返回。
语法:var newArray = arr.flat([depth])
var arr1 = [1, 2, [3, 4]]arr.flat() // [1,2,3,4]var arr2 = [1, 2, [3, 4, [5, 6]]]arr2.flat() // [1, 2, 3, 4, [5, 6]]var arr3 = [1, 2, [3, 4, [5, 6]]]arr3.flat(2) // [1, 2, 3, 4, 5, 6]// 使用Infinity可展开任意深度的嵌套数组arr4.flat(Infinity) // [1, 2, 3, 4, 5, 6]
13.93、some()
some()
:方法测试数组中是不是至少有1个元素通过被提供函数的测试,返回值是Boolean类型值。 数组中有至少一个元素通过回调函数的测试就会返回**true
**;所有元素都没有通过回调函数的测试返回值才会为false。
callback
被调用时传入三个参数:元素的值,元素的索引,被遍历的数组。
语法:arr.some(callback(element,index,array),thisArg)
function isBiggerThan10(element, index, array) { return element > 10;}[2, 5, 8, 1, 4].some(isBiggerThan10); // false[12, 5, 8, 1, 4].some(isBiggerThan10); // true
13.94、from()
from():方法从一个类似数组或可迭代对象创建一个新的数组实例
arrayLike:想要转换成数组的伪数组对象或可迭代对象
mapFn:新数组中的每个元素会执行该回调函数
thisArg:执行回调函数mapFn时this对象
语法:Array.from(arrayLike, mapFn,thisArg)
const set = new Set(['foo', 'bar', 'baz', 'foo'])Array.from(set) // ["foo", "bar", "baz"]
13.95、sort()
sort():排序,对数组的元素进行排序,并返回数组。
语法:arr.sort(first, second)
var numbers = [4, 2, 1, 3, 5]numbers.sort((a, b) => a-b)log(numbers) // [1,2,3,4,5]numberss.sort((a, b) => b-a)log(numberss) // [5,4,3,2,1]
-
map()
map()方法会返回一个新的数组,数组中的元素为原始数组调用函数处理后的值,不会对空数组进行检测、不会改变原始数组
let array = [1,2,3,4,5]let newArray = array.map(item => { return item * item})console.log(newArray) // [1, 4, 9, 16, 25]
-
set()
set对象允许你存储任何类型的唯一值,值不会重复,返回一个set对象
let mySet = new Set();mySet.add(1); // Set [ 1 ]mySet.add(5); // Set [ 1, 5 ]mySet.add("some text"); // Set [ 1, 5, "some text" ]const numbers = [2,3,4,4,2,3,3,4,4,5,5,6,6,7,5,32,3,4,5]console.log([...new Set(numbers)])// [2, 3, 4, 5, 6, 7, 32]
-
find()
find()方法返回数组中满足提供测试函数的第一个元素的值,否则返回undefined
var arr = [ {name: 'apples', quantity: 2}, {name: 'bananas', quantity: 0}, {name: 'cherries', quantity: 5}]const findResult = arr.find(y => y.name === 'apples')// Object {name: 'apples', quantity: 2}
-
filter()
filter()方法创建一个新数组,返回满足提供函数测试的元素,如果全都不满足,则返回空数组
var fruits = ['apple', 'banana', 'grapes', 'mango', 'orange'];const result = fruits.filter(x => x.name==='apple') // {name: 'apple'}
-
forEach()
forEach()方法对数组的每个元素执行一次给点 函数
const array1 = ['a', 'b', 'c'];array1.forEach(element => console.log(element));// expected output: "a"// expected output: "b"// expected output: "c"
-
indexOf()
indexOf()方法可以找到一个给定的元素的第一个索引,如果存在则返回该索引,不存在则返回-1
const beasts = ['ant', 'bison', 'camel', 'duck', 'bison'];console.log(beasts.indexOf('bison'));// expected output: 1// start from index 2console.log(beasts.indexOf('bison', 2));// expected output: 4console.log(beasts.indexOf('giraffe'));// expected output: -1
-
join()
join()方法将一个数组的所有元素连接成字符串并返回这个字符串
const elements = ['Fire', 'Air', 'Water'];console.log(elements.join());// expected output: "Fire,Air,Water"console.log(elements.join(''));// expected output: "FireAirWater"
-
map与filter区别
var array = [{key: 1, value: 10}, {key: 2, value: 20}, {key:3, value: 30}]var mapRes = array.map((v,i) => {return v.value = v.value+'s'})console.log(mapRes) //['10s', '20s', '30s']//map可以返回一个新数组,内容格式可以是原数组的一部分var filterRes = array.filter((v,i) => {return v.value=v.value+'s'})console.log(filterRes)//[{key:1,value:'10ss'},{key:2,value:'20ss'},{key:3,value:'30ss'}]//filter返回的数组与原数组结构一致
14、vuex的使用
先在根目录下创建store–>store.js 初始化实例对象
// store/store.js--// 1.导入vue、vueximport Vue from 'vue'import Vuex from 'vuex'// 2.将vuex置为vue插件Vue.use(Vuex)// 3.创建实例对象storeconst store = new Vuex.Store({ state: { }, getters: { }, mutations: { }, actions: { }, // 挂载store模块 modules: { }})// 4.导出实例对象storeexport default store
在main.js中导入store实例对象,并挂载到vue实例上
// main.jsimport Vue from 'vue'import App from './App'#import store from './store.js'import { myRequest } from 'util/index.js'Vue.config.productionTip = falseApp.myType = 'app'const app = new Vue({ ...App, #store})app.$mount()
创建购物车store模块,cart.js,初始化vuex模块
// store/cart.jsexport defaule { // 开启模块命名空间 namespaced: true, state: () => ({ }), mutations: {}, getters: {}, actions: {}}
在store.js模块中,导入并挂载购物车的vuex模块
// store/store.jsimport Vue from 'vue'import Vuex from 'vuex'import moduleCart from './cart.js'Vue.use(Vuex)const store = new Vuex.Store({ // 挂载store模块 modules: { // 挂载购物车的 vuex 模块,模块内成员的访问路径被调整为 m_cart m_cart: moduleCart }})export default store
在.vue页面使用
// goods_detail.vue 不用使用this<view class='yf'> {{cart.length}} </view>// 无论映射 mutations 方法,还是 getters 属性,还是 state 中的数据,都需要指定模块的名称,才能进行映射import {mapState} from 'vuex'export default { computed: { // ...mapState('模块的名称', ['要映射的数据名称1', '要映射的数据名称2']) ...mapState('m_cart',['cart']) }}
15、JQuery
15.1、多选框选中方法
<input class="getFocus_userid" name="circle" type="checkbox" id="{$vo.focus_userid}" /><span>{$vo.realname}</span><!-- id的值为数字--><script> $("#btn").click(function() { var ids = '' $('.confirm').each(function() { if($(this).is(":checked")) { // if(this.checked == true) { if(ids == '') { ids = $(this).attr('value') } else { ids = ids + ',' + $(this).attr('value') } } }) console.log(ids) })</script>
// indexOf + push来添加是否选中checkboxarr = []gotofocus = function(item) { item2 = JSON.parse(item).id var useid = arr.indexOf(item2) // 判断input点击事件,点击触发,定义空数组,第一次点击,判断数组中是否存在id,不存在就添加,存在就删除 if(useid == -1) { arr.push(item2) } else { arr.splice(useid,1) }}
16、BFC
<!-- 一个BFC包含创建上下文元素的所有子元素,但是不包含子元素创建了新BFC的内部元素 一个元素不能存在2个BFC之中 BFC最重要的作用是:处于BFC内部的元素与外部的元素相互隔离 BFC:块级格式化上下文,是一个独立的渲染区域 元素产生BFC满足条件: 1:根元素 2:float值不为none 3:overflow值不为visible 4:display值为inline-block、table-cell、table-caption 5:position值为absolute或者fixed BFC特性: 1: 内部的盒会在垂直方向上排列 2: 处于同一个BFC下的元素,可能会发生margin重叠 3: 每个元素的margin box的左边与容器块border box的左边会接触 4:BFC内的子元素的一个隔离的独立容器,与外部隔绝 --> <!-- 触发BFC:根元素、float不为none、overflow不为visible、display为inline-block、position值为absolute或者fixed -->
17、加入购物车渲染徽标
1、购物车数据用vuex来管理数据,创建store.js启用modules:{},可以管理多个模块,里面只要填写name,在各分支模块书写被管理数据的状态:namespaced、state、getters、mutations、actions。2、触发加入购物车事件:在分支cart.js中mutations写添加方法,引入到商品详情页面使用该方法,需要传参。3、将添加购物车数据渲染:在cart.js中getters进行对cart数据的计算,将购物车商品数量累加起来,在详情页面时使用watch监听数据的变化,侦听器由于刚加载不会触发,所以需要对它进行改造,使用handler+immediate,将handler(e)接受到的变化e赋值给购物车options的info。4、将数据保存本地化:在分支cart.js中mutations定义方法。5、在tabBar上渲染数字徽标:在4个tabBar页面引入vuex的total计数,将这个总数进行页面的渲染,uni.setTabBarBadge({index:2, text: '字符串'}),需要在页面一进来就进行渲染,在onShow()调用存:uni.setStorageSync('cart',JSON.stringify(state.cart))取:JSON.parse(uni.getStorageSync('cart') || '[]') 有为空的可能在mutations中某一个方法调用其他的方法:this.commit('cart/saveStorage')
1、你的博客系统的优势在哪? 因为本系统针对的个人用户,用户使用非常便捷,便于其他人预览自己的博文内容,页面布局美观,操作简便,没有计算机基础的用户也能使用。2、你的验证码的设计思路是什么? 前端通过发起get请求获取接口得到的4个随机数,然后通过jquery插件的validate扁担验证给你,来验证输入的字符是否与获取到的验证码一致。3、你觉得还有什么地方能够改进? 可以优化内容的屏蔽信息功能,将部分敏感信息进行关键字屏蔽,这样就不会造成不良的影响。 添加一个关注博客用户功能,将喜欢的博主进行关注,下一次可以更改的找到
18、router
18.1、传参
-
通过URL传递参数
比如:
?name=index&key=value
获取方法:this.$route.query
-
通过路由规则的占位符
比如:
/name/value
获取方法:this$route.params
18.2、路由规则 human legacy
const routes = [ {path: '/', redirect: '/login'}, {path: '/login', name: 'login', component: Login}, {path: '/home', name: 'home', component: ()=>import('@/views/video')},// 懒加载 {path: '/my', name: 'my', children: [ {path: '', name: 'qa', component: ()=>import('@/views/qa')}, // 默认子路由只能有一个 {path:'/video', name: 'video', component:()=>import('@/views/video')} ]}]