目录
Vue的组件化编程
Vue.component("组件名称", {}) // 声明一个全局组件
- <body>
- <div id="app">
-
- <button-counter>button-counter>
- div>
- <script>
- // 声明一个全局组件
- Vue.component('button-counter', {
- data() { // 组件提供的data函数(为什么是data函数,不是data属性?因为属性的值被改变了,其他使用此属性的值都会被改变,而函数不会)
- return {count:0}
- },
- template: '',
- });
- new Vue({
- el: "#app"
- });
- script>
- body>
const c = Vue.extend({}); // 声明一个局部组件,返回组件对象
- <body>
- <div id="app">
-
- <c>c>
- div>
- <script>
- // 声明一个局部组件
- const c = Vue.extend({
- data() { // 组件提供的data函数(为什么是data函数,不是data属性?因为属性的值被改变了,其他使用此属性的值都会被改变,而函数不会)
- return { count: 0 }
- },
- template: '',
- });
- new Vue({
- el: "#app",
- components: { // 局部声明的组件,要在Vue实例里使用components块注册
- c: c // 属性名和属性值相同,可以简写成 c
- }
- });
- script>
- body>
- <body>
- <div id="app">
-
- <aa>aa>
- div>
- <script>
- // 二级组件
- const bb = Vue.extend({
- data() {
- return { name: '二级组件' }
- },
- template: ' {{ name }} ',
- });
-
- // 一级组件
- const aa = Vue.extend({
- data() {
- return { name: '一级组件' }
- },
- template: `
- {{ name }}
-
- `,
- components: {
- bb
- }
- });
- new Vue({
- el: "#app",
- components: {
- aa
- }
- });
- script>
- body>
脚手架中的Vue组件就是上面讲到的 局部组件 Vue.extend()。Vue.extend() 变成脚手架的方式就是把返回值变成了 export default 导出的方式,然后父组件 import 进行导入,template 属性被 标签替换
props
// props的数据时单向的,只能从⽗组件传到⼦组件。
// props的数据不可更改,如果要更改需备份到data中做操作
父组件代码
- <div>
-
- <HelloWorld msg="123" />
- <HelloWorld v-bind:msg="123" />
- div>
- <script>
- import HelloWorld from './components/HelloWorld.vue'
- export default {
- name: 'App',
- components: {
- HelloWorld
- }
- }
- script>
- <style>
- style>
子组件代码
- <div>
- <h1>{{ msg }}h1>
- div>
- <script>
- export default {
- name: 'HelloWorld',
-
- data() {
- return {
- msg_copy: this.msg // props的数据不可更改,如果要更改需备份到data中做操作
- }
- },
-
- // 方式一:
- // props: [ // 子组件使用 props 属性,数组的方式 接收变量值
- // "msg"
- // ]
-
- // 方式二:
- // props: { // 使用 props 属性,对象的方式限制传进来的值的类型
- // msg: String
- // }
-
- // 方式三:
- props: { // 限制类型,限制必传,限制默认值
- msg: {
- type: String,
- required: true,
- default: "你好", // 没有传值的时候用默认值
- }
- }
- }
- script>
- <style >
- style>
父组件代码
- <div>
- <h1>{{mess}}h1>
- <HelloWorld :transmits="transmit"/>
- div>
- <script>
- import HelloWorld from './components/HelloWorld.vue'
- export default {
- name: 'App',
- data() {
- return {
- mess: "" // 用于接收 子组件传过来的值
- }
- },
- components: {
- HelloWorld
- },
- methods: {
- transmit(name) { // 定义一个回调函数
- this.mess = name;
- }
- }
- }
- script>
- <style>
- style>
子组件代码
- export default {
- name: 'HelloWorld',
- data() {
- return {
- name: "我是子组件的值" // 子组件的数据
- }
- },
- props: ["transmits"], // 接收父组件的回调函数
- mounted() {
- this.transmits(this.name) // 调用回调函数,把 值传进去
- }
- }
// 父组件
@自定义事件名称M="函数名S" // 事件名称和函数名不能取成一样的
// 子组件
this.$emit("事件名称M", "传递的数据")
父组件代码
- <div>
- <IndexOne @mysj="dianji"/>
- div>
- <script>
- import IndexOne from './components/IndexOne.vue'
- export default {
- name: 'App',
- components: {
- IndexOne
- },
- methods: {
- dianji(name) {
- console.log("传进来的值=", name);
- }
- }
- }
- script>
子组件代码
- export default {
- mounted() { // 初始化自动执行函数
- this.$emit("mysj", "我是要传的数据");
- }
- }
// 父组件
ref="变量名S"
this.$refs.变量名S.$on("事件名N", 箭头函数)
// 子组件
this.$emit("事件名N", "传递的数据")
父组件代码
- <div>
- <IndexTwo ref="dianji"/>
- div>
- <script>
- import IndexTwo from './components/IndexTwo.vue'
- export default {
- name: 'App',
- components: {
- IndexTwo
- },
- methods: {
- test(name) {
- console.log("传进来的值=", name);
- }
- },
- mounted() { // 监听 自定义事件
- this.$refs.dianji.$on("mysj", this.test)
- }
- }
- script>
子组件代码
- <div>
- <button @click="change">点击button>
- div>
- <script>
- export default {
- methods: {
- change() {
- this.$emit("mysj", "我是要传的数据");
- }
- }
- }
- script>
this.$off();
Vue实例上安装全局事件总线
- new Vue({
- beforeCreate() {
- // 安装全局事件总线,$bus 可以自定义其他名称
- Vue.prototype.$bus = this;
- },
- render: h => h(App),
- }).$mount('#app')
在需要接收数据的组件里绑定自定义事件
- export default {
- methods: {
- consoleData(myData) {
- // 打印接收到的数据
- console.log(myData);
- }
- },
- mounted() { // 初始化完成后,监听自定义事件,
- this.$bus.$on("mysj", this.consoleData);
- }
- }
提供数据的组件
- <div>
- <button @click="change">触发全局总线button>
- div>
- <script>
- export default {
- methods: {
- change() {
- this.$bus.$emit("mysj", "我是数据")
- }
- }
- }
- script>
解绑全局事件总线
beforeDestroy() { this.$bus.$off(); }
在html中的自定义组件中使用html标签
- <template>
- <div>
- <HelloWorld>
- <h1>Vueh1>
- HelloWorld>
- div>
- template>
- <template>
- <div>
- <slot>slot> // 插槽标签,父组件的 html 标签就会放在插槽标签指定的位置
- div>
- template>
// v-slot 只能写在 template 标签以及组件上
- <template>
- <div>
- <HelloWorld>
- <template v-slot:a>
- <p>Vuep>
- template>
- <template v-slot:b>
- <p>Javap>
- template>
- HelloWorld>
- div>
- template>
- <template>
- <div>
- <h1>
- <slot name="a">slot>
- h1>
- <h6>
- <slot name="b">slot>
- h6>
- div>
- template>
数据定义在⼦组件,但是数据需要在⽗组件的插槽中使⽤
- <template>
- <div>
- <HelloWorld>
- <template v-slot="newList">
- <div v-for="item,index in newList.list" :key="index"> {{item}} div>
- template>
- HelloWorld>
- div>
- template>
- <template>
- <div>
- <slot :list="list">slot>
- div>
- template>
- <script>
- export default {
- name: 'HelloWorld',
- data() {
- return {
- list: ["Java", "Vue"]
- }
- }
- }
- script>
定义
提供了一种非常灵活的方式,来分发 Vue 组件中的可复用功能。一个混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象的选项将被“混合”进入该组件本身的选项
// 就是导入js数据
- // 片段js数据 a.js
- export const myMixin = {
- data () {
- return {
- name: "公共变量数据"
- }
- },
- mounted () {
- console.log("我是可以被其他Vue组件引入的片段");
- }
- }
- <div>
- <div>{{name}}div>
- div>
-
- <script>
- import { myMixin } from "../a.js"
- export default {
- mixins: [myMixin] // 需要使用Vue提供的 mixins 块
- }
- script>
片段js数据是相同的
- // main.js
- import { myMixin } from "./a.js";
- Vue.mixin(myMixin);
当组件和混入对象含有同名选项时,这些选项将进行“合并”
在选项发生冲突时以组件数据优先
请谨慎使用全局混入,因为会使实例以及每个组件受影响