vue2 API-实例property在项目中的使用

1.$options

概念:用于当前 Vue 实例的初始化选项。需要在选项中包含自定义 property 时会有用处:

用处示例:

①获取,调用data外定义的属性

<script>
export default {
  data() {
    return {
    };
  },
  //在data外面定义的属性和方法通过$options可以获取和调用
  name: "options_test",
  age: 18,
  testOptionsMethod() {
    console.log("hello options");
  },
  created() { 
    console.log(this.$options.name);  // options_test
    console.log(this.$options.age);  // 18
    this.$options.testOptionsMethod();  // hello options
  },
</script>

②复用过滤器filters中的方法

//常用于在表达式的尾部
<div>{{ text | filterText }}</div>
 
export default {
    data() {
        return {
            text: 'hello'
        } 
    },
    filters: {
        filterText: function (value) {
            if (!value) return ''
            return value
         }
    },
    methods:{
      getTextFn(){
        let filterText = this.$options.filters.filterText
        this.text = filterText('Hi')
      },
    },
}

③一键搞定之重置data中的数据

<script>
    export default {
        data() {
            return {
                // 表单
                searchForm: {
                    input: ''
                }
            }
        },
        methods: {
            retset() {
                //重置某一个表单数据
                this.searchForm = this.$options.data().searchForm;
                //重置整个$data
                this.$data = this.$options.data();
            }
        },
    }
</script>

2.$parent

$parent:子组件获取父组件的数据、调用父组件的方法
父组件:
<template>
  <div class="parent">
    <h3>父组件</h3>
    <div class="view-contain-box">
      <child-one />
      <child-two />
    </div>
  </div>
</template>
<script>
import ChildOne from '../components/child-one.vue'
import ChildTwo from '../components/child-two.vue'
export default {
  components: {
    ChildOne, ChildTwo
  },
  data () {
    return {
      text: 'hello'
    }
  },
  methods: {
    test () {
      return 123
    }
  }
}
/************************************************/
子组件:
<template>
  <div class="view-contain-one">
    <button @click="getParentData">获取父组件数据并调用其内部方法</button>
  </div>
</template>
<script>
export default {
  data () {
    return {
      message: 123
    }
  },
  methods: {
    getParentData () {
      const val = this.$parent.text
      const val1 = this.$parent.test()
    }
  }
}
</script>

3.$children

$children:父组件获取子组件的数据、调用子组件的方法
<template>
  <div class="parent">
    <h3>父组件</h3>
    <div @click="getChild1Value" class="operate">获取子组件1data里的数据并执行对应的方法</div>
    <div @click="getChild2Value" class="operate">获取子组件2data里的数据并执行对应的方法</div>
    <div class="view-contain-box">
      <child-one />
      <child-two />
    </div>
  </div>
</template>
<script>
import ChildOne from '../components/child-one.vue'
import ChildTwo from '../components/child-two.vue'
export default {
  components: {
    ChildOne, ChildTwo
  },
  data () {
    return {
      text: 'hello'
    }
  },
  methods: {
    getChild1Value () {
      const val = this.$children[0].message || ''
      const val1 = this.$children[0].test()
    },
    getChild2Value () {
      const val = this.$children[1].message || ''
      const val1 = this.$children[1].test()
    }
  }
}
</script>

4.$root

$root:获取当前组件树的根 Vue 实例。如果当前实例没有父实例,此实例将会是其自己。通过 $root,可以实现组件之间的跨级通信
 
父组件:
<template>
  <div>
    <div class="view-contain-box">
      <child-one />
      <child-two />
    </div>
  </div>
</template>
<script>
import ChildOne from '../components/child-one.vue'
import ChildTwo from '../components/child-two.vue'
export default {
  components: {
    ChildOne, ChildTwo
  },
  data () {
    return {
      text: 'hello'
    }
  },
  methods: {
  }
}
</script>
<style scoped>
.view-contain-box {
  display: flex;
  justify-content: center;
  align-items: center;
}
</style>
 
 
/************************************************************************/
子组件1:
<template>
  <div class="view-contain-one">
    <p>我是子组件1</p>
    <button @click="changeData">改变son2数据</button>
  </div>
</template>
<script>
export default {
  data () {
    return {
      message: 123
    }
  },
  methods: {
    // 点击按钮后需要改变Child2组件的数据。
    // 我们可以通过在Child1组件的methods中使用$root属性来访问和操作Child2组件的数据:
    changeData () {
      this.$root.$emit('changeChild2Data', 456)
    }
  }
}
</script>
<style scoped>
.view-contain-one {
  height: 300px;
  width: 500px;
  border: 1px solid #ccc;
}
</style>
 
 
/************************************************************************/
子组件2:
<template>
  <div class="view-contain-two">
    <p>我是子组件2</p>
    <p>{{ child2Data }}</p>
  </div>
</template>
<script>
export default {
  data () {
    return {
      child2Data: 123
    }
  },
  methods: {},
  created () {
    this.$root.$on('changeChild2Data', data => {
      this.child2Data = data // 更新组件数据
    })
  }
}
</script>
<style scoped>
.view-contain-two {
  height: 300px;
  width: 500px;
  border: 1px solid #ccc;
}
</style>

5.$refs

$refs:我们通常会将 refs 绑定在子组件上,从而获取子组件实例
<template>
  <div class="parent">
    <h3>父组件</h3>
    <button @click="getChildData">获取子组件1data里的数据并执行methods对应的方法</button>
    <div class="view-contain-box">
      <child-one ref="childOne" />
    </div>
  </div>
</template>
<script>
import ChildOne from './components/child-one.vue'
export default {
  components: {
    ChildOne
  },
  data () {
    return {
      text: 'hello'
    }
  },
  methods: {
    getChildData () {
      const message = this.$refs.childOne.message
      console.log('message==', message)
      const data = this.$refs.childOne.changeData()
      console.log('data==', data)
      // 需要注意下拾贝云框架中的refs嵌套问题
      // this.$refs.DataTable.$refs.tableRef[0].clearSelection()
      // const selection = this.$refs.DataTable.$refs.DataTable.getSelectionData();
      const sonMessage = this.$refs.childOne.$refs.sonOne.message
      console.log('sonMessage==', sonMessage)
      // $refs引用将指向子组件的实例
      // 在使用$refs时,需要确保在组件渲染完成后再去访问它们,例如在mounted生命周期钩子中,
      // 这样可以确保ref注册的元素或组件已经被正确地创建和挂载,从而避免出现访问不到的情况
      // if(this?.$refs?.DataTable) {}
    }
  }
}
</script>

6.$attrs和$listeners

父子组件的通信可以使用props和$emit的方式,但是如果进行父子组件和孙子组件的通讯使用props和$emit的话就比较复杂了,需要层层传递。
而$attrs和$listeners就减少了子组件的代码。它打通了父组件和孙组件之间的阻碍。
 
 
// 父组件
<template>
  <div class="app">
    <h3>我是父组件</h3>
    <child-one :data1="data1" :data2="data2" :data3="data3" @fun1="fun1" @fun2="fun2"></child-one>
  </div>
</template>
<script>
import childOne from './components/child-one.vue'
export default {
  name: 'App',
  components: {
    childOne
  },
  data () {
    return {
      data1: '11',
      data2: '22',
      data3: '33'
    }
  },
  methods: {
    fun1 (val) {
      console.log('通过子组件触发', val)
    },
    fun2 (val) {
      console.log('通过子组件触发', val)
    }
  }
}
</script>
 
 
// 子组件
<template>
  <div class="parent">
    <h3>我是子组件</h3>
    <Son v-bind="$attrs" v-on="$listeners"></Son>
  </div>
</template>
<script>
import Son from './son-one.vue'
export default {
  name: 'ChildOne',
  props: {
    data1: {
      type: String,
      default: ''
    }
  },
  components: {
    Son
  },
  created () {
    console.log('this.$attrs==', this.$attrs) // data2: "数据2", data3: "数据3"
    console.log('this.$listeners==', this.$listeners) // fun1, fun2
  }
}
</script>
 
 
// 孙组件
<template>
  <div class="son">
    <h3>我是孙组件</h3>
    这是爷爷的数据=={{data2}} <br>
    这是自己的数据=={{message}}<br>
    <button @click="toParent">传递数据给父组件</button>
  </div>
</template>
<script>
export default {
  name: 'Son',
  props: {
  // 接收父组件的数据
    data2: {
      type: String,
      default: ''
    },
    data3: {
      type: String,
      default: ''
    }
  },
  data () {
    return {
      message: 123
    }
  },
  created () {
    console.log(this.data2, this.data3, '$attrs')
  },
  methods: {
    toParent () {
    // 触发父组件的方法
      this.$emit('fun1', '我是孙组件数据')
    }
  }
}
</script>

7.$slots

$slots:用来访问被插槽分发的内容。在使用渲染函数书写一个组件时,访问 vm.$slots 最有帮助。
 
 
// 父组件
<template>
  <div class="parent">
    <div class="view-contain-box">
      <child-one :tableData="tableData">
        <div>123</div>
        <div>456</div>
        <div slot="header">slot: header</div>
        <div slot="footer">slot: footer</div>
      </child-one>
    </div>
  </div>
</template>
<script>
import ChildOne from './components/child-one.vue'
export default {
  components: {
    ChildOne
  },
  data () {
    return {
      tableData: [
        { name: 111 },
        { name: 222 },
        { name: 333 }
      ]
    }
  },
  methods: {
  }
}
</script>
 
 
// 子组件
<script>
export default {
  props: {
    tableData: {
      type: Array,
      default () {
        return []
      }
    }
  },
  data () {
    return {
    }
  },
  mounted () {
    console.log('this.$slots==', this.$slots) // { default:[VNode, VNode], footer: [VNode], header:[VNode] }
    console.log('this.$slots.default==', this.$slots.default) // undefind
  },
  render (h, vm) {
    return (
      <ul>
        {
          this.tableData.map(item => (
            <li>{this.$slots.default || item.name}</li>
            // <li>{this.$slots.header || item.name}</li>
          ))
        }
      </ul>
    )
  }
}
</script>

8.$scopedSlots

用来访问作用域插槽。vm.$scopedSlots 在使用渲染函数开发一个组件时特别有用。
 
// 父组件
<template>
  <div class="parent">
    <div class="view-contain-box">
      <child-one :tableData="tableData">
        <!-- 无论怎么修改,页面显示的列表项都是一样的,因为我们的default插槽是一样的。 -->
        <!-- <span>{{tableData[0].name}} ===> vm.$slots的使用</span> -->
        <span slot-scope="scope">{{scope.name}}  ===> vm.scopedSlots的使用</span>
      </child-one>
    </div>
  </div>
</template>
<script>
import ChildOne from './components/child-one.vue'
export default {
  components: {
    ChildOne
  },
  data () {
    return {
      tableData: [
        { name: 111 },
        { name: 222 },
        { name: 333 }
      ]
    }
  },
  methods: {
  }
}
</script>
 
 
// 子组件
<script>
export default {
  props: {
    tableData: {
      type: Array,
      default () {
        return []
      }
    }
  },
  data () {
    return {
    }
  },
  mounted () {
    // 作用域插槽允许子组件向父组件传递数据
    console.log('this.$scopedSlots.default==', this.$scopedSlots.default)
  },
  render (h, vm) {
    return (
      <ul>
        {
          this.tableData.map(item => (
            // <li>{this.$slots.default || item.name}</li>
            <li>{this.$scopedSlots.default(item)}</li>
          ))
        }
      </ul>
    )
  }
}
</script>

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue 3 使用 Vue-Quill-Editor 可能会出现以下错误: ``` [vue-composition-api] "Uncaught TypeError: Cannot read property '_vm' of undefined" ``` 这是因为 Vue 3 使用了 Composition API,而 Vue-Quill-Editor 还没有完全适配 Composition API。解决该问题可通过在 `setup()` 函数引入 `onMounted`、`onUnmounted` 等钩子函数,然后手动初始化 Quill 编辑器。 以下是一个示例: ```vue <template> <div> <div ref="editor"></div> </div> </template> <script> import { onMounted, onUnmounted, ref } from 'vue'; import Quill from 'quill'; import 'quill/dist/quill.snow.css'; export default { setup() { const editor = ref(null); onMounted(() => { const quill = new Quill(editor.value, { modules: { toolbar: [ ['bold', 'italic', 'underline', 'strike'], [{ list: 'ordered' }, { list: 'bullet' }], ['link', 'image'], ], }, theme: 'snow', }); quill.on('text-change', () => { console.log(quill.root.innerHTML); }); // save the instance of Quill editor editor.value.__quill = quill; }); onUnmounted(() => { // destroy the instance of Quill editor editor.value.__quill.destroy(); editor.value.__quill = null; }); return { editor, }; }, }; </script> ``` 在上述示例,我们在 `setup()` 函数使用 `onMounted` 和 `onUnmounted` 钩子函数来初始化和销毁 Quill 编辑器。同时,我们在 `onMounted` 监听 `text-change` 事件,以便在编辑器内容发生变化时执行一些操作。最后,我们将 Quill 实例保存在 `editor.value.__quill` ,以便在其他地方访问该实例
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值