vue3学习

Posted 房东家的猫

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue3学习相关的知识,希望对你有一定的参考价值。

安装

npm install -g @vue/cli@next

子传父

父
    <One :titles="msg1" @oneTwo="clickMethod"/>
子
export default {
  name: "One",
  emits: [\'oneTwo\'],
  methods: {
    updatedOne() {
      this.$emit(\'oneTwo\', 12)
    }
  }
}

update方面的修改

父     <One v-model="msg1" ></One>
子
 updatedOne() {
      // 内部把v-model 封装到 modelValue
      this.$emit(\'update:modelValue\',10)
    }

动态组件

<component :is="currentTabComponent"></component>
<component :is="condition ? \'FooComponent\' : \'BarComponent\'"></component>

watch

 obj: {
        name: 12
      }
  
watch:{
     // 正常的基本类型的监听 
    nums(val) {
      console.log(val);
    },
    obj:{
      handler(newName, oldName) {
        console.log(newName, oldName);
      },
      immediate: true,//立即执行触发回调
      deep: true   // 深度监听
    }
  },

可以改成字符串的形式,可以理解为铺平

 obj: {
        name: 12
      }

  \'obj.name\': {
      handler(newName, oldName) {
        console.log(newName, oldName);
      },
  }        

我们知道deep:true 很消耗性能

  created() {
    this.fn = this.$watch(\'obj\', (newVal) => {
      console.log(newVal);
    }, {immediate: true, deep: true})
  },
  unmounted() {
    this.fn();
  } 

vue3.0

      // 监听title发生改变
        watch(
            () => props.title,
            (newTitle, oldTitle) => {
                console.log(\'newTitle, oldTitle :>> \', newTitle, oldTitle);
                context.emit(\'change-title\', title);
            }
        );

监听多个值得变化

     const r = ref(1)
    const s = ref(1)
    const t = ref(1)
    
   watch([r, s, t], val => {
      console.log(\'watch\', val)
    })

$forceUpdate

强制刷新,只会影响实例本身和插入了插槽内容的子组件

@

@click.stop等修饰符

.stop 阻止事件冒泡event.stopPropagation()

.prevent 阻止事件的默认行为``event.preventDefault()`

.self 自身元素触发

Keep-alive

缓存组件

  • include- string | RegExp | Array。仅具有匹配名称的组件将被缓存。
  • exclude- string | RegExp | Array。名称匹配的任何组件都不会被缓存。
  • max- number | string。要缓存的组件实例的最大数量。
<transition>
  <keep-alive>
    <component :is="view"></component>
  </keep-alive>
</transition>

<keep-alive>
  <comp-a v-if="a > 1"></comp-a>
  <comp-b v-else></comp-b>
</keep-alive>

条件匹配
<keep-alive :include="[\'a\', \'b\']">
  <component :is="view"></component>
</keep-alive>
最大缓存组件
<keep-alive :max="10">
  <component :is="view"></component>
</keep-alive>

setup

  • 参数, props , context
  setup(props, context) {
    // Attributes (Non-reactive object)
    console.log(context.attrs)

    // Slots (Non-reactive object)
    console.log(context.slots)

    // Emit Events (Method)
    console.log(context.emit)
  }

  setup(props, { attrs, slots, emit }) {
    ...
  }

ref

ref的本质是拷贝,与原始数据没有引用关系

reactive 复杂类型的响应

toRef

toRef将单个reactive对象属性转换为保持与父对象的连接的ref:

const state = reactive({
  foo: 1,
  bar: 2
})

const fooRef = toRef(state, \'foo\')
	// 这样进行修改值,因为转化为ref类型啦
     foos.value=100

toRefs

toRefs所有属性转换为具有refs属性的普通对象:

<h1>{{foo}}</h1>

setup() {
    const state = reactive({
      foo: 1,
      bar: 2
    })
    const clickMethod = () => {
      state.foo=100
    }
    return {
      clickMethod,
      ...toRefs(state)
    }
  },

computed

const twiceTheCounter = computed(() => counter.value * 2)

get/set

const count = ref(1)
const plusOne = computed({
  get: () => count.value + 1,
  set: val => {
    count.value = val - 1
  }
})

plusOne.value = 1
console.log(count.value) // 0

slot

命名插槽

父
<One>
      <h1>223223</h1>
      <template v-slot:header>
        <h1>Here might be a page title</h1>
      </template>
</One>

子
	// 默认插槽
  <slot></slot>
	// 命名插槽
  <slot name="header"></slot>

生命周期

选件API 钩在里面 setup
beforeCreate 不需要*
created 不需要*
beforeMount onBeforeMount
mounted onMounted
beforeUpdate onBeforeUpdate
updated onUpdated
beforeUnmount onBeforeUnmount
unmounted onUnmounted
errorCaptured onErrorCaptured
renderTracked onRenderTracked
renderTriggered onRenderTriggered
activated onActivated
deactivated onDeactivated

提供/注入

父
  provide: {
    location: \'North Pole\',
    geolocation: {
      longitude: 90,
      latitude: 135
    }
  }
子
  inject: [\'location\', \'geolocation\']

vue3.0

父
 setup() {
    provide(\'location\', \'North Pole\')
    provide(\'geolocation\', {
      longitude: 90,
      latitude: 135
    })
  }

  setup() {
    const location = ref(\'North Pole\')
    const geolocation = reactive({
      longitude: 90,
      latitude: 135
    })

    const updateLocation = () => {
      location.value = \'South Pole\'
    }

    provide(\'location\', location)
    provide(\'geolocation\', geolocation)
    provide(\'updateLocation\', updateLocation)
  }

子/孙
  setup() {
    const userLocation = inject(\'location\', \'The Universe\')
    const userGeolocation = inject(\'geolocation\')

    return {
      userLocation,
      userGeolocation
    }
  }

dom查找

  <div ref="root">This is a root element</div>

    setup() {
      const root = ref(null)
      onMounted(() => {
        console.log(root.value) // <div>This is a root element</div>
      })
      return {
        root
      }
    }

toRaw

拿到原始的值, 类似于表单表单的提交给后面的值

const foo = {name:\'xx\'}
const reactiveFoo = reactive(foo)

console.log(toRaw(reactiveFoo) === foo) // true

watchEffect

  • 没有过多的参数 只有一个回调函数
  • 立即执行,没有惰性,页面的首次加载就会执行。
  • 自动检测内部代码,代码中有依赖 便会执行
  • watchEffect 当我想观察多个反应特性而我不在乎旧值时
watchEffect能够监视在回调函数中引用的任何反应变量。

	 watchEffect(() => {
      console.log(root.value);
    })
    setTimeout(() => {
      root.value = 10
    },1000)
// 1  默认执行一次
// 10

watch单个电抗值更改时,如果您想触发副作用,请使用此命令。

watch(user, () => doSomething({ user: user.value, profile: profile.value }))

使用watchEffect时,你需要看多个反应值,并引发副作用,只要任何人被更新。

watchEffect(() => doSomething({ user: user.value, profile: profile.value }))

清除监听

我们知道监听会有副作用, 我们可以发现这个跟react的useEffect 很像

const stop = watchEffect(() => {
  /* ... */
})

// 离开后,我们可以执行清除监听
stop() 

更新策略

flush: \'post\' 设置后是DOM更新后运行效果

  <div ref="root">This is a root element</div>
  setup() {
      const root = ref(null)
      watchEffect(() => {
        console.log(root.value) // => <div></div>
      }, 
      {
        flush: \'post\'
      })
      return {
        root
      }
    }

teleport

<teleport>并告诉Vue将这个html传送body标签

 <teleport to="body">
      <div v-if="modalOpen" class="modal">
      	xxxxxxx
      </div>
    </teleport>

我们可以把两个组件添加到同一个目标

<teleport to="#modals">
  <div>A</div>
</teleport>
<teleport to="#modals">
  <div>B</div>
</teleport>

<div id="modals">
  <div>A</div>
  <div>B</div>
</div>

render

resolveComponent用于全局注册的组件。

const { h, resolveComponent } = Vue

// ...

render() {
  const ButtonCounter = resolveComponent(\'ButtonCounter\')
  return h(ButtonCounter)
}

ts 的写法

<script lang="ts">
import { defineComponent } from \'vue\'

export default defineComponent({
  // type inference enabled
})
</script>

全局刷新

    const {ctx: _this}: any = getCurrentInstance()
      _this.$forceUpdate();

防抖节流

全局添加 
Vue.createApp({
    methods: {
      // Debouncing with Lodash
      click: _.debounce(function() {
        // ... respond to click ...
      }, 500)
    }
  }).mount(\'#app\')
另一种形式  
生命周期挂钩中添加去抖动功能
app.component(\'save-button\', {
  created() {
    // Debouncing with Lodash
    this.debouncedClick = _.debounce(this.click, 500)
  },
  unmounted() {
    // Cancel the timer when the component is removed
    this.debouncedClick.cancel()
  },
  methods: {
    click() {
      // ... respond to click ...
    }
  },
  template: `
    <button @click="debouncedClick">
      Save
    </button>
  `
})

这种方式才是computed的精华所在

const vm = Vue.createApp({
  data() {
    return {
      firstName: \'Foo\',
      lastName: \'Bar\'
    }
  },
  computed: {
    fullName() {
      return this.firstName + \' \' + this.lastName
    }
  }
}).mount(\'#demo\')

vue3

https://cli.vuejs.org/core-plugins/typescript.html#injected-commands

vue add typescript

别用vue-component-class 感觉不是很成熟

reactive

 const book = reactive({ title: \'Vue 3 Guide\' })
 book.title 使用就可以啦, 不能用 .value

最后上一个,刚开始学习的小案例

import {ref, watch, onMounted, computed,toRefs} from \'vue\'


export default {
  name: "One",
  props:[\'sex\'],
  setup(props) {
    let {sex} = toRefs(props);
    console.log(sex.value);
    let sex1=toRefs(props,\'sex\')
    console.log(sex1.sex.value);
    let a = ref(0)
    // 监听
    watch(a, (newVal, val) => {
      console.log(newVal, val);
    }, {deep: true})
    //如果还需要监控一个就继续写一个
    watch(b, (newValue, oldValue) => {
      console.log(newValue, oldValue);
    })

    const add = () => {
      // 类似请求修改值
      a.value = [1, 2, 3, 4]
    };
    // 计算属性
    const b = computed(() => a.value[0] + 100)
    // 生命周期
    onMounted(add)
    return {a, b}
  }
}

html

<input type="text" v-model="a[0]">
    {{ a }} <br>
    {{ b }}
    {{sex}}

以上是关于vue3学习的主要内容,如果未能解决你的问题,请参考以下文章

vue3.2 基础及常用方法

使用带有渲染功能的 Vue.js 3 片段

Vue3快速入门学习笔记一

重启Vue3学习

Vue3.0 解读

Vue3学习笔记(6.0)