组件传值
<h3>props 父传子:</h3>
<p>父组件给子组件一个礼物,礼物是一辆车 BMW</p>
<pre><code class="language-javascript">&lt;template&gt;
&lt;div&gt;我是父组件&lt;/div&gt;
&lt;Child :gift=&quot;car&quot;&gt;&lt;/Child&gt;
&lt;/template&gt;
&lt;script setup&gt;
import { ref } from 'vue'
import Child from '@/components/Child.vue'
let car = ref('BMW')
&lt;/script&gt;</code></pre>
<pre><code class="language-javascript">&lt;template&gt;
&lt;div&gt;我是子组件&lt;/div&gt;
{{ gift }}
&lt;/template&gt;
&lt;script setup&gt;
let props = defineProps(['gift'])
console.log(props.gift)
&lt;/script&gt;</code></pre>
<p>父组件换礼物了,礼物是一辆车 Benz,点击按钮之后,子组件的模板自动更新,是响应式的</p>
<pre><code class="language-javascript">&lt;template&gt;
&lt;div&gt;我是父组件&lt;/div&gt;
&lt;Child :gift=&quot;car&quot;&gt;&lt;/Child&gt;
&lt;button @click=&quot;change&quot;&gt;点击更换&lt;/button&gt;
&lt;/template&gt;
&lt;script setup&gt;
import { ref } from 'vue'
import Child from '@/components/Child.vue'
let car = ref('BMW')
function change() {
car.value = 'Benz'
}
&lt;/script&gt;</code></pre>
<pre><code class="language-javascript">&lt;template&gt;
&lt;div&gt;我是子组件&lt;/div&gt;
{{ gift }}
&lt;/template&gt;
&lt;script setup&gt;
let props = defineProps(['gift'])
console.log(props.gift)
&lt;/script&gt;</code></pre>
<p>子组件可以监听父组件是否更换 gift 了</p>
<pre><code class="language-javascript">&lt;template&gt;
&lt;div&gt;我是父组件&lt;/div&gt;
&lt;Child :gift=&quot;car&quot;&gt;&lt;/Child&gt;
&lt;button @click=&quot;change&quot;&gt;点击更换&lt;/button&gt;
&lt;/template&gt;
&lt;script setup&gt;
import { ref } from 'vue'
import Child from '@/components/Child.vue'
let car = ref('BMW')
function change() {
car.value = 'Benz'
}
&lt;/script&gt;</code></pre>
<pre><code class="language-javascript">&lt;template&gt;
&lt;div&gt;我是子组件&lt;/div&gt;
&lt;/template&gt;
&lt;script setup&gt;
import { watchEffect } from 'vue'
let props = defineProps(['gift'])
watchEffect(() =&gt; {
console.log('父组件传值了' + props.gift)
})
&lt;/script&gt;</code></pre>
<p>父组件想多传一些 gift</p>
<pre><code class="language-javascript">&lt;template&gt;
&lt;div&gt;我是父组件&lt;/div&gt;
&lt;Child :gifts=&quot;giftList&quot;&gt;&lt;/Child&gt;
&lt;/template&gt;
&lt;script setup&gt;
import { ref } from 'vue'
import Child from '@/components/Child.vue'
let giftList = ref(['BMW','House','Girlfriend'])
&lt;/script&gt;</code></pre>
<pre><code class="language-javascript">&lt;template&gt;
&lt;div&gt;我是子组件&lt;/div&gt;
&lt;/template&gt;
&lt;script setup&gt;
const props = defineProps({
gifts: {
type: Array
},
money: {
type: Number,
default: 99
}
})
console.log(props.gifts)
console.log(props.money)
&lt;/script&gt;</code></pre>
<hr />
<h3>props 子传父:</h3>
<p>父组件给子组件传递一个方法,子组件去执行,可以携带参数,父组件可以接收这个参数</p>
<pre><code class="language-javascript">&lt;template&gt;
&lt;div&gt;我是父组件&lt;/div&gt;
&lt;Child :sendToy=&quot;getToy&quot;&gt;&lt;/Child&gt;
&lt;/template&gt;
&lt;script setup&gt;
import { ref } from 'vue'
import Child from '@/components/Child.vue'
function getToy(value) {
console.log(value)
}
&lt;/script&gt;</code></pre>
<pre><code class="language-javascript">&lt;template&gt;
&lt;div&gt;我是子组件&lt;/div&gt;
&lt;button @click=&quot;sendToy(toy)&quot;&gt;送玩具&lt;/button&gt;
&lt;/template&gt;
&lt;script setup&gt;
import { ref } from 'vue'
let toy = ref('toy gun')
let props = defineProps(['sendToy'])
&lt;/script&gt;</code></pre>
<hr />
<ul>
<li>利用 useAttrs 父传子:</li>
</ul>
<pre><code class="language-javascript">App:
&lt;template&gt;
&lt;Child text=&quot;App文本&quot;&gt;&lt;/Child&gt;
&lt;/template&gt;
&lt;script setup&gt;
import Child from &quot;@/components/Child.vue&quot;;
&lt;/script&gt;</code></pre>
<pre><code class="language-javascript">Child:
&lt;template&gt;&lt;/template&gt;
&lt;script setup&gt;
import { useAttrs } from &quot;vue&quot;;
const attrs = useAttrs();
console.log(attrs.text);
&lt;/script&gt;</code></pre>
<hr />
<ul>
<li>props 和 useAttrs 的区别:
<img src="https://www.showdoc.com.cn/server/api/attachment/visitFile?sign=8ae6200fa778038803c3c1614b8d0075" alt="" /></li>
</ul>
<hr />
<ul>
<li>emits子传父:</li>
</ul>
<pre><code class="language-javascript">Child:
&lt;template&gt;&lt;/template&gt;
&lt;script setup&gt;
const emits = defineEmits([&quot;childdata&quot;]);
emits(&quot;childdata&quot;, &quot;child消息&quot;);
&lt;/script&gt;</code></pre>
<pre><code class="language-javascript">App:
&lt;template&gt;
&lt;Child @childdata=&quot;CHILDDATA&quot;&gt;&lt;/Child&gt;
&lt;/template&gt;
&lt;script setup&gt;
import Child from &quot;@/components/Child.vue&quot;;
function CHILDDATA(s) {
console.log(s);
}
&lt;/script&gt;</code></pre>
<hr />
<ul>
<li>expose子组件向外暴露:</li>
</ul>
<pre><code class="language-javascript">Child:
&lt;template&gt;&lt;/template&gt;
&lt;script setup&gt;
import { ref, onMounted } from &quot;vue&quot;;
let childtext = ref(&quot;子组件暴露的数据&quot;);
defineExpose({
childtext,
});
&lt;/script&gt;</code></pre>
<pre><code class="language-javascript">App:
&lt;template&gt;
&lt;Child ref=&quot;CHILDTEXT&quot;&gt;&lt;/Child&gt;
&lt;/template&gt;
&lt;script setup&gt;
import { ref, onMounted } from &quot;vue&quot;;
import Child from &quot;@/components/Child.vue&quot;;
let CHILDTEXT = ref(null);
onMounted(() =&gt; {
console.log(CHILDTEXT.value.childtext);
});
&lt;/script&gt;</code></pre>
<hr />
<ul>
<li>利用父传子一个function,实现子传父</li>
</ul>
<pre><code class="language-javascript">App:
&lt;template&gt;
&lt;Child :PARENTFUNCTION=&quot;parentFunction&quot;&gt;&lt;/Child&gt;
&lt;/template&gt;
&lt;script setup&gt;
import Child from &quot;@/components/Child.vue&quot;
const parentFunction = (data) =&gt; {
console.log(data)
}
&lt;/script&gt;</code></pre>
<pre><code class="language-javascript">Child:
&lt;template&gt;&lt;/template&gt;
&lt;script setup&gt;
const props = defineProps({
PARENTFUNCTION: {
type: Function
}
})
props.PARENTFUNCTION(&quot;子组件的数据&quot;)
&lt;/script&gt;</code></pre>
<hr />
<ul>
<li>provide / inject 类似消息订阅与发布:</li>
</ul>
<pre><code class="language-javascript">App:
&lt;template&gt;
&lt;Child&gt;&lt;/Child&gt;
&lt;/template&gt;
&lt;script setup&gt;
import { provide } from &quot;vue&quot;;
import Child from &quot;@/components/Child.vue&quot;;
provide(&quot;name&quot;, &quot;Andy&quot;);
&lt;/script&gt;</code></pre>
<pre><code class="language-javascript">Child:
&lt;template&gt;&lt;/template&gt;
&lt;script setup&gt;
import { inject } from &quot;vue&quot;;
let info = inject(&quot;name&quot;);
console.log(info);
&lt;/script&gt;</code></pre>
<hr />
<h3>mitt 任意组件传值:类似于消息订阅与发布</h3>
<p>下载 mitt</p>
<pre><code class="language-bash">npm install mitt</code></pre>
<p>新建 emitter.js</p>
<pre><code class="language-javascript">import mitt from 'mitt'
const emitter = mitt()
export default emitter</code></pre>
<p>子组件引入 emitter,并且订阅 send-toy</p>
<pre><code class="language-javascript">&lt;template&gt;
&lt;div&gt;我是子组件&lt;/div&gt;
&lt;/template&gt;
&lt;script setup&gt;
import { ref } from 'vue'
import emitter from '@/utils/emitter'
emitter.on('send-toy', (value) =&gt; {
console.log(value)
})
&lt;/script&gt;</code></pre>
<p>父组件也引入 emitter,点击按钮之后发布一个事件 send-toy,子组件那边就会收到</p>
<pre><code class="language-javascript">&lt;template&gt;
&lt;div&gt;我是父组件&lt;/div&gt;
&lt;button @click=&quot;send&quot;&gt;送玩具&lt;/button&gt;
&lt;Child&gt;&lt;/Child&gt;
&lt;/template&gt;
&lt;script setup&gt;
import { ref } from 'vue'
import Child from '@/components/Child.vue'
import emitter from '@/utils/emitter'
let toy = ref('toy gun')
function send() {
emitter.emit('send-toy', toy.value)
}
&lt;/script&gt;</code></pre>