...
 
Commits (3)
    https://gitcode.net/qq_39019768/test_git/-/commit/f8a139bd9caf550bcced37ba6886aba0f74ddc98 vue3 2022-04-25T09:41:05+08:00 wuyb@phxg.cn wuyb@phxg.cn https://gitcode.net/qq_39019768/test_git/-/commit/0691da670b0c52a7a07290d4003d82f258f63e58 Merge branch 'master' of https://gitcode.net/qq_39019768/test_git 2022-04-25T09:41:51+08:00 wuyb@phxg.cn wuyb@phxg.cn Conflicts: vite-demo/src/views/skills/vue3/fnApi.vue https://gitcode.net/qq_39019768/test_git/-/commit/3e7a5c273247bcf9dfaea63642ac624938392cb8 vue3 2022-04-25T17:36:06+08:00 wuyb@phxg.cn wuyb@phxg.cn
<template>
<div>
<div class="child">
<div>我是儿子组件{{child_title}}</div>
</div>
<grandson v-bind="$attrs"/>
</div>
</template>
<script>
import grandson from "./grandson.vue";
export default {
components: {
grandson
},
// 继承所有父组件的内容
inheritAttrs: true,
data() {
return {
child_title: "",
childType: ""
};
},
// props:{
// title:String,
// },
mounted() {
console.log('props- attrs', this.$attrs)
console.log('props- attrs', this.$props)
},
setup(props, {attrs}) {
console.log('props- attrs', props)
console.log('props- attrs', attrs)
}
};
</script>
<template>
<div>
<div class="grandson">我是孙子组件{{title}}{{type}}</div>
</div>
</template>
<script>
export default {
// 不想继承所有父组件的内容,同时也不在组件根元素dom上显示属性
inheritAttrs: true ,
props: {
title: {
type: String,
default: ""
},
type: {
type: [String, Number],
default: ""
}
},
data() {
return {};
}
};
</script>
<template>
<child title="通过attrs传递参数" type="1" @click="ondb"/>
</template>
<script>
// 听过attrs传递参数
import child from './child.vue'
export default {
name: "index",
components: {
child
},
setup() {
const ondb = () => {
console.log(ondb);
}
return {
ondb
}
}
}
</script>
<style scoped>
</style>
\ No newline at end of file
## props和attrs的区别
```
props 要先声明才能取值,attrs 不用先声明
props 声明过的属性,attrs 里不会再出现
props 不包含事件,attrs 包含
props 支持 string 以外的类型,attrs 只有 string 类型
```
## inheritAttrs
[关于Vue的inheritAttrs的理解](https://blog.csdn.net/qq_38211541/article/details/105824684)
```
当inheritAttrs为true时
参数在根节点渲染
当inheritAttrs为false时
参数不在根节点渲染
```
\ No newline at end of file
<template>
   <button @click="f">heihei</button>
   
<button @click="f">heihei</button>
</template>
<script setup>
import {useAttrs } from "@vue/runtime-core";
import {useAttrs} from "@vue/runtime-core";
// 所有的事件,只要不在emits中声明,都会默认绑定在父组件的attrs上
// 当在父组件自定义事件,若没有在子组件中声明时,将自动绑定在父组件的$attrs上;而当在子组件声明时,则不会在父组件的$attrs上出现
const emits = defineEmits(['fun2'])
const {onFun} = useAttrs()
const f = () => {
if(onFun)
if (onFun)
onFun()
emits('fun2')
}
console.log(useAttrs())
console.log('123', useAttrs())
</script>
<template>
<!-- <attrsChild v-bind="$attrs" @edit="edit"></attrsChild>-->
<div>
组件1(加上fun事件,但不在emits中声明)
<com-one-vue @fun='call'/>
</div>
<div>
组件1(加上fun2事件,在emits中声明)
<com-one-vue @fun2='call'/>
</div>
</template>
<script>
// import attrsChild from "./attrsChild.vue";
import comOneVue from './comOne.vue'
export default {
name: "index",
components: {
// attrsChild,
comOneVue
},
setup() {
const call = () => {
console.log('xx')
}
return {
call
}
}
}
</script>
<style scoped>
</style>
\ No newline at end of file
<template>
<div>
<a-card title="响应式 - 核心">
<a-tag color="#2db7f5">ref</a-tag>
<a-tag color="#2db7f5">reactive</a-tag>
<a-tag color="#2db7f5">readonly</a-tag>
<a-tag color="#2db7f5">computed</a-tag>
<a-tag color="#2db7f5">watch</a-tag>
</a-card>
<a-card title="响应式 - 工具函数">
<a-tag color="#2db7f5" title="检查某个值是否为 ref">isRef</a-tag>
<a-tag color="#2db7f5" title="若参数值是一个 ref 则取出内部的值,否则返回值就是参数本身">
<a target="_blank" href="https://staging-cn.vuejs.org/api/reactivity-utilities.html#unref">unref</a>
</a-tag>
<a-tag color="#2db7f5" title="可以通过一个响应式对象的属性来创建一个 ref">toRef</a-tag>
<a-tag color="#2db7f5" title="将一个响应式对象转为一个简单对象,其中每个属性都是一个指向源对象相应属性的 ref">toRefs</a-tag>
<a-tag color="#2db7f5">isProxy</a-tag>
<a-tag color="#2db7f5">isProxy</a-tag>
<a-tag color="#2db7f5">isReactive</a-tag>
</a-card>
<a-card title="响应式 - 进阶">
<a-tag color="#2db7f5" title="ref() 的浅层作用形式。">shallowRef</a-tag>
<a-tag color="#2db7f5" title="强制触发依赖于一个 浅层 ref 的副作用,这常常用在对浅层 ref 的内部值做了变更之后">triggerRef</a-tag>
<a-tag color="#2db7f5" title="创建一个自定义的 ref,显式声明对其依赖追踪和更新触发的控制方式。">customRef</a-tag>
<a-tag color="#2db7f5" title="reactive() 的浅层作用形式。">shallowReactive</a-tag>
<a-tag color="#2db7f5" title="readonly() 的浅层作用形式">shallowReadonly</a-tag>
<a-tag color="#2db7f5" title="根据一个 Vue 创建的代理返回其原始对象">toRaw</a-tag>
<a-tag color="#2db7f5" title="将一个对象标记为不可被转为代理的对象。返回也是该对象。">markRaw</a-tag>
</a-card>
</div>
</template>
<script>
import {reactive, ref, unref, isRef, toRef, shallowRef, watchEffect, triggerRef, toRaw} from 'vue'
export default {
name: "compositionAPI",
setup() {
const foo = {
a: 'b'
}
const reactiveFoo = reactive(foo)
console.log('toRow', toRaw(reactiveFoo) , reactiveFoo);
console.log('toRow', toRaw(reactiveFoo) === foo) // true
return {}
}
}
</script>
<style scoped>
</style>
\ No newline at end of file
......@@ -3,16 +3,17 @@
这是btn1
<p>{{ num }}</p>
<slot></slot>
<slot name="name" :text="num"></slot>
<slot name="name"></slot>
</div>
</template>
<script>
import { ref, defineComponent } from 'vue'
import {ref, defineComponent} from 'vue'
export default defineComponent({
name: 'btn1',
setup() {
const num = ref(1)
return { num }
return {num}
}
})
</script>
\ No newline at end of file
ref
> [ref](https://staging-cn.vuejs.org/guide/essentials/reactivity-fundamentals.html#reactive-variables-with-ref)
```shell script
仅当 ref 是模板渲染上下文的顶层 property 时才适用自动“解包”
const object = { foo: ref(1) }
foo 是顶层 property,但 object.foo 不是
```
reactive
```shell script
仅对对象类型有效(对象、数组和 Map、Set 这样的集合类型),而对 string、number 和 boolean 这样的 原始类型 无效。
响应式对象的 property 赋值或解构至本地变量时会失去响应式
```
<template>
<renderFn :type="1">
<p>默认插槽: 111111</p>
<template #name="{type}">
<span>具名插槽</span> name
<span>使用子组件属性{{type}}</span>
</template>
</renderFn>
</template>
<script>
import {renderFn} from './renderFn.js'
export default {
name: "index",
components: {
renderFn,
},
}
</script>
<style scoped>
</style>
\ No newline at end of file
......@@ -9,7 +9,7 @@ export const renderFn = function (props, {slots}) {
// return props.type == 1 ? h(btn1) : h(btn2)
// 加载默认插槽 - 具名插槽
return props.type == 1 ? h(btn1, [slots.default(), slots.name({
text: props.type
type: props.type
})]) : h(btn2)
}
<template>
<div id="mask"></div>
<renderFn :type="1">
<p>默认插槽: 111111</p>
<template #name>
<span>具名插槽</span> name
</template>
</renderFn>
<div>attrs</div>
<attrsChild v-bind="$attrs" @edit="edit"></attrsChild>
<a-tabs v-model:activeKey="activeKey" type="card">
<a-tab-pane key="1" tab="jsx的使用和插槽传参">
<jsx></jsx>
</a-tab-pane>
<a-tab-pane key="2" tab="vue中的attrs" force-render>
<a-tabs tab-position="left">
<a-tab-pane key="1" tab="Tab 1">
<attrsVue3></attrsVue3>
</a-tab-pane>
<a-tab-pane key="2" tab="$attrs">
<attrs/>
</a-tab-pane>
</a-tabs>
</a-tab-pane>
<a-tab-pane key="3" tab="compositionApi">
<compositionAPI/>
</a-tab-pane>
</a-tabs>
<!-- 组件1(加上fun事件,但不在emits中声明)-->
<com-one-vue @fun='call'/>
<div>
<!-- 组件1(加上fun2事件,在emits中声明)-->
<com-one-vue @fun2='call'/>
</template>
<script>
import {renderFn} from '../components/renderFn.js'
import attrsChild from "../components/attrs/attrsChild.vue";
import {ref} from 'vue'
// jsx
import jsx from '../components/jsx/index.vue'
import attrsVue3 from "../components/attrs/vue3-attrs/index.vue";
// 通过attrs传递参数
import attrs from '../components/attrs/index.vue'
import compositionAPI from "../components/compositionAPI.vue";
console.log(renderFn);
export default {
name: "createVNode",
components: {
renderFn,
attrsChild
jsx,
attrsVue3,
attrs,
compositionAPI
},
setup(props, {emit}) {
function edit(val) {
......@@ -37,12 +47,13 @@
}
return {
edit
edit,
activeKey: ref('1'),
}
}
}
</script>
<!--https://blog.csdn.net/jason_renyu/article/details/122042249-->
<style scoped>
</style>
\ No newline at end of file