Fork me on GitHub

Coding Poineer

Coding Poineer

Coding Poineer

Coding Poineer

Coding Poineer

Coding Poineer

Coding Poineer

Coding Poineer

Coding Poineer

Coding Poineer

Coding Poineer

Vue-Api 细分理解

<body> <div> <a href="https://www.cnblogs.com/lhx9527/p/14247707.html" target="_blank" rel="noopener noreferrer">跳转到-> vue-router </a> <h2>目录:</h2> <ul> <li> <a href="#GlobalApi">全局API及部分全局配置</a> </li> <li> <a href="#VueItems">Vue内的选项</a> <ul> <li> <a href="#DataItem">选项-数据</a> </li> <li> <a href="#DomItem">选项-DOM</a> </li> <li> <a href="#HookItem">Vue钩子函数</a> </li> <li> <a href="#ResourceItem">选项-资源</a> </li> <li> <a href="#ComItem">选项-组合</a> </li> </ul> </li> <li> <p>Vue 实例属性</p> <ul> <li> <a href="#InstanceProperties">Vue实例--属性</a> </li> <li> <a href="#InstanceFunData">Vue实例--数据有关的方法</a> </li> <li> <a href="#InstanceFunEvent">Vue实例--事件有关的方法</a> </li> <li> <a href="#InstanceFunLife">Vue实例--生命周期有关的方法</a> </li> <li> <a href="#dircts">Vue实例--指令集</a> </li> <li> <a href="#spcAttrs">Vue实例--特殊指令集</a> </li> </ul> </li> </ul> </div>

------------------------------------问题部分-----------------------------------------------

常见问题:

  • 自递归+for循环:渲染菜单
  • // 注意通过 prop 传入的参数能终止递归
    <template>
      <div class="ball" v-if="ball.children">
        <div>{{ball.v}}</div>
    // 递归嵌套位置
        <ball-vue :ball="ball.children"></ball-vue>
      </div>
    </template>
    <script>
    export default {
      name: 'ballVue',
      props:['ball'] }
    
  • keep-alive : 缓存组件,无需重加载消耗资源
  •   <el-tabs v-model="activeName" type="card" @tab-click="handleClick">
        <el-tab-pane label="用户管理" name="first">用户管理</el-tab-pane>
        <el-tab-pane label="配置管理" name="second">配置管理</el-tab-pane>
    // include 不能为空。为空则匹配所有,写一个不可能有的name即可
        <keep-alive include='组件name属性' exclude>
           <router-view></router-view>
        </keep-alive>    
      </el-tabs>
    
  1. 全局API及部分全局配置

    • Vue.config.optionMergeStrategies.要合并的属性

        Vue.config.optionMergeStrategies.data = (parent,child)=>{
          //这里是vue中的data属性会受到合并策略的影响
          console.log('调用',parent,child);
            if (!parent) {  
                return child
            }
            if (!child) {  
                 return parent
             }
            return Object.assign(parent,child) 
          };
      
    • mixins:实质上除App.vue外的每个组件都会有mixin,只不过初始值都是undefine

      export default {
        name: "HelloWorld",
        mixins:[hello],
        //这里parent:helloworld中的data函数,child是mixin中hello的data函数
      };
      

      实际上借助上面optionMergeStrategies中的打印函数,我们看到了不止1次打印

      一:mixins自己也有mixin(undefine,mixin)、二:组件内部正常打印(mixin,组件内data函数)、三:每个组件有默认的mixins(即使没写出来,也会打印undefine,自己的data函数)

    • 使用Vue.extend(已使用Vue.component)

      Cannot create property '_Ctor' on string 'xxx'

      更改Vue.extend产生的组件构造函数的函数名即可

      Vue.extend产生构造函数,调用后产生一个组件--直接挂载即可,不能放在vue的components(里面的是对象未经过编译)属性中

    • Vue.nextTick( [callback, context]):vue中DOM操作是异步的,可能在同步代码中得到undefine

      Vue.set( target, propertyName/index, value ):给响应式新增一个属性(响应式的,直接添加不是响应式的)

      Vue.delete( target, propertyName/index ):与上面相反

      this.msg = 'msg'
      //要操作DOM(即使用到DOM的api),不是操作vue组件中的属性
      this.$nextTick(()=>{
         //放里面能获取到
        this.msg1 = this.$refs.msgDiv.innerHTML
      })
      //放外面获取不到
      this.msg2 = this.msg1
      this.$set(this.obj,'num',100)
      // 不能在 data 上设置根级数据
      

      把后面依赖异步的代码放到nextTick中的回调函数中执行

    • Vue.directive(id,[definition]):自定义指令

      // 全局定义
      import Vue from 'vue';
      Vue.directive('focus',{
        inserted:function(el){
          el.focus()
        }
      })
      // 局部定义
      export default {
        data(){return{}}
        directives:{
          focus : {
            inserted : function(el){el.focus()}} }
        filters:{ //自定义过滤器
          upper: function(val){return val.toUpperCase()},
          addol: function(val){return val+'ol'}
        }
      }
      

      id:指令名(使用时以v-开头)、第二个参数:对象(多个生命周期钩子函数)

    • Vue.filter( id, [definition] ):自定义过滤器

      过滤器函数名,局部/全局使用方式同directive

      下面展示2种使用方法

      // 双花括号使用{{}}
      <div>{{obj.name | upper | addol}}</div>
      // v-bind,这个可以在父组件向子组件传参时使用
      <api v-bind:id="apiId | upper"></api>
      props:['id'],
      
    • Vue.component( id, [definition] ):注册或获取全局组件。注册还会自动使用给定的 id 设置组件的名称

      Vue.component返回的是一个构造器函数

      构造器函数(同Vue.extend)执行-> 编译后 -> render -> VNode -> $mounts : vue实例

      // 注册组件,传入一个扩展过的构造器
      Vue.component('my-component', Vue.extend({ /* ... */ }))
      // 注册组件,传入一个选项对象 (自动调用 Vue.extend)
      Vue.component('my-component', { /* ... */ })
      // 获取注册的组件 (始终返回构造器)
      var MyComponent = Vue.component('my-component')
      // -------------------实际使用-------------------------
      Vue.component('com',{
        mounted() {
        },
      })
      var MyComponent = Vue.component('com')
      export default {  
        components:{ com } //这里给的构造函数
        //----或者-------
        components:{
          com: {      // 这里给的对象 ,与平时import子组件一样
            mounted:function() {
              alert('开始ile')}}
        }};
      
    • Vue.use( plugin ):{Object | Function} plugin

      如果插件是一个对象,必须提供 install 方法。如果插件是一个函数,它会被作为 install 方法。install 方法调用时,会将 Vue 作为参数传入。 该方法需要在调用 new Vue() 之前被调用。

      当 install 方法被同一个插件多次调用,插件将只会被安装一次。

    • Vue.compile( template ):{string} template,将一个模板字符串编译成 render 函数。只在完整版时可用

      如果插件是一个对象,必须提供 install 方法。如果插件是一个函数,它会被作为 install 方法。install 方法调用时,会将 Vue 作为参数传入。 该方法需要在调用 new Vue() 之前被调用。

      当 install 方法被同一个插件多次调用,插件将只会被安装一次。

    • var res = Vue.compile('<div><span>{{ msg }}</span></div>')
      new Vue({
        data: {
          msg: 'hello'
        },
        render: res.render,
        staticRenderFns: res.staticRenderFns
      })
      
    • Vue.observable(object):让一个普通对象可相应

      返回的对象可以直接用于渲染函数和计算属性内,并且会在发生变更时触发相应的更新。也可以作为最小化的跨组件状态存储器,用于简单的场景

      Vue2中返回的对象和源对象是同一个对象,Vue3中是返回一个新的对象

      const state = Vue.observable({ count: 0 })
      const Demo = {
        render(h) {
          return h('button', {
            on: { click: () => { state.count++ }}
          }, `count is: ${state.count}`)
        }
      }
      
    • Vue.version:返回一个版本号

  2. Vue内的选项

    • 选项-数据

      • data:Object | Function

        Vue会递归将data的property(不包含原型链上)转换为getter/setter(通过Object.defineProperty)->变为响应式的数据

        无法在根数据对象上添加响应式property:推荐在创建实例之前,就声明所有的根级响应式property

        data() {
          return {
            name: 'lhx',
            age : 12,
            // obj是data中的根级数据,obj.name不是。根级数据是不能新增/删除,所以提前设置好需要的,后期不再变更
            obj:{
              name: '二级数据'
            },
            // 由于Vue实例的代理,this.name == this.$data.name
            $gg :'jj'
        }},
        methods: {
          change(){
            this.$set(this.data,'num',13) 
        // _/$开头可能与内置Api/Property冲突,不能以代理方式访问
            console.log(this.$data.$gg); }}
        

        实例创建之后,通过 vm.$data.name / vm.name(Vue实例代理( proxy )data 对象所有的 property) 访问原始数据对象,

        以 _ 或 $ 开头的 property 不会被代理,通过 vm.$data._property 访问

        data之所以被声明为函数,函数返回一个对象,对象都会指向创建它的vue实例,所以可通过this.$data访问

        深拷贝data中的属性:JSON.parse(JSON.stringify(...))

      • props: Array(string) | Object

        type:String、Number、Boolean、Array、Object、Date、Function、Symbol,会检查是否是这个类型

        default:any(默认值,如果该 prop 没有被传入,则换做用这个值, 另外数组、对象的值必须用函数返回

        required : 是否必须传入

        validator : 验证器函数

        props:{
          objdata:{
            type : Object,
            default : ()=>{},
            require : true,
            validator : function(value){
              return Object.keys(value).length>0
             }
          }
        };
        
    • 选项-DOM

      • el:string | Element

        只在用 new 创建实例时生效(其它情况写的el是无效)

        实例化时存在这个选项,实例将立即进入编译过程,否则,需要显式调用 vm.$mount() 手动开启编译

        如果不是在new情况下,this.$el会指向 template 中的DOM元素

      • template : string

        加到挂载点的DOM模板,挂载点:el / 页面中的xxx-vue

        模板会替换挂载点及原有DOM,可以通过 slot插槽 保留

        模板会替换挂载点及原有DOM,可以通过 slot插槽 保留

        //模板方式1
        <template>
          <div></div>
        </template>
        //方式2   优先级低于1
        template:'<div>字符串模板</div>'
        // 方式3  x-template ,在.vue文件无法使用,异步的渲染函数无法渲染同步的 template 中的‘#’选择器
        <script type="x-template" id="mytem">
          <div>我是x-template生成的模板</div>
        </script>
        
      • render : (createElement: () => VNode) => VNode

        render的优先级比template高,即render和template产生相同,render也渲染模板

        影响render在与createElement参数

        main.js中render中的 h 只是一个形参,最终会将createElement作为实参传进去

        import Vue from 'vue';
        var vnVue = Vue.component('vn',{
          render:function(createElement){
            // return createElement('h1','render')
            return createElement(参数1,2,3)
        // 参数1 : {String | Object | Function} html标签名/组件名 必选
        // 2 : {Object} 与模板中  attribute 对应的数据对象 可选(主要是一些属性)
        // 3 : {String | Array}  子级虚拟节点 (VNodes) 
          }
        })
        export default {
          components:{
            vnVue
          }
        };
        
      • 选项-生命周期钩子

        • beforeCreate

          此阶段vue实例的基本结构已有

        • created阶段~beforeMount阶段

          .vue文件中的template标签 > render(createElement) > vue组件内部的template

          如果上述都没有,会从outerHtml中获取(可以在html文件中测试)

      • 选项-资源

        • directives: 包含 Vue 实例可用指令的哈希表。

          自定义指令

        • filter: 包含 Vue 实例可用过滤器的哈希表

          自定义过滤器

        • components: 包含 Vue 实例可用组件的哈希表

          Vue.component(/*全局注册,后面注册的组件及其子组件都可访问*/)

          component:{ /*局部注册*/ }

      • 选项--组合(交互,将组件联系起来)

        • parent : 类型:Vue instance

          this.$parent/$children 可以访问父组件(应急方法,优先使用props、emit)

        • extends : 注意并非 Vue.extend

          var com = {
            data(){
              return { msg : 'com' }}} 
          // 使用类似 mixin ,在外面定义一个对象,然后在组件中添加一项
          extends:com
          
        • provide / inject :

          provide:Object | () => Object

          inject:Array | { [key: string]: string | Symbol | Object }

          // 父组件,其中一项
          provide : {
            foo: 'bar'
          }
          // 子组件,类似 prop
          inject: ['foo'],
          
          </li> </ul> </li> </ul> </li> </ul> </li> <li class="instance"> <p>Vue 实例属性</p> <ul> <li id="InstanceProperties"> <p>Vue实例--属性</p> <ul> <li> <p>vm.$<strong style="font-size: 20px;">data</strong>:Vue 实例代理data对象里面的property的访问</p> </li> <li> <p>vm.$<strong style="font-size: 20px;">props</strong>:Vue 实例代理了对其 props 对象 property 的访问</p> </li> <li> <p>vm.$<strong style="font-size: 20px;">el</strong>:Vue 实例使用的根 DOM 元素,</p> </li> <li> <p>vm.$<strong style="font-size: 20px;">options</strong>:用于当前 Vue 实例的初始化选项,一个Vue 实例最初的一个框架,不包含挂载之后的东西</p> </li> <li> <p>vm.$<strong style="font-size: 20px;">refs</strong>:一个对象,持有注册过 ref attribute 的所有 DOM 元素和组件实例</p> </li> <li> <p>vm.$<strong style="font-size: 20px;">attrs</strong>:包含了父作用域中不作为 prop 被识别 (且获取) 的 attribute 绑定。可以通过 v-bind="$attrs" 传入内部组件</p> </li> <li> <p>vm.$<strong style="font-size: 20px;">listeners</strong>:包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。通过 v-on="$listeners" 传入内部组件</p> </li> </ul> </li> <li id="InstanceFunData"> <p>Vue实例--与数据有关的方法</p> <div>vm.$watch / vm.$set / vm.$delete</div> </li> <li id="InstanceFunEvent"> <p>Vue实例--与事件有关的方法</p> <div>vm.$on / vm.$once / vm.$off:移除事件 / vm.$emit</div> </li> <li id="InstanceFunLife"> <p>Vue实例--与生命周期有关的方法</p> <div>vm.$mount / vm.$nextTick / vm.$destroy</div> <div>vm.$forceUpdate:迫使 Vue 实例重新渲染。注意它仅仅影响实例本身和插入插槽内容的子组件,而不是所有子组件</div> </li> <li id="dircts"> <p>Vue实例--指令集</p> <div>v-html / v-show / v-if / v-else / v-else-if / v-for / v-on / v-bind / v-model / v-slot / v-once</div> <div>v-pre :不会再编译里面的东西,直接以字符串输出,提高编译速度`<span v-pre>{{ this will not be compiled }}</span>` </div> <div>v-cloak:保持元素关联直至替换实例准备完毕</div> </li> <li id="spcAttrs"> <p>Vue实例--特殊指令集</p> <div>key / ref / is :用于动态组件渲染</div> <div>v-pre :不会再编译里面的东西,直接以字符串输出,提高编译速度`<span v-pre>{{ this will not be compiled }}</span>` </div> <div>v-cloak:保持元素关联直至替换实例准备完毕</div> </li> </ul> </li> </ol> </body>
posted @ 2020-12-29 18:46  365/24/60  阅读(256)  评论(0编辑  收藏  举报