美文网首页react & vue & angular
学习vue3(一)-基本使用+router

学习vue3(一)-基本使用+router

作者: 遇见wn | 来源:发表于2023-02-16 18:02 被阅读0次

    1.生命周期和组合式api(Composition API)

    在原有vue2的生命周期基础上在前缀加上on,例如:onMounted;使用组合式api的方法,生命周期函数需要引入使用

    <script setup>
    import { onBeforeMount } from "vue";
    onBeforeMount(() => {
    
    })
    </script>
    
    Tips:setup 是围绕 beforeCreate 和 created 生命周期钩子运行的,所以不需要显式地去定义。

    2.响应式赋值和写法

    使用ref,reactive来分别复制普通数据类型和复杂数据类型,使用组合式api写法,依然要进行引入。例如:

    import { ref, reactive } from "vue";
    
    let obj = reactive({ list: {} })
    let num = ref(0)
    let arr = ref([])
    

    注册一个点击事件

    //ref响应式赋值需要.value操作num的值,读取num的值不需要.value
    //ref通过Object.defineProperty()的get和set实现数据劫持
    function add() {
      num.value++
    }
    
    //reactive响应式赋值可以直接取值
    //reactive通过Proxy实现数据劫持
    function edit() {
      obj.list = {old:1}
    }
    

    3.多根节点

    可以有多个根节点。例如:

    <template>
       <div class="root"></div>
       <div class="root"></div>
       <div class="root"></div>
    </template>
    

    4.全局变量和全局方法

    相较于vue2,vue3的组合式写法,没有了this,无法直接指向vue实例,取得项目创建的全局方法和变量,但是vue3提供了一个proxy,记录了变量和方法,但是需要引入使用。例如:

    import { getCurrentInstance } from "vue";
    const { proxy } = getCurrentInstance()
    

    创建一个文件夹mock,新建一个test.js文件,文件中写入点需要全局使用的变量等。

    let mockJs = {
      skuData: [{
        list: [
          "5kg",
          "10kg",
          "15kg"
        ],
        name: "重量"
      }, {
        list: [
          "红色",
          "黄色"
        ],
        name: "颜色"
      }]
    }
    
    export default mockJs
    

    在main.js文件中导入,然后注册到全局中

    import { createApp} from 'vue'
    import App from './App.vue'
    import mockData from '../mock/test'
    const app = createApp(App)
    //关键代码,不在使用vue2的prototype了,而是使用app.config.globalProperties.mockData来操作原型
    app.config.globalProperties.mockData = mockData
    
    app.mount('#app')
    

    使用时引入实例,结构出proxy

    import { getCurrentInstance,reactive } from "vue";
    const { proxy } = getCurrentInstance()
    let data = reactive({skuData:{}})
    //不使用this. 而是使用proxy.
    data.skuData = proxy.mockData.skuData
    

    5.Teleport(独立组件) vue3内置组件的使用

    Teleport组件主要作用是当项目中需要使用到模态框,不是相较于父级定位的html结构时,可以使用

    //to可以把组件发送到body中,后续的定位等也是相较于body定位,disabled:显示和隐藏
    <teleport to='body' :disabled="disabled">
          <div class="dialog" v-if="disabled">
            dialog
          </div>
     </teleport>
    
    
    //这样就可以实现一个视图左右垂直居中的模态框了,仅仅只要操作组件中的元素就行,方便很多
    .dialog {
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        width: 200px;
        height: 200px;
        background-color: #fc6d18;
      }
    

    6.响应式原理

    vue2的响应式原理用Object.defineProperty的get和set进行数据劫持,从而实现响应式

    (1).vue2中只有get和set方法去进行属性的读取和修改操作,当我们进行新增,删除时,页面不会实时更新
    (2).直接通过下标改数组,页面也不会实时更新

    vue3中响应式原理使用Proxy进行代理,使用window内置对象Reflect反射

    (1).Proxy可以拦截对象中任意的属性变化,当然包括读写,添加,删除等
    (2).Reflect对源对象属性进行操作
    const data = new Proxy(data, {
    // 读取属性时调用
        get (target, propName) {
            return Reflect.get(target, propName)
        },
    //修改属性或添加属性时调用
        set (target, propName, value) {
            return Reflect.set(target, propName, value)
        },
    //删除属性时调用
        deleteProperty (target, propName) {
            return Reflect.deleteProperty(target, propName)
        }
    }) 
    
    

    7.组合式api写法补充 computed、watch、watchEffct

    computed

    <template>
         <div>
            {{ fullName }}
         </div>
    </template>
    
    import {  reactive, computed } from "vue";
    let message = reactive({
      name: '小明',
      old: '18'
    })
    
    let fullName = computed(() => {
      return message.name + ',今年' + message.old
    })
    

    watch

    <template>
        <p @click="add">{{ num }}</p>
    </template>
    import {  ref,watch } from "vue";
    let num = ref(0)
    function add() {
      num.value++
    }
    watch(num, (newValue, oldValue) => {
      console.log('num变动了' + 'num' + 'oldValue:' + oldValue + ' ' + 'newValue:' + newValue);
    })
    

    watchEffct 默认开启 immediate:true

    <template>
        <p @click="add">{{ num }}</p>
    </template>
    import {  ref,watchEffect } from "vue";
    let num = ref(0)
    function add() {
      num.value++
    }
    watchEffect(() => {
      console.log('watchEffect' + num.value);
    })
    

    8.hooks函数的使用

    新建一个hooks文件夹,创建一个hooks.js的文件

    import {
      reactive,
      onMounted,
      onBeforeUnmount
    } from 'vue'
    export default function () {
      //鼠标点击坐标
      let point = reactive({
        x: 0,
        y: 0
      })
    
      //实现鼠标点击获取坐标的方法
      function savePoint(event) {
        point.x = event.pageX
        point.y = event.pageY
        console.log(event.pageX, event.pageY)
      }
    
      //实现鼠标点击获取坐标的方法的生命周期钩子
      onMounted(() => {
        window.addEventListener('click', savePoint)
      })
    
      onBeforeUnmount(() => {
        window.removeEventListener('click', savePoint)
      })
    
      return point
    }
    

    使用hooks定义的方法

    //导入,调用
    import hooks from '../../hooks/hooks'
    hooks()
    

    9.router

    router.js

    import {
      createRouter,
      createWebHashHistory
    } from "vue-router"
    
    const routes = [{
        path: '/',
        component: () => import('../view/HelloWorld.vue')
      },
      {
        path: '/home',
        name: "home",
        component: () => import('../view/home.vue')
      },
    
    ]
    export const router = createRouter({
      history: createWebHashHistory(),
      routes: routes
    })
    
    export default router
    

    在vue3定义了一个vue−router,直接引入useRoute,useRouter,相当于vue2中提供的this.route,this.router

    import { useRouter, useRoute } from "vue-router";
    // ---router---
    const route = useRoute()
    const router = useRouter()
    
    //定义一个点击事件toHome
    function toHome() {
      router.push('/home')
    }
    

    10.父组件和后代组件之间的传参

    使用provide,inject

    //父组件
    <template>
      <div>
        home
      </div>
      <home-son />
    </template>
    
    <script setup>
    import homeSon from '../components/homeSon.vue'
    import { provide, reactive } from 'vue';
    
    const data = reactive({
      name: '小红',
      old: 18
    })
    provide('datas', data)
    
    </script>
    
    //后代组件
    <template>
      <div>
        我是后代组件
      </div>
      <div>
        父组件传递过来的值:{{ datas.name + '今年' + datas.old }}
      </div>
    </template>
    
    <script setup>
    import { inject } from 'vue'
    let datas = inject('datas')
    </script>
    

    11.父子组件之间的传值

    父传子 props

    <template>
      <p>我是父组件</p>
      <home-son :propsData="propsData" />
    </template>
    
    <script setup>
    import homeSon from '../components/homeSon.vue'
    import { reactive } from 'vue';
    
    const propsData = reactive({
      name: '小明',
      old: 20
    })
    
    </script>
    
    <template>
      <div>
        我是后代组件
      </div>
      <p>
        props父组件传递过来的值:{{ propsData.name + '今年' + propsData.old }}
      </p>
    </template>
    
    <script setup>
    // 父传子
    //defineProps不需要引入,直接使用
    let props = defineProps({
      propsData: {
        type: Object
      }
    })
    </script>
    

    子传父 emit

    <template>
      <div>
        home
      </div>
      <p>我是父组件:</p>
      <p>子传父过来的值:{{ emitData.emitData.name + '今年' + emitData.emitData.old }}</p>
      <home-son  @emitDatas="emitDatas" />
    </template>
    
    <script setup>
    import homeSon from '../components/homeSon.vue'
    import {  reactive } from 'vue';
    
    let emitData = reactive({ emitData: {} })
    function emitDatas(data) {
      emitData.emitData = data
    }
    
    </script>
    
    <template>
      <div>
        我是后代组件:
      </div>
    </template>
    
    <script setup>
    // 子传父
    //defineEmits不需要引入,直接使用
    let emits = reactive({
      name: '小清',
      old: 30
    })
    const emit = defineEmits('emitDatas')
    emit('emitDatas', emits)
    </script>
    

    相关文章

      网友评论

        本文标题:学习vue3(一)-基本使用+router

        本文链接:https://www.haomeiwen.com/subject/wvlpkdtx.html