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}}
posted @ 2021-05-16 18:49  猫神甜辣酱  阅读(118)  评论(0编辑  收藏  举报