vue3.0

310 阅读5分钟

keep-alive

blog.csdn.net/weixin_4966…

接收父组件传下来的值,调用父组件方法steup(props, context)

setup: // 没有this
    seuup(props, context){ // setup
        // 创建数据
        let conut = ref(5const plus = () => {
            count.value++
        }
        return {
            // 返回数据
            count, // 导出变量
            plus,  // 导出函数
        }
    }
    
props参数:// 解构props会失去响应式
    // setup 函数中的第一个参数是 props。正如在一个标准组件中所期望的那样,setup 函数中的 props 是响应式的,当传入新的 prop 时,它将被更新。
    props: {
        title: String
    },
    setup(props) { // 参数props === props
        console.log(props.title)
    }
    {{props.title}} // 模板引用
    
context参数:
    // context 是一个普通的 JavaScript 对象,也就是说,它不是响应式的,这意味着你可以安全地对context 使用 ES6 解构
    emits:['plus'] // 方法需要注册
    setup(props, context)
        // Attribute (非响应式对象)
        console.log(context.attrs)

        // 插槽 (非响应式对象)
        console.log(context.slots)

        // 触发事件 (方法)
        console.log(context.emit)
        // 调用父组件方法
        context.emit('plus','需要传递的数据')
  }

定义/修改数据

ref // 只有一个属性,访问/设置他的值都必须访问他的value,return 会自动展开
    // 如果ref放入的是对象,会包装一层reactive
    let count = ref(5): 创建基本数据类型
    return { count }
    {{count}} // 模板引用
    
    // 如果ref放入的是对象,会包装一层reactive
    // 访问是这样的conut.value.a 
    let count = ref({
      a: 1,
      b: 2
    })
    return { count }
    {{count.a}} // 模板引用
    
unref: // 只要是使用unref,无论如何都只返回具体的值,而不是一个ref对象
    console.log(unref(count)) // 0
    console.log(unref(num)) // 0
    
reactive // 创建引用数据类型,是个深度的
    const state = reactive({
        count:5
    })
    {{state.count}} // 模板引用
    return {state}
    
torefs:// 单独提取对象的一个数据,共享数据源
    const state = reactive({
      foo: 1,
      bar: 2
    })
    const fooRef = toRef(state, 'foo')
    fooRef.value++
    console.log(state.foo) // 2
    state.foo++
    console.log(fooRef.value) // 3
    
torefs:将响应式对象转换为普通对象,每个数据都是ref
    const state = reactive({
      foo: 1,
      bar: 2
    })

    const stateAsRefs = toRefs(state) 
    return {
        ...stateAsRefs
    }
    
    {{foo}} // 模板引用
    {{bar}} // 模板引用
    
isRef: 判断是不是ref数据
    isRef(state)

customRef: 创建一个自定义的 ref,并对其依赖项跟踪和更新触发进行显式控制。它需要一个工厂函数,该函数接收 track 和 trigger 函数作为参数,并且应该返回一个带有 get 和 set 的对象。
    function useDebouncedRef(value, delay = 200) {
      let timeout
      return customRef((track, trigger) => {
        return {
          get() { // 获取值时调用
            track()
            return value
          },
          set(newValue) { // 更新值时调用
            clearTimeout(timeout)
            timeout = setTimeout(() => {
              value = newValue
              trigger()
            }, delay)
          }
        }
      })
    }

    export default {
      setup() {
        return {
          text: useDebouncedRef('hello')
        }
      }
    }
    
shallowRef/triggerRef: 创建响应式对象,发生修改后变成没有响应式,值改变后watchEffect监听不到不变化,需要使用triggerRef手动触发
    const info = shallowRef({
        name: '张三'
    })
    let name = ''
    watchEffect(() => {
        name = info.value.name
        console.log(name)
    })
    info.name.value = {
        李四
    }
    isReactive(info.value) 
    triggerRef(info)

获取vue实例和vuex

    const ctx = getCurrentInstance() // 获取vue实例
    store = ctx.$store // 获取vuex仓库
    const changCityInfo = () => { // 调用vuex里的方法
        store.commit('方法', 数据) 
    }
    return {
        changCityInfo, // 返回函数
    }

监听数据,变化

conputed: // 计算属性
    // get
    const count = ref(1)
    const plusOne = computed(() => count.value + 1)
    console.log(plusOne.value) // 2
    plusOne.value++ // error
    
    // 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
    
readonly: // 用readonly包裹,变成只读属性,不可修改
    const original = reactive({ count: 0 })
    const copy = readonly(original)
    original.count++ // 正常修改
    copy.count++ // 警告,不可修改!
    
watchEffect : // 初始化时执行,数据更新的也会触发这个回调函数(首次立即执行,响应式的去追踪他的依赖)
              // watchEffect返回一个stop函数,当调用这个函数watchEEfect会停止
              // 当组件被卸载的时候,watchEEtect也会停止
              // watchEffect回调函数接收一个参数onInvalidate,onInvalidate是一个可执行函数,onInvalidate也有一个参数,这个参数也是个回调函数
              // watchEffect在更新前调用,第二个参数flush,设置为post会变成更新后执行,默认是
              // pre: 默认值, post:更新后调用,sync:同步执行
    const stop = watchEffect((onInvalidate) => {
        onInvalidate(() => {
            // 优先执行,当依赖改变的时候才会触发
        })
    }, {
        flush: 'post' 
    }) 
    stop()
    
    // Watcher Debugging
    // 开发模式工作,生产无效
    watchEffect(() =>{},() => {
        onTrack(e) {
            // 初始化会执行
            // 依赖被改变都会触发
        },
        onTrigger(e) {
            debugger
            // 依赖被改变都会触发
        }
    })
    
watch: // 初始化时不触发,数据更新时触发
        // watch拥有第二个参数用法和watchEffect一样
        // 返回一个函数,调用会停止监听
    ref数据时
    watch(title, (newValue, oldValue) => {}) // newValue数据变化的值 oldValue旧的值
    
    reactive数据时
    watch(() => state.title // 返回需要监听的数据
    , (newValue, oldValue) => {}) // newValue数据变化的值 oldValue旧的值
    
    // 监听多个数据的变化
    watch(() => {
        return [name.value, age.value] // 返回一个数组
    }, ([newName, newAge], [oldName, oldAge]) => { // 参数变为数组
        console.log(newName, oldName, newAge, oldAge)
    })

生命周期

只能用在setup函数中,是同步的
1、去掉了vue2.0中的 beforeCreate 和 created 两个阶段,同样的新增了一个 setup
2、beforeMount 挂载之前    改名  onBeforeMount
3、mounted 挂载之后    改名  onMounted
4、beforeUpdate 数据更新之前    改名  onBeforeUpdate
5、updated 数据更新之后    改名  onUpdated
6、beforeDestroy 销毁前    改名  onBeforeUnmount
7、destoryed 销毁后    改名  onUnmounted
8、errorCaptured 捕获子孙组件发生错误  改名  onErrorCaptured(e => {})
9、renderTracked -> onRenderTracked // 用于调式,渲染是调用 onErrorCaptured(e => {debugging})
10、renderTriggered -> onRenderTriggered // 用于调式,重新渲染是调用 onErrorCaptured(e => {debugging})

依赖注入

Vue2.0
// 注入
provide: {
    name: '张三'
}
// 访问实例上的data数据时,provide需要写成一个function
provide() {
    return {
        name: this.name
    }
}
// 默认是没有响应式,需要使用computed
provide() {
    return {
        name: Vue.computed(() => this.name)
    }
}
// 接收
inject:['name']

Vue3.0

// 注入,拥有响应式
setup() {
    const name = ref('张三')
    const changName = () => {
        name = '李四'
    }
    // 可以单独注入每一个porvied,使用redonly包裹,防止子组件修改数据
    provide('name', redonly('张三'))
    provide('age')
    // 注入修改方法
    provide('changName')
}
// 接收
setup() {
    // 可以设置他的默认值
    const name = inject('name', '无名')
    const age = inject('age')
    // 接收修改方法
    const changName = inject('changName')
}

获取DOM元素(子组件,元素)

// 获取单个DOM元素
<template>
  <div ref="myRef">获取单个DOM元素</div>
</template>

<script>
import { ref, onMounted } from 'vue';

export default {
  setup() {
    const myRef = ref(null);

    onMounted(() => {
      console.dir(myRef.value);
    });
    return {
      myRef
    };
  }
};
</script>

// 获取多个DOM(一般用于获取数组)
<template>
  <div>获取多个DOM元素</div>
  <ul>
    <li v-for="(item, index) in arr" :key="index" :ref="setRef">
      {{ item }}
    </li>
  </ul>
</template>

<script>
import { ref, nextTick } from 'vue';

export default {
  setup() {
    const arr = ref([1, 2, 3]);

    // 存储dom数组
    const myRef = ref([]);

    const setRef = (el) => {
      myRef.value.push(el);
    };

    nextTick(() => {
      console.dir(myRef.value);
    });
    return {
      arr,
      setRef
    };
  }
};
</script>

插件