数组与设计思路

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、搜索页面思路

  1. 使用uni-ui布局搜索框,输入内容时input方法可以获取输入的内容-keyword,对用户输入时做节流功能,防止用户快速一直输入一直输出结果
  2. 发起查询请求,请求参数是输入内容 keyword,得到结果searchList之后书写ui框架进行渲染,渲染之后进行美化,点击对应的列表能进行跳转到商品列表,传入参数item,uni.navigator({url:’’})进行跳转到商品列表
  3. 若没有搜索词,那么需要让searchlist重置为空,在请求数据之前,return出去
  4. 将搜索框输入的关键字保存到searchHistoryList中,通过set方法让获取的值不会重复,set得到的是对象,需要通过Array.from转为数组,通过computed计算属性使searchHistoryList能反转,让最近的搜索排在前面,最后将得到的searchHistoryList,通过JSON.stringify保存到本地Storage中uni.setStorageSync('keyword', JSON.stringify(this.historylist))
  5. 在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、商品详情加入购物车逻辑

  1. 点击加入购物车按钮,购物车图标数量增加
  1. 通过uni-ui插件,导入购物车uni-goods-nav,再经过2个点击事件,click、buttonclick
  2. 使用vuex来管理购物车数据,在cart.js的mutations中写一个判断方法addToCart(state,goods),传入(state,goods)2个参数,用来判断点击的这件商品是否在购物车中,没有则把该商品push到购物车得到cart数组,存在则让count++
  3. 在商品详情页面的buttonclick事件中,先判断点击的是index==0的加入购物车按钮,再调用mutations的判断方法addToCart(goods),并且定义参数对象-goods,参数goods需要定义6个数据
  4. 在cart.js中定义计算属性getters,定义total函数使用forEach函数计算购物车的数量
  5. 在商品详情页面, 使用普通函数的形式定义的 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图标勾选状态

  1. 在cart.vue中,在使用子组件my-goodslist中绑定自定义点击事件,@radio-change="radioChange"

  2. 在子组件my-goodslist.vue中,给radio绑定点击事件 @click=radioChangemd

  3. 在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)

回调函数第一次执行时,accumulatorcurrentValue的取值有两种情况:如果调用reduce()时提供了initialValueaccumulator取值为initialValuecurrentValue取数组中的第一个值;如果没有提供 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]
  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]
    
  2. 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]
    
  3. 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}
    
  4. filter()

    filter()方法创建一个新数组,返回满足提供函数测试的元素,如果全都不满足,则返回空数组

    var fruits = ['apple', 'banana', 'grapes', 'mango', 'orange'];const result = fruits.filter(x => x.name==='apple') // {name: 'apple'}
    
  5. forEach()

    forEach()方法对数组的每个元素执行一次给点 函数

    const array1 = ['a', 'b', 'c'];array1.forEach(element => console.log(element));// expected output: "a"// expected output: "b"// expected output: "c"
    
  6. 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
    
  7. join()

    join()方法将一个数组的所有元素连接成字符串并返回这个字符串

    const elements = ['Fire', 'Air', 'Water'];console.log(elements.join());// expected output: "Fire,Air,Water"console.log(elements.join(''));// expected output: "FireAirWater"
    
  8. 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的使用

  1. 先在根目录下创建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
    
  2. 在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()
    
  3. 创建购物车store模块,cart.js,初始化vuex模块

    //	store/cart.jsexport defaule {    // 开启模块命名空间    namespaced: true,    state: () => ({    }),    mutations: {},    getters: {},    actions: {}}
    
  4. 在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
    
  5. 在.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')}    ]}]

热门文章

暂无图片
编程学习 ·

exe4j详细使用教程(附下载安装链接)

一、exe4j介绍 ​ exe4j是一个帮助你集成Java应用程序到Windows操作环境的java可执行文件生成工具&#xff0c;无论这些应用是用于服务器&#xff0c;还是图形用户界面&#xff08;GUI&#xff09;或命令行的应用程序。如果你想在任务管理器中及Windows XP分组的用户友好任务栏…
暂无图片
编程学习 ·

AUTOSAR从入门到精通100讲(126)-浅谈车载充电系统通信方案

01 引言 本文深入研究车载充电系统策略,设计出一套基于电动汽车电池管理系统与车载充电机的CAN通信协议,可供电动汽车设计人员参考借鉴。 02 电动汽车充电系统通讯网络 电动汽车整车控制系统中采用的是CAN总线通信方式,由一个整车内部高速CAN网络、内部低速CAN网络和一个充电…
暂无图片
编程学习 ·

CMake(九):生成器表达式

当运行CMake时&#xff0c;开发人员倾向于认为它是一个简单的步骤&#xff0c;需要读取项目的CMakeLists.txt文件&#xff0c;并生成相关的特定于生成器的项目文件集(例如Visual Studio解决方案和项目文件&#xff0c;Xcode项目&#xff0c;Unix Makefiles或Ninja输入文件)。然…
暂无图片
编程学习 ·

47.第十章 网络协议和管理配置 -- 网络配置(八)

4.3.3 route 命令 路由表管理命令 路由表主要构成: Destination: 目标网络ID,表示可以到达的目标网络ID,0.0.0.0/0 表示所有未知网络,又称为默认路由,优先级最低Genmask:目标网络对应的netmaskIface: 到达对应网络,应该从当前主机哪个网卡发送出来Gateway: 到达非直连的网络,…
暂无图片
编程学习 ·

元宇宙技术基础

请看图&#xff1a; 1、通过AR、VR等交互技术提升游戏的沉浸感 回顾游戏的发展历程&#xff0c;沉浸感的提升一直是技术突破的主要方向。从《愤怒的小鸟》到CSGO,游戏建模方式从2D到3D的提升使游戏中的物体呈现立体感。玩家在游戏中可以只有切换视角&#xff0c;进而提升沉浸…
暂无图片
编程学习 ·

flink的伪分布式搭建

一 flink的伪分布式搭建 1.1 执行架构图 1.Flink程序需要提交给 Job Client2.Job Client将作业提交给 Job Manager3.Job Manager负责协调资源分配和作业执行。 资源分配完成后&#xff0c;任务将提交给相应的 Task Manage。4.Task Manager启动一个线程以开始执行。Task Manage…
暂无图片
编程学习 ·

十进制正整数与二进制字符串的转换(C++)

Function one&#xff1a; //十进制数字转成二进制字符串 string Binary(int x) {string s "";while(x){if(x % 2 0) s 0 s;else s 1 s;x / 2;}return s; } Function two&#xff1a; //二进制字符串变为十进制数字 int Decimal(string s) {int num 0, …
暂无图片
编程学习 ·

[含lw+源码等]微信小程序校园辩论管理平台+后台管理系统[包运行成功]Java毕业设计计算机毕设

项目功能简介: 《微信小程序校园辩论管理平台后台管理系统》该项目含有源码、论文等资料、配套开发软件、软件安装教程、项目发布教程等 本系统包含微信小程序做的辩论管理前台和Java做的后台管理系统&#xff1a; 微信小程序——辩论管理前台涉及技术&#xff1a;WXML 和 WXS…
暂无图片
编程学习 ·

树莓派驱动DHT11温湿度传感器

1&#xff0c;直接使用python库 代码如下 import RPi.GPIO as GPIO import dht11 import time import datetimeGPIO.setwarnings(True) GPIO.setmode(GPIO.BCM)instance dht11.DHT11(pin14)try:while True:result instance.read()if result.is_valid():print(ok)print(&quo…
暂无图片
编程学习 ·

ELK简介

ELK简介 ELK是三个开源软件的缩写&#xff0c;Elasticsearch、Logstash、Kibana。它们都是开源软件。不过现在还新增了一个 Beats&#xff0c;它是一个轻量级的日志收集处理工具(Agent)&#xff0c;Beats 占用资源少&#xff0c;适合于在各个服务器上搜集日志后传输给 Logstas…
暂无图片
编程学习 ·

Linux 基础

通常大数据框架都部署在 Linux 服务器上&#xff0c;所以需要具备一定的 Linux 知识。Linux 书籍当中比较著名的是 《鸟哥私房菜》系列&#xff0c;这个系列很全面也很经典。但如果你希望能够快速地入门&#xff0c;这里推荐《Linux 就该这么学》&#xff0c;其网站上有免费的电…
暂无图片
编程学习 ·

Windows2022 无线网卡装不上驱动

想来 Windows2022 和 windows10/11 的驱动应该差不多通用的&#xff0c;但是死活装不上呢&#xff1f; 搜一下&#xff0c;有人提到 “默认安装时‘无线LAN服务’是关闭的&#xff0c;如果需要开启&#xff0c;只需要在“添加角色和功能”中&#xff0c;选择开启“无线LAN服务…
暂无图片
编程学习 ·

【嵌入式面试宝典】版本控制工具Git常用命令总结

目录 创建仓库 查看信息 版本回退 版本检出 远程库 Git 创建仓库 git initgit add <file> 可反复多次使用&#xff0c;添加多个文件git commit -m <message> 查看信息 git status 仓库当前的状态git diff 差异对比git log 历史记录&#xff0c;提交日志--pret…
暂无图片
编程学习 ·

用Postman生成测试报告

newman newman是一款基于nodejs开发的可以运行postman脚本的工具&#xff0c;使用Newman&#xff0c;可以直接从命令运行和测试postman集合。 安装nodejs 下载地址&#xff1a;https://nodejs.org/en/download/ 选择自己系统相对应的版本内容进行下载&#xff0c;然后傻瓜式安…
暂无图片
编程学习 ·

Java面向对象之多态、向上转型和向下转型

文章目录前言一、多态二、引用类型之间的转换Ⅰ.向上转型Ⅱ.向下转型总结前言 今天继续Java面向对象的学习&#xff0c;学习面向对象的第三大特征&#xff1a;多态&#xff0c;了解多态的意义&#xff0c;以及两种引用类型之间的转换&#xff1a;向上转型、向下转型。  希望能…