2022年8月前端学习笔记

目录

2022.08.16

1、Vuex内容

2、vue3组件间传值

3、typescript  接口interface

2022.08.17

1、vue3 + vite 多环境打包 及axios的封装

2、给背景加上毛玻璃效果

3、stylus预编译器     .styl文件

4、vuex 4 + ts

5、vant组件库中的slot插槽怎么使用?

6、vue单页项目判断有没有上一页

7、动态绑定class

2022.08.18

1、请求后端数据以及渲染前端页面过程

2、验证码倒计时60秒

2022.08.19

1、vue3 语法糖

2、ts中数组的类型注解

3、css3 盒模型

4、vue3 祖孙组件通信:provide、inject

5、Pinia 全新的Vue状态管理库

2022.08.23 

1、避免大量if...else...

2、将多个条件封装

3、css3实现图片边框动画

2022.08.25

1、遇到的坑:访问从后端获取的链接里面的数据,进行页面展示

2、解决vuex刷新页面后state数据丢失 

2022.08.26

1、遇到的坑:用reactive定义数组,对数组赋值或者用concat方法都无法获取到响应数组

2、vue  v-for之后怎么修改最后一项的样式

2022.08.30

1、async await  要求:执行完第一个事件后,才开始执行第二个事件 

2、api,发送path参数和body参数给后端 

 2022.08.31

1、使用Day.js插件格式化时间

2、vue3实现骨架屏

3、两个盒子,左边固定宽,右边自适应 

4、flex:1;表示什么? 


2022.08.16

1、Vuex内容

commit:同步操作,数据提交至mutations,可用于读取用户信息写到缓存里

vue2:
组件中使用this.$store.commit('loginStatus',1)
或者使用 mapMutations 辅助函数

vue3:
组件中使用store.commit('home/SET_DETAIL', item)
在vuex文件中,使用commit('SET_DETAIL', data)

 dispatch:含有异步操作,数据提交至actions,可用于向后台提交数据

vue2:this.$store.dispatch('isLogin',true)
vue3:store.dispatch('user/getInfo',参数 可要可不要)

读取 Vuex 的内容经常使用 computed 属性进行读取,因为 Vuex 的数据是响应式的

const bannerList = computed(() => store.state.home.bannerList)

 使用常量替代 Mutation 事件类型

mutations: {
    // 可以使用 ES2015 风格的计算属性命名功能
    // 来使用一个常量作为函数名
    ['SET_NOTICE'](state: IBaseState, payload: INotice) {
         // 修改 state
         state.notice = payload
    }
  }

2、vue3组件间传值

以setup语法糖为例,子组件必须使用 defineProps 和 defineEmits API 来声明 props 和 emits。

props

// ts写法
const props = defineProps<{
  foo: string
  bar?: number
}>()
const props = defineProps({
  foo: String,
  closeText: {
      type: String,
      default: '取消'
  }
})

 emits

<script setup lang="ts">
import { defineEmits } from 'vue'

const emit = defineEmits(["onClose"])
function clickButton(){
    emit("onClose",参数 可有可无)
}
</script>
// ts写法
const emit = defineEmits<{
  (e: 'change', id: number): void
  (e: 'update', value: string): void
}>()

const click = () => {
  emit('change', 1)  
  emit('update', 'abc')
}

3、typescript  接口interface

接口可以用来描述对象的形状

interface Speakable { 
    speak(): void; 
    readonly lng: string; //readonly表示只读属性 后续不可以更改 
    name?: string; //?表示可选属性 
} 

let speakman: Speakable = { 
    // speak() {}, //少属性会报错 
    name: "hello", 
    lng: "en", 
    age: 111, //多属性也会报错 
};

2022.08.17

1、vue3 + vite 多环境打包 及axios的封装

  • 开发环境、测试环境、生产环境 

开发环境:npm run dev

测试环境:npm run build:test

生产环境:npm run build

  • 配置环境变量

在项目根目录下新建三个配置文件

 .env.development文件:

注意,后面不用加分号,注释也不能加在url后面,常量名也必须已VITE_开头。

NODE_ENV = development

VITE_APP_ENV = develop

VITE_APP_BASE_API = 'https://'

.env.production文件:

NODE_ENV = production

VITE_APP_ENV = release

VITE_APP_BASE_API = 'https://'

 .env.test文件:

NODE_ENV = tset

VITE_APP_ENV = develop

VITE_APP_BASE_API = 'https://'
  •  使用全局变量

vue-cli引用:

process.env.变量名

vite引用:

import.meta.env.变量名
  • 配置打包命令:
"dev": "vite",
"build": "vue-tsc && vite build --mode production",
"build:test": "vue-tsc --noEmit --skipLibCheck && vite build --mode development",

  •  创建axios实例,在配置axios时使用全局baseURL
const baseURL = import.meta.env.VITE_BASE_URL as string;  //根据环境获得不同的代理模式
const service = axios.create({
    baseURL
})
  • 接口api 

  •  所有请求放在vuex的actions中

2、给背景加上毛玻璃效果

opacity: 0.75;
backdrop-filter: blur(10px) contrast(100%);
-webkit-backdrop-filter: blur(10px) contrast(100%);  //解决ios端兼容性问题

3、stylus预编译器     .styl文件

不再需要花括号{},冒号: ,分号; 

且可以嵌套

4、vuex 4 + ts

actions有两个参数。第一个参数{ commit, state }context参数,vuex 的 d.ts 提供有类型 ActionContext,用法如下:

import { ActionContext } from 'vuex'

const actions = {
  setBanner (context: ActionContext<IHomeState, IStore>, payload: number) {
    const res = await getBanner()
    context.commit('SET_BANNER', res.data?.list)
  }

  //或者
  async setBanner({ commit }: ActionContext<IHomeState, IStore>, payload: number) {
    const res = await getBanner()
    commit('SET_BANNER', res.data?.list)
  }
}

5、vant组件库中的slot插槽怎么使用?

 .vue文件中,使用<template #slot> </template>

6、vue单页项目判断有没有上一页

判断一个页面有没有上一页,没有就关闭页面,有的话就返回上一页

// 全局后置钩子函数
router.afterEach((to, from) => {
    // 当页面为打开的第一个页面时,url添加进sessionStorage
    if (!window.sessionStorage.firstUrl && to.path !== '/') {
        window.sessionStorage.firstUrl = window.location.href
    }
})

7、动态绑定class

<div :class="{ 'isActive' : active }"></div>

<div :class="{ 'isActive' : active === 1 }"></div>

<div :class="[ isActive ? 'active' : '' ]"></div>

2022.08.18

1、请求后端数据以及渲染前端页面过程

第一步,先在actions中发送请求,获取数据;

第二步,通过mutations函数将数据保存在vuex中;

第三步,获取vuex中的数据,渲染页面。

 

2、验证码倒计时60秒

<template>
    <div class="count-down" :style="{ color: color }" @click="handleClick">
        重新发送 {{ count ? `${count}s` : '' }}
    </div>
</template>

<script setup lang="ts">
import { onBeforeUnmount, ref } from 'vue'

const count = ref(60)
const timer = ref<number>(0)

const emit = defineEmits(['onClick'])

defineProps({
    color: {
        type: String,
        default: 'rgba(95, 143, 245, 1)'
    }
})

const init = () => {
    timer.value = setInterval(() => {
        if (count.value > 0) {
            count.value--
        } else {
            clearInterval(timer.value)
            timer.value = 0
        }
    }, 1000) as unknown as number
}
init()

const handleClick = () => {
    // 如果倒计时还在动,就不能点击重新倒计时
    if (count.value > 0) {
        return
    }
    count.value = 60
    init()
    emit('onClick')
}
// 在组件销毁之前,清除定时器
onBeforeUnmount(() => {
    clearInterval(timer.value)
})
</script>
<style lang="stylus" scoped>
.count-down {
    display: inline-block
    color: rgba(95, 143, 245, 1);
}
</style>

2022.08.19

1、vue3 语法糖<script setup>

优点:

  • 引入组件后可直接使用,无需注册
  • 无需再return变量的值和函数
  • defineProps,defineEmits,defineExpose,withDefaults这几个编译器宏,不需要手动引入

2、ts中数组的类型注解

const levelList = ref<{ name: string; icon: string }[]>([])

const levelList = ref<object[]>([])

3、css3 盒模型

盒模型有两种:标准盒模型、IE(替代)盒模型

盒模型由“ content + padding + border + margin ”构成,大小由“ content + padding + border ”决定。 但是盒子内容宽/高(width / height)的计算范围根据盒子模型的不同而有所不同。

  • 标准盒模型:只包含content
  • IE(替代)盒模型:包含content + padding + border

可以通过 box-sizing 来改变元素的盒模型。

  • 标准盒模型:box-sizing:content-box;
  • IE(替代)盒模型:box-sizing:border-box;

4、vue3 祖孙组件通信:provide、inject

祖组件:

setup(){
    let car = reactive({name:'奔驰',price:'40万'})
    provide('car',car) //可以用来传递响影数据
}

孙组件:

setup(){
    const car = inject('car')
    return {car}
}

5、Pinia 全新的Vue状态管理库

抛弃传统的 Mutations ,只有 state, getters 和 actions。

1.安装Pinia:npm install pinia

2. 在main.ts中挂载pinia

import { createPinia } from 'pinia'

const pinia = createPinia()
app.use(pinia)

3. 创建Store

// src/store/index.ts
import { defineStore } from 'pinia'

export const mainStore = defineStore('main',{
   state:() => {
       return{
           msg:'Hello Pinia!'
       }
   },
   getters:{},
   actions:{}
})

4. 使用Store

<template>
    <div>{{ store.msg }}</div>
</template>

<script setup lang='ts'>
    import { mainStore } from '../store/index'
    const store = mainStore()
</script>

 5. 解构Store:storeToRefs  (ES6传统方式解构store,数据不会响应式更新)

<template>
    <div>{{ count }}</div>
</template>

<script setup lang='ts'>
    import { storeToRefs } from 'pinia'

    const  { conut } = storeToRefs(store)
</script>

6. 修改多条数据  $patch

 $patch(对象)

 $patch(函数)

7. 通过actions修改

actions:{
    changeState(){
        this.count++
        this.msg = 'Pinia还挺简单!'
    }
}

在组件中调用actions中的方法

const clickMe = () => {
    store.changeState()
}

8. getters

Pinia 中的 getter 和 Vue 中的计算属性几乎一样

getter 中的值有缓存特性,如果值没有改变,多次使用也只会调用一次

2022.08.23 

1、避免大量if...else...

示例1:

if(x===a){
   res=A
}else if(x===b){
   res=B
}else if(x===c){
   res=C
}else if(x===d){
    //...
}

改写成map的写法

let mapRes={
    a:A,
    b:B,
    c:C,
    //...
}
res=mapRes[x]

 示例2:

const isMammal = (creature) => {
  if (creature === "human") {
    return true;
  } else if (creature === "dog") {
    return true;
  } else if (creature === "cat") {
    return true;
  }
  // ...
return false;
}

 改写成数组

const isMammal = (creature) => {
  const mammals = ["human", "dog", "cat", /* ... */];
  return mammals.includes(creature);
}

2、将多个条件封装

if (
  person.getAge() > 30 &&
  person.getName() === "simon" &&
  person.getOrigin() === "sweden"
) {
  // ...
}

 改写成

const isSimon =
  person.getAge() > 30 &&
  person.getName() === "simon" &&
  person.getOrigin() === "sweden";

if (isSimon) {
  // ...
}

转载于:写出干净的 JavaScript 5 个小技巧 - 掘金  

3、css3实现图片边框动画

转载于: CSS 边框动画_哔哩哔哩_bilibili

第二种样式css边框动画

div{
  display: flex;
  width: 258px
  height: 258px
  justify-content: center;
  align-items: center;
  padding: 11px;
  background: url(@/assets/1.png) no-repeat
  background-size: 100% 100%;
  box-sizing: border-box
  position relative
  overflow hidden
  border-radius: 20px
  &::before{
    content: ''
    background-image: conic-gradient(rgba(255,255,255,0.3) 10deg, transparent 45deg, rgba(255,255,255,0.3) 90deg, transparent 135deg, rgba(255,255,255,0.3) 180deg, transparent 225deg, rgba(255,255,255,0.3) 270deg, transparent 315deg, rgba(255,255,255,0.3))
    width 160%
    height: 160%
    position: absolute
    animation: rotate 6s linear infinite
  }
  @keyframes rotate {
    0%{
      transform: rotate(0deg)
    }
    100%{
      transform: rotate(360deg)
  }
}

2022.08.25

1、遇到的坑:访问从后端获取的链接里面的数据,进行页面展示

actions: 

 

mutations:

state:

 在ts中获取vuex中的数据:

在页面上展示: 

2、解决vuex刷新页面后state数据丢失 

安装vuex-persist插件 

npm install --save vuex-persist

在store文件下的index.ts中引入

import VuexPersistence from 'vuex-persist'

创建对象并配置

const vuexLocal = new VuexPersistence({
      storage: window.localStorage
})

在vuex文件中引入

state:{},
mutations:{},
actions:{},
plugins:[vuexLocal.plugin]

2022.08.26

1、遇到的坑:用reactive定义数组,对数组赋值或者用concat方法都无法获取到响应数组

// 方法一:对已经获取的数组进行遍历,逐项push进变量里
let list = reactive([])
for(let i = 0; i < arr.length; i++){
    list.push(arr[i])
}

// 方法二:采用扩展运算符
let list = reactive([])
list.push(...arr)

// 方法三:嵌套一层对象在外层
let obj = reactive({
  list: []
})
obj.list = arr

// 方法四:使用ref去定义
let list = ref([])
list.value = arr

2、vue  v-for之后怎么修改最后一项的样式

动态添加class名设置样式,:class="{'special-style':index===textList.length - 1}"

<div class="interest-item-context">
    <van-row
        class="interest-item-text"
        v-for="(item, index) in textList"
        :key="index"
    >
        <van-col
            span="6"
            :class="{ 'special-style': index === textList.length - 1 }"
            >{{ item.key }}:</van-col
        >
        <van-col span="18">{{ item.value }}</van-col>
    </van-row>
</div>
.special-style{
    color: red;
}

2022.08.30

1、async await  要求:执行完第一个事件后,才开始执行第二个事件 

2、api,发送path参数和body参数给后端 

// api文件
export const updateAddressApi = (data: { id: string; data: IAddressApi }) => {
    return service({
        url: `/address/${data.id}`,
        method: 'PUT',
        data: data.data
    })
}


// vuex:actions
async updateAddress(
    { commit }: ActionContext<ISettingsState, IStore>,
    payload: { id: string; data: IAddressApi }
) {
    try {
        const res = await updateAddressApi(payload)
        if (res.code === 200) {
            // commit('SET_ADDRESS_DETAIL', res.data || {})
            return Promise.resolve(res)
        }
        return Promise.reject(res)
    } catch (error) {
        return Promise.reject(error)
    }
}


// .vue文件
const data = { id: tempEditId.value, data: IAddress }
const res = await store.dispatch('settings/updateAddress', data)
if (res.code === 200) {
    showDialog.value = false
    getData()
} else {
    Toast.fail(res.message)
}

api文件: 

 actions中:

mutations中:

state中:

  

页面上:

 2022.08.31

1、使用Day.js插件格式化时间

 Day.js官网:安装 | Day.js中文网 (fenxianglu.cn)

 下载dayjs

npm install dayjs --save

 导入到组件中

import dayjs from 'dayjs'

 格式化时间 

dayjs(time).format('YYYY-MM-DD HH:mm:ss')

2、vue3实现骨架屏

  安装 

npm install -S @x-ui-vue3/skeleton

  main.js文件 

import { createApp } from 'vue'
import Skeleton from '@x-ui-vue3/skeleton'
import App from './App.vue'

createApp(App).use(Skeleton).mount('#app')

  页面中使用 

<template>
  <label for="loading">点击切换</label>
  <input v-model="loading" id="loading" type="checkbox" />

  <br /><br />

  <div v-skeleton="loading">
    <span v-skeleton-item>超文本标记语言是一种用于创建网页的标准标记语言。</span>
    <br /><br />
    <span v-skeleton-item>www.runoob.com</span>
    <br /><br />
    <span v-skeleton-item>Good good study, day day up!</span>
  </div>
</template>

<script setup>
import { ref } from 'vue'
const loading = ref(false)
</script>

  转载于:@x-ui-vue3/skeleton - npm (npmjs.com)

3、两个盒子,左边固定宽,右边自适应 

<div class="content">
    <div class="left"></div>
    <div class="right"></div>
</div>

方法一:float和BFC实现 (BFC: 使得内部元素不受外界因素影响)

.content {
    height: 800px;
    padding: 20px;
}
.left {
    width: 200px;
    height: 100%;
    float: left;
}
.right {
    height: 100%;
    overflow: hidden;
}

方法二:absolute定位和margin值实现

    .content {
        height: 800px;
        padding: 20px;
    }
    .left {
        width: 200px;
        height: 100%;
        position: absolute;
    }
    .right {
        height: 100%;
        margin-left: 200px;
    }

 方法三:flex布局

    .content {
        height: 800px;
        padding: 20px;
        display: flex;
    }
    .left {
        width: 200px;
        height: 100%;
    }
    .right {
        height: 100%;
        flex: 1;
    }

方法四:calc(100%-固定内容的宽度)  用calc函数动态计算数值

    .content {
        height: 800px;
        padding: 20px;
    }
    .left {
        width: 200px;
        height: 100%;
        float: left;
    }
    .right {
        height: 100%;
        float: left;
        width: calc(100% - 200px);
    }

方法五:使用table和table-cell实现

     .content {
         width: 100%;
         height: 800px;
         display: table;
     }
     .left {
         width: 200px;
         height: 100%;
         display: table-cell;
     }
     .right {
         height: 100%;
         display: table-cell;
     }

转载于:两个盒子,左边固定宽,右边自适应,你能想到几种方法? - 掘金 (juejin.cn)

4、flex:1;表示什么? 

flex属性是 flex-grow,flex-shrink,flex-basis 的简写,默认值是flex:0 1 auto;

flex:1; 等同于 flex:1 1 0%;     适合等分布局

flex-grow属性都为1,则它们将扩大,等分剩余空间。

flex-shrink属性都为1,当空间不足时,都将等比例缩小。

flex-basis属性为项目本身的大小,默认值是auto。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值