Vue3零基础记录

182 阅读4分钟

Mac 版本开发

  • 1、node -v v12.22.1
  • 2、vue -V @vue/cli 5.0.0-alpha.5
  • 3、npm -v 6.14.12
  • 4、nvm ls 查看当前电脑 node 版本

image.png

再讲一下 MVVM model 数据 view 试图 viewModel 试图数据连接层

vue 开发环境

image.png

setup() 函数

setup函数是在created实例被完全初始化之前调用

image.png

vue3中的 引入 ref ,reactive ,readonly , toRefs,toRef,computed, watch

setup 函数中(props,context) context 里面包含 attrs, slots, emit

原理是通过proxy对数据进行封装,当数据变化时,触发模板等内容更新

  • ref 用于处理基本数据类型
  • reactive 处理复杂数据类型
  • readonly 无法被修改的内容
  • toRefs 用于处理内容结构赋值
  • toRef 用于处理空值时候的处理
  • computed 计算属性使用详情见下方
  • watch 的使用详情见下方

proxy 处理 Dell 变成proxy({value:'dell'})这样的一个响应式引用

toRefs原理 proxy({name:'xxx',age:'xxxx'}),{name:proxy({value:'xxx'},age:proxy(value:'xxxx'))}响应式数据

image.png

这里是toRef 的使用 image.png

创建一个 input 输入框 image.png

image.png

image.png

计算属性 computed 使用 初级版本

image.png

计算属性 computed 使用赋值 get set 形式 可以接收一个对象 set可以接收参数

image.png

  • watch 侦听器的使用
  • watch具有一定的惰性 首次刷新页面并不现实
  • watch的参数可以拿到原始和当前值
  • watchEffect 立即执行没有惰性
  • 不需要传递你要侦听的内容,自动会感知代码依赖,不需要传递很多参数。
  • 不能获取之前数据的值
  • 把watch 变成非惰性的

watch(()=>{ },immediate:true)

image.png watch侦听器使用reactive 复杂数据类型的时候 监听时候需要使用 箭头函数来处理。

image.png

watch侦听器,在处理多个复杂数据类型的时候,使用箭头函数来处理多个对象数据,当前数据显示的是当前的参数

image.png

teleport 展示
<template>
  <div class="area">
    <button @click="handleBtnClick">按钮</button>
    <teleport to="body">
      <div class="mask" v-show="show"></div>
    </teleport>
  </div>
</template>
<script>
//teleport 传送门
export default {
  data() {
    return {
      show: false
    }
  },
  methods: {
    handleBtnClick() {
      this.show = !this.show
    }
  }
}
</script>

<style scoped>
.area {
  position: absolute;
  width: 200px;
  height: 300px;
  background: green;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);

}

.mask {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  background: #fff;
  opacity: 0.5;
}
</style>

image.png

render函数

render function template ---> render ---> h ---> 虚拟DOM(js对象) ---> 真实DOM ---> 展示到页面上

plugin 插件

解决问题也是把通用性的功能封装起来

路由

hash 路由 带# 井号 路由是指根据url 的不同,展示不同的内容 router-link 是跳转路由的标签 router-view 是路由对应的展示

vuex

Vuex数据管理框架 Vuex 创建了一个全局唯一的仓库,用来存放全局的数据

最贱的一个 vue2的 获取方式
computed: {
  myName() {
    return this.$store.state.name
  }
}
store 的获取两种方式

<script>
import store from "@/store";

export default {
  name: 'Home',
  data() {
    return {
      store1: store
    }
  },
  computed: {
    myName() {
      return this.store1.state.name
    }
  }

}
</script>

Vuex想要更改内容,必须需要进行一个事件的派发 就action this.$tore.dispatch('xxxx')

<template>
  <div class="home">
    <img alt="Vue logo" src="../assets/logo.png">
    <h1 @click="handleClick">这里是点击更改</h1>
    {{ myName }}
  </div>
</template>

<script>
export default {
  name: 'Home',
  computed: {
    myName() {
      return this.$store.state.name
    }
  },
  methods: {
    handleClick() {
      //想改变数据,vuex 要求第一步,必须派发一个action
      this.$store.dispatch('change')
    }
  },

}
</script>

Vuex第二部, store 感知你触发了一个叫做change 的action 执行, change 方法 第三部分 提交一个commit 触发一个mutation

import {createStore} from 'vuex'

export default createStore({
    state: {
        name: 'dell'
    },
    mutations: {},
    actions: {
        change() {
            console.log('123')
        }
    },
    modules: {}
})

Vuex的整体使用

import {createStore} from 'vuex'

export default createStore({
    state: {
        name: 'dell'
    }, mutations: {
        //第四部,对应的mutation 被执行
        change() {
            //第五部,在mutation 里面修改数据
            this.state.name = '李四'
        },
        changeTwo() {
            this.state.name = '王五'
        }
    }, actions: {
        //第二部 store 感知到用户触发了一个change 的 action 行为,执行 change
        change() {
            //第三部,提交一个commit 触发一个 mutation
            this.commit('change')
        },
        changeTwo() {
            this.commit('changeTwo')
        }
    }, modules: {}
})
<template>
  <div class="home">
    <img alt="Vue logo" src="../assets/logo.png">
    <h1 @click="handleClick">这里是点击更改</h1>
    {{ myName }}
    <h1 @click="handleClickTwo">这里是点击更改第二次</h1>
  </div>
</template>

<script>
export default {
  name: 'Home',
  computed: {
    myName() {
      return this.$store.state.name
    }
  },
  methods: {
    handleClick() {
      //想改变数据,vuex 要求第一步,必须派发一个action
      this.$store.dispatch('change')
    },
    handleClickTwo(){
      this.$store.dispatch('changeTwo')
    }
  },

}
</script>
  • Vuex的整体记录
  • 1、dispatch 方法 派发一个action 名字叫做 action
  • 2、store 组件里面 的action 感知到 actions 里面的方法 使用 commit 进行更改
  • 3、commit 提交一个 change 的数据改变
  • 4、mutation 感知到提交的change 改变, 执行change方法改变数据 这里不涉及到 异步提交, 使用commit 使用在同步的时候可以 在mutation 中更改 在mutation 里面只允许写同步的代码,不允许写异步代码,这是规定
  • actions 里面进行异步操作中的方法获取参数 第一个是 (store,str)
  • mutations里面的参数是(state,str)

vuex参数记录

dispatch 和 actions 关联 commit 和 mutation 关联

在vue3中 使用vuex Composition API

import {toRefs} from 'vue' import {useStore}from 'vuex' const sotre = useStore()

<template>
  <div class="home">
    <img alt="Vue logo" src="../assets/logo.png">
<!--    <div>{{ myName }}</div>-->
    <div>{{ name }}</div>

  </div>
</template>

<script>
import {toRefs} from "vue";
import {useStore} from 'vuex'

export default {
  name: 'Home',
  setup() {
    const store = useStore()
    // const myName = store.state.name
    const {name} = toRefs(store.state)
    return {name}
  }

}
</script>

image.png

<template>
  <div class="about">
    <h1>This is an about page</h1>
    <h1>{{ name }}</h1>
    <button @click="handleClick">按钮</button>
  </div>
</template>
<script>
import {toRefs} from "vue";
import {useStore} from "vuex";

export default {
  setup() {
    const store = useStore()
    const {name} = toRefs(store.state)
    const handleClick = () => {
        //异步更改
      store.dispatch('change', '李四')  actions
      //同步更改
      store.commit('xxx') mutations
    }
    return {name, handleClick}
  }
}
</script>
import {createStore} from 'vuex'

export default createStore({
    state: {
        name: 'dell'
    }, mutations: {
        change(state, str) {
            state.name = str
        }
    }, actions: {
        change(store, str) {
            setTimeout(() => {
                store.commit('change', str)

            }, 2000)
        }
    }, modules: {}
})

Vue3生命周期函数

beforeMount ==> onBeforeMount mounted ===> onMounted beforeUpdate ===> onBeforeUpdate update ===> onUpdated beforeUnmount ===> onBeforeUnmount unmouted ==> onUnmouted beforeCreate ===> setup 函数之间 create ===> setup 函数之间

onRenderTracked 收集响应式依赖 onRenderTriggered 只有重新触发才会触发triggered 函数

子组件传值 子孙级

provide传递 inject接收

setup() {
  provide('name', ref('父组件给子组件传参'))
}
<template>
  <div>
    <HelloWorld/>
  </div>
</template>

<script>
import {provide} from "vue";
import HelloWorld from './components/HelloWorld.vue'

export default {
  name: 'App',
  components: {
    HelloWorld
  },
  setup() {
    provide('name','父组件给子组件传参')
  }

}
</script>

<style>
</style>
<template>
  <div>子组件传参</div>
  {{ name }}
</template>

<script>
import {inject} from "vue";

export default {
  name: 'HelloWorld',
  setup() {
    const name = inject('name',)
    return {name}
  }
}
</script>

<style scoped>

</style>

image.png

setup() {
  provide('name', ref('父组件给子组件传参'))
  provide(changeAppList, (value) => {
    xxx.value = value
  })

  return {}
}

image.png

ref 获取

获取真实的DOM节点 先声明一个 ref

<template>
  <div>
    <div ref="hello">测试</div>
  </div>
</template>

<script>

import {ref, onMounted} from "vue";

export default {
  setup() {
    const hello = ref(null)
    onMounted(() => {
      console.log('hello', hello)
      console.log('hello', hello.value)
    })
    return {hello}
  }
}
</script>

<style>
</style>

image.png