vue2学习记录

vue2深度学习

一、 标签属性

  • v-ifv-show的区别

    • v-if每次切换都会重新删除或创建元素,切换性能消耗较高,频繁切换不建议使用v-if,推荐使用v-show
    • 使用v-if值为false的组件,在进入时,不被渲染创建,而使用v-show的组件,会进入时就将所有组件创建了
    • 切换时,不会触发组件生命周期(进入时已经创建了)
    • v-show不会进行dom节点的删除和增添。切换时,只是进行元素的样式显隐修改:display的样式值,初始化渲染消耗较高
    • 使用场景
      • v-if多用于显示隐藏有数据刷新情况 - 初次加载较快
      • v-show多用于固定显隐,如某些按钮的显示隐藏
  • v-bindv-model的区别

    • v-bind
      • 用来绑定数据和属性以及表达式
      • 只能实现数据的单向绑定,从M(data)自动绑定到V(页面),无法实现数据的双向绑定。
      • 形式:v-bind:某属性="数据", v-bind:可以简写为“:”
    • v-model仅适用于输入框,实现数据双向绑定,
    • 形式:v-model="数据"

    注:v-model在表单元素外使用不起作用

  • v-on

    • 事件的表达可简写为@后跟事件名

    • 可通过@事件.属性可以对事件进行一定控制

      • .stop:阻止事件冒泡
      • .prevent:阻止默认行为;例如a的跳转
      • .capture:添加事件的监听捕获
      • .self:只有事件发生在自己身上时才触发
      • .once:只触发一次事件,串联情况下,前边的控件效果也只有一次效果
    • .stop.self的区别:

      • .stop写在被阻止冒泡的事件身上,阻止该事件引发的所有冒泡
      • .self写在冒泡途中的某事件身上,阻止冒泡行为在自己身上的触发,仅当事件发生在自己身上时才被触发,冒泡在他身上无效,但是当触发它时,也会产生冒泡

一、 组件内属性

  • watch的使用

    • watch内监听的数据有两种书写格式

      1. 函数式:

        watch: {
          aaa(newName, oldName){
            // 第一个参数 : 新值
            // 第二个参数 : 旧值,之前的值
          }
          // 当值第一次绑定的时候,不会执行监听函数,只有值发生改变才会执行
          // 当监听一个对象时,不能监听其属性变化
        }
            
        
      2. 对象式: aaa: {}

          watch: {
            aaa: {
              handler(newName, oldName) {}, // 发生变化便执行的函数
              // 注意:属性值发生变化后,handler执行后获取的 newVal 值和 oldVal 值是一样的
              immediate: true, // immediate值为true时,会监听第一次绑定
              deep: true // 是否开启深度监听 - 优点:监听对象任意值发生变化都会触发执行 -- 缺点:所监听的对象有任意值变化,都会遍历监听所有属性,所有相对十分消耗性能
            } // 定向深度监听 - watch不能监听 aaa.b这样的值,但是可以将前面的那种写法改成字符串形式,即'aaa.b',如此便可以定向监听了
            // 示例
            'aaa.b': {}
          }
        
    • 路由监听

      data:{}
      watch:{
        '$route' (to, from){
          console.log(to, from)
          console.log('当监听到路由地址改变时,会触发,常用来监听复用同一个组件被多个不同路由复用的情况')
        }
      }
      
  • 计算属性和data的数据区别

    • data里边的数据只会在页面构建时进行获取,并将其变成静态数据,构建后边不会在改变了

    • computed计算属性里边的值,会时刻监督影响输出数值所涉及变量的变化,从而进行数据重渲染

    • 计算属性里边的值(不管是不是与输出值相关)发生变化,都会触发计算属性执行

      计算属性里边要获取路由信息,需要写成函数的return形式

    • vue的计算属性中仅包含对返回值的计算,不能用于修改data里边的数据(此问题发生在对象和数组中,引用类型,引者改权)

    • 计算属性小案例

      在echarts图表中,通过生命周期mounted来调用实现图表构建函数,而图表调用值仅发生在生命周期调用时的一次,即对计算属性里边的值仅调用一次,计算属性在没有被调用,便将数据缓存里,后边改变计算属性里边的相关数据,由于计算属性值没有被调用,所以数据不会刷新

  • 数据优先级

    props > methods > data > computed > watch

二、 路由

  • 路由模式:

    • hash模式: 带#
      • 路由跳转时,若找不到对应路由,不会发送请求
      • 打包自测时,使用hash,如果使用histor模式,会出现空白页问题
    • history模式: 不带#的 – 需要后端重定向
      • 路由跳转时,找不到对应路由,会将对应路由带在路径上,发送一次请求
  • 三种路由传参

    1. 字符串形式

      this.$router.push('/abc/' + this.aaa + '?k=' + this.bbb)
      
    2. 模板字符串

      this.$router.push(`/abc/${this.aaa}?k=${this.bbb}`)
      
    3. 对象传参

      this.$router.push({
        name: 'abc',
        params: {
          keyword: this.a
        },
        query: {
          k: '你好'
        }
      })
      
  • 路由传参误区

    1. 路由跳转传参时,对象的写法可以是name、path形式。但是,path不能与params传参一起使用(若一起使用,会报错)

    2. 配置路由时,使用params参数占位了但是跳转时却不传参数 - 此时路由路径会出现问题(路径参数消失 - 若有问号,则问好前的路由路径丢失), 若想解决,可以在params参数后面加一个问号

      {
        path: '/abb/:aaa?',
        name: 'abb',
        ...
      }
      
    3. 配置了params参数,传的是空值(空的字符串) - 路径会出现问题(同不传一样,路径消失),可以通过或运算,取undefined

      this.$router.push({
        name: 'aab',
        params: {
          keyword: '' || undefined,
          abc: '你好'
        }
      })
      
    4. 路由组件可以通过配置路由params参数及props来传props参数(只能传params参数),也可以直接配置路由的props项,将其配置为对象(传死值)来传递对应参数(额外传值),以及将props项写成函数的形式来传递参数(常用)

      // 路由文件
      // 形式一
      {
        path: '/aab/:abc',
        name: 'aab',
        props: true
      }
      // 使用
      this.$router.push({
        name: 'aab',
        params: '22'
      })
      // 形式二
      {
        path: '/aab',
        name: 'aab',
        props: {
          aa: '李大爷',
          bb: '王二狗'
        }
      }
      // 形式三
      {
        path: '/aab',
        name: 'aab',
        props: ($route) => {
          return {
            keywor: $route.params,
            ka: $route.query
          }
        }
      }
      
  • 路由编程式导航重复点击问题
    原因:编程式导航引入了promise,而promise需要传递一个成功或者失败的回调
    解决

    // 路由文件 - 对push进行二次封装
    let originPush = VueRouter.prototype.push // 将vueRouter原型对象的push存一份
    VueRouter.prototype.push = function(loction, resolve, reject) {
      if(resolve && reject) {
        originPush.call(this, loction, resolve, reject)
      } else {
         originPush.call(this, loction, ()=>{}, ()=>{})
      }
    }
    

导航守卫

  • 全局守卫

    • 全局前置守卫 beforeEach

        router.beforeEach((to, from, next) => {
       //  to: 代表去的路由
       //  form: 代表来着哪个路由
       //  next: 控制路由的跳转与取消  -- next()跳转  --- next(false)禁止跳转  ---next('要跳转的路径')   跳转到指定路径  ---若没有此选项,则不能进行路由页面跳转
      })
      
    • 全局后置守卫afterEach

  • 路由独享守卫

    • beforeEnter(to,form,next){}
    • 只有进入当前页面时才执行
    • 写于当前路由配置项中
  • 组件内守卫

    写于对应组件内,与生命周期同级
    组件守卫里面不能访问当前组件实例的属性和方法

    • beforeRouteEnter(to, from, next){} 进入组件前执行的函数
    • beforeRouteUpdate(to, from, next){} 组件复用时执行的守卫函数 – 有条件的,不好用
    • beforeRouteLeave(to, from, next){} 离开组件前执行的守卫函数 – 不使用next()的话,不能离开当前页面
  • 复用组件数据刷新

      // 原理 - 复用同一个组件,不会触发生命周期,但是依然会离开当前组件,然后再进入当前组件,这时,就可以再守卫那里做事情了
      beforeRouteEnter (to, from, next) {
        console.log('进入')
        next((vm) => { // 所有数据都在vm上
          vm.aaa = true
        })
      },
      beforeRouteLeave (to, from, next) {
        console.log('离开')
        this.aaa = false
        next()
      }
      思路:离开时使用 v-if = false 将组件关掉,进入时等于true使组件重新渲染
    
  • 页面路由跳转,滚动清零

    在路由配置文件里边加上scrollBehavior(to, from, saved){return {x:0,y:0}}

  • 路由拆分

    // 路由源文件 router > index.jsx
    import Vue from 'vue'
    import Router from 'vue-router'
    // 拆分路由引入
    import VOTE from './modules/vote' 
    
    Vue.use(Router)
    // 定义路由
    const routes = [
    
    ]
    const router = new Router({  
      mode: 'history',  
      routes,
      VOTE
    })
    export default router
    
    // 拆分的文件
    export default [      
      {        
        path: '/vote/index',        
        name: 'VoteIndex',        
        component: resolve => require(['@/view/vote/index'], resolve) 
      },    
      。。。  
    ]
    

三、 组件关系

  • 组件复用

    // 当复用组件是,可以通过watch来监控路由
    watch: {
      $route(to, from){
      
      }
    }
    
  • 组件传值

    • 父传子

      • 子组件通过props接收父组件传来的值

      • type 也可以是一个自定义构造器函数,使用 instanceof 检测。

      • 在 default 或 validator 函数里,诸如 data、computed 或 methods 等实例属性还无法使用

      • 单向数据流,子组件可以通过计算属性或者watcha来监听修改

        // 传值校验
        poprs: {
          a: Number, // 基础类型校验
          b: [String, Number], // 多种类型校验
          c: {
            type: String,
            required: true, // 必传
            default: 100 // 有默认值 - 一般与必传不一起使用
          },
          d: { // 对象或数组的使用
            type: [Object, Array],
            validator: (val) => { // 自定义校验
              return val > 10
            }
            default: () => {
              return {}
              // 或 return []
            }
          }
        }
        
    • 子传父

      子组件通过this.$emit("方法名", 数据)向父组件传值 – 本质是触发父组件的@方法名对 应的函数

    • 公共bus

      // gloublBus.js // 名字自定义
      import Vue from 'vue'
      export default new Vue()
      
      // 发送方
      import gloubs from '公共bus地址'
      // 某函数下
      gloubs.$emit('注册key名--注册车辆', data) // data为要穿的数据,可以是任何值吧
      
      // 使用方
      import gloubs from '公共bus地址'
      // 生命周期函数created()或 mounted()下
      gloubs.$on('使用对应的注册的车名', res => {})
      

      也可以

      // main.js中
      Vue.prototype.$bus = new Vue()
      
      // 发送
      this.$bus.$emit('xxx', data)
      // 接收
      this.$bus.$on('xxx', ()=>{})
      

四、 插槽

一共有三种插槽:匿名、具名、作用域
语法:必须写在引用组件内,子组件必须有<slot></slot>

  • 匿名插槽

     <!-- 父组件  -->
     <demon>
       写于父组件
     </demon>
     <!-- 子组件 -->
     <template>
       <slot></slot>
     </template>
    

    特点:可以直接接收引用处写在组件内的内容,并用其替换子组件的<slot></slot>,无需特殊操作
    缺点:单向广播,无差别替换 - 下边些几个<slot></slot>,将引用处内容重复几次

  • 具名插槽

    <!-- 父组件 -->
    <demon>
      <div slot="zhangsan"></div>
      <div slot="lisi"></div>
      <!-- 或者 -->
      <template slot="zhangsan"></template>
      <!-- 或者 - 注意:  v-slot 只能添加在 <template> 上,除非子组件是匿名插槽,此时可以直接写于组件上-->
      <template v-slot:zhangsan></template>
    </demon>
    <!-- 子组件 -->
    <template>
      <slot name="zhangsan"></slot>
      <slot name="lisi"></slot>
    </template>
    

    特点: 针对性放矢,对号入座式替换,可以根据需要对不同部分内容进行对应替换
    缺点: 也是单向

  • 作用域插槽

    <!-- 父组件 -->
    <demon>
      <!-- 第一种写法 -->
      <!-- 匿名写法 -->
      <div slot-scope="nihao">
       {{nihao}}
      </div>
      <!-- 或者 -->
      <!-- 具名写法 -->
      <div slot="zhangsan" slot-scope="nihao">
        {{nihao}}
      </div>
      <!-- 或者 -->
      <!-- 插槽写法  --  一般都这样写 -->
      <template slot="zhangsan" slot-scope="nihao">
        {{nihao}}
      </template>
      <!-- 第二种写法 -->
      <template v-slot:zhangsan="nihao">
        {{nihao}}
      </template>
    </demon>
    <!-- 子组件 -->
    <template>
      <slot name="zhangsan" :nida="msg"></slot>
    </template>
    <script>
      export default {
        data () {
          return {
            msg: '我是你大爷'
          }
        }
      }
    </script>
    
    • slot,slot-scope可以写在普通元素上,也可以写在template上,但是两个属性必须写在同一个元素标签上,不然无效 – 测试过,未写于同一标签,不显示内容
    • 特例: 在使用表格组件时,自封装表格,在引用组件上使用<el-table-column slot="setting"><template slot-scope="scope"></el-table-column>时,可以分开写 – 原因: 未知
    • v-slot替换了slot,slot-scope的分开写法,但是v-slot只能写于template标签上,不然报错
    • v-slot可以简写成’#',只能写于template标签中

五、 部分API学习

  • 全局 - API
    1. vue.directive(key, definition)

      • key {String}: 注册指令的名字 - 就一个字符串
      • definition {function | object}: 对注册指令的的定义 - 调用该指令对应执行的事件,可以是一个函数或是一个对象

      解释: 自定义指令
      范例 - 注册一个自定义指令v-focus

      // 全局注册自定义指令
          // 对象形式注册
          Vue.directive('focus', {
              // 只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
            bind: function () {}, 
            // 被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)
            inserted: function () {}, 
            // 所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。
            update: function () {}, 
            // 指令所在组件的 VNode 及其子 VNode 全部更新后调用。
            componentUpdated: function () {}, 
            // 只调用一次,指令与元素解绑时调用
            unbind: function () {}
          })
          // 函数形式注册 - 只会调用bind和update  - 触发相同行为
          Vue.directive('my-directive', function (el) {})
      // 局部注册自定义指令
          directives: {
            focus: { // 指令的定义
              inserted: function (el) {}
            }
          }
      // 使用示例 - <input v-focus:foo.a.b="message">
      // 参数:
      /**
      * 1、 el : 指令所绑定的元素,可以用来直接操作 DOM。
      * 2、 binding: 一个对象
      *     {
      *       name:指令名,不包括 v- 前缀。
      *       value:指令的绑定值  - 解析执行后的具体值
      *       oldValue:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用     - 无论值是否改变都可用
      *       expression:字符串形式的指令表达式 - 绑定值解析执行前的字符串
      *       arg:传给指令的参数 - 例如: v-focus:foo --> v-focus:[argument]="value"
      *       modifiers:一个包含修饰符的对象
      *       vnode:Vue 编译生成的虚拟节点
      *      }
      */
      
    2. vue.filter(key, definition)

      • key {String}: 过滤器的名字 - 就一个字符串
      • definition {function}: 过滤的函数

      解释: 过滤器
      范例
      注: 可串联多个 - 筛选后,再筛选

      <!-- 使用一 - 双花括号中 -->
      <div>{{ message | capitalize }}{{ message | capitalize }}</div>
      <!-- 使用二 -  v-bind 中 -->
      <div v-bind:id="message | capitalize"></div>
      
      // 全局注册过滤器
      Vue.filter('capitalize', function (value) {}) // 返回处理后的值
      // 局部注册过滤器
      filters: {
        capitalize: function (value) {}
      }
      
    3. vue.mixin({}) – 混入方法

      • 作用:给vue添加一些公共的方法和数据
      • 混入的生命周期高于原生的生命周期

五、 项目配置

  • 环境变量配置

    1. 开发环境: 根目录下创建.env.development

        VUE_APP_ENV = 'dev'
        VUE_APP_BASH_API = '基础路径' # 必须以VUE_APP开头
      
    2. 生产环境: 根目录下创建.env.production

        VUE_APP_ENV = 'pro'
        VUE_APP_BASH_API = '基础路径' # 必须以VUE_APP开头
      
  • 环境变量使用

      // 使用判断
      process.env.VUE_APP_ENV  // 判断这个的值,取对应地址
    

六、 特殊语法

  • .sync学习

    本质:是一个语法糖,简化了父子传值(具体来讲,是简化父组件传值写法)。
    效果:不用父组件写自定义监听事件,便可以使子组件修改父组件的值

    • 格式:子组件传递给父组件值的格式:this.$emit(‘update:aaa’,值)
      • update+冒号是必须写的,后面跟的 aaa 是父组件传来的值的名称
      • 第二个便是传递给父组件的值
    • .sync使用示例

       <!-- 父组件传值变动写法 -->
       <组件名 :aaa.sync="bcc"/>
       <!-- 子组件返回值变动写法 -->
       <script>
         方法名() {
            this.$emit('update:.sync前边的值,其实也就是对应的方法',)
         }
       </script>
       
      
      • 原型:

        <text-document
          v-bind:title="doc.title"
          v-on:update:title="doc.title = $event"
        ></text-document>
        
      • 简化后:

        <text-document :title.sync="doc"></text-document>
        

        总体简化了一个v-on及对应的监听事件

      • 子组件里边要做改变

        // 原来的写法
         this.$emit('事件名',)
        //  现在的写法
         this.$emit('update:.sync前边的值,其实也就是对应的方法',)
        
          示例:
          {
            this.$emit('update:title', 123)
          }
        
        
  • this.$nextTick()作用及用法

    • 作用:用于获取vue更新之后的dom
    • 确保数据更新视图之后才执行(数据数据变了,DOM数据也变化后)
    • 属异步,可以理解为一个定时器
    • vue中使用的都是虚拟DOM,当对页面进行数据修改时,同步操作是获取不到DOM元素的内容的。因为虚拟DOM到真实的DOM是需要时间的,大型项目约在17~20ms之间。
    • 使用场景:当你想要在修改修改数据之后,马上操作数据影响的DOM
  • ref

    • vue中获取dom的方法
    • 可以通过ref来获取子组件内的方法或数据

七、 vuex

  • 使用vuex的好处
    • 能够在vuex中集中管理共享数据,易于开发和后期维护
    • 能够高效的实现组件之间的数据共享,提高开发效率
    • 存储在vuex中的数据都是响应式,能够实时与各个页面保持同步

vuex对外只认store – 在全局中。
即: 在main.js中导出时,必须是store此时可以在this里面找到$store属性,若是其他的,则在全局中找不到你所公布的那个vuex属性,且也没有$store

  • 在main.js中错误的vuex导出

    // 引入
    import Vue from 'vue'
    import abcc from './自定义路径/vuex' // vuex那个文件名可以随意取名,无所谓
    // 导出
    new Vue({
      abcc,
      render: h => h(App)
    }).$mount('#app')
    

    这里边的abcc是随便取的vuex导入名,可以认为他可代替任何不是store的名字

    这样写的结果是在全局中找不到vuex属性,即你即找不到*$store*也找不到aabc这个属性

    伴随错误:

    Error in render: “TypeError: Cannot read property ‘state’ of undefined” found in 文件地址

  • 正确引入

    // 引入
    import Vue from 'vue'
    import store from './自定义路径/vuex' // vuex那个文件名可以随意取名,无所谓
    // 引入的名称发生了变化
    // 导出
    new Vue({
      store,
      render: h => h(App)
    }).$mount('#app')
    
    

    此时vuex使用便正常了

  • vuex 传参

  • vuex只能传递一个参数,若要传递多个参数,则可以以对象或者组织的形式传入

  • vuex之grtters

grtters中的数据,在没有使用的时候,是不会请求的

  • 使用

    1. state的使用

      1. 在state中,写入共享属性及值

      2. 在需要的地方通过import { mapState } from 'vuex'的方式引入

      3. 引入后,在计算属性computed中对数据进行导入使用:

        computed: {
           ...mapState(['对应state中的数据'])
        }
        
      4. 在其他组件中,也可以通过this.$store.state.要访问的数据名字来访问相应数据

    2. 数据操作 - 数据修改–方法引用:

      错误示例:可以通过对"this. s t o r e . s t a t e . 要访问的数据名字 " 数据进行改变达到对同步数据进行改变,当项目大了,不利于维护正确示例:通过对 m u t a t i s 中定义函数,用以数据改变,在通过 t h i s . store.state.要访问的数据名字"数据进行改变达到对同步数据进行改变,当项目大了,不利于维护 正确示例:通过对mutatis中定义函数,用以数据改变,在通过this. store.state.要访问的数据名字"数据进行改变达到对同步数据进行改变,当项目大了,不利于维护正确示例:通过对mutatis中定义函数,用以数据改变,在通过this.store.commit(‘函数名’, ‘参数一’)来调用对于函数

      • 也可以使用导入式引入

      • 在需要使用方法的地方通过import { mapState, mapMtations } from 'vuex'的方式引入

      • 在组件方法里边通过使用...mapMutations(['方法名'])

        methods:{
          ...mapMutations(['方法名']), // 建议写在第一的位置,便于查找其他方法
        }
        
      • 后边调用时,可以通过this.方法名(参数)调用对应方法

      • 想要调用actions中的函数,需要通过this.$store.dispatch(‘函数名’)

    3. 同步异步:

      • 在mutations中写异步代码,效果可以在页面显示,但是违反规则,故不要再mutations函数中共湖南执行异步操作

      • 异步操作中,action无法直接操作state中的数据,需要调用间接调用mutations中的函数来执行修改

        abc(context){
        context.commit('mutations中的某个函数')
        }
        
        • gitter可以理解为对state中的数据进行加工形成新的数据
        • getter使用:可以通过"this.$sotore.getters.名称"来调用getter中的函数
          也可以通过导入的方式将getter中的数据加载到相应组件
          impor { mapGetters } from ‘vuex’// 数据引入
          再计算属性里边导入:computed: {
          …mapGetters([‘对应getter中的数据’])
          }
          getter中的数据需要return出来 --即有返回值

扩展

  • 在vue中使用 require() 来获取"本地"静态图片 – require() - 文件加载

    原因:vue在DOM中直接引入的图片会被转为 base64 格式,使用变量引入的话,图片不会转为 base64 格式,因此引入的图片不会正常显示,使用require(‘./aaa.png’) 可以将引入的图片转为base64
    :在标签中直接写上图片路径,路径会转为 base64,但是如果通过变量设置静态路径,则不会转为 base64,仍然显示变量值对应的路径,故图片无法正常显示

  • 读取文件夹下的文件名 require.context('../abc',false,/.\.js$/)

    参数一:文件夹的路径
    参数二:是否查询子文件夹
    参数三: 要匹配的文件后缀 – 是个正则表达式

    const file = require.context('../abc',false,/.\.js$/)
    console.log(file.keys()) // 通过keys()可以打印文件下的所有文件名 - 构成一个文件名数组
    
  • 组件的切换过渡

    • 将过渡事件写在vue定义的一个"域"内:<transition></transition>

    • 通过给<transition>里边加name="my"属性可以将相应的阶段属性的v-改成my-enter的样式

    • 在样式标签里边进行定义样式:

      • v-enter:时间点-进入之前/元素初始状态/还没进入页面
      • v-leave-to:时间点-动画离开后/离开的终止状态/动画已经结束
      • v-enter-active:入场时间段
      • v-leave-active:离场时间段
    • 在离开或进入的时间段里边写动画属性便可以产生动画效果

    // 例:
    .v-leave-active{
      transition: all 0.8s ease;
    }
    
    // 在给组件设置动画时,对它的外部(外置部位)加一个过渡组件包裹
    <transition mode="过渡效果">
      <component :is="key"/>
    </transition>
    
  • 定义指令

    • 定义全局指令:Vue.directive( "指令名称",{含有相关函数的对象})

      • 指令名称定义时前边不加v-前缀,但是,调用/使用时名称前边必须加v-前缀,以此进行调用。
      • 每个函数的第一个参数都是el,表示被绑定的那个元素,是一个原生的js对象
      • 第二个参数是一个对象,包含指令名(name)绑定值(value/expression)
      Vue.directive( "指令名称", { 
        bind:function (el) {} // 每当指令绑定到元素上时,会立即执行bind函数,只执行一次。
        inserted:function (el) {} // 元素插入到dom中时会执行inserted函数,仅执行一次
        updated:function (el) {}// 当VNode更新时执行updated,可能会触发多次
      })
      
    • 定义私有指令:

    // 与data同级
      directives:{
        "指令名称": {
        // 对象加相应函数
        }
        // 简写:
        '指令名'function (el,binding) {
        // 执行的函数
        // 等同于把事件绑定在bind和update上
        }
        // 例如:
        "color":function (el, binding) {
          el.style.color = parseInt(binding.value)+"px"
        }
      }
    
  • 组件创建

    • 全局创建(注册)

      Vue.component('组件名',{
          template:'<h3>我是你的组件</h3>'
        })
      // 简写时,将Vue.extend()省略,直接换成对象,包含一个template属性名。
      
      
    • 外联创建

      <template id="对应的id名">
        <div> 里边写正常的HTML的内容,但要被一个根元素包裹 </div>
      </template>
      
      Vue.component('组件名', {
          template:'#id名'
        })
      
    • 私有组件创建

      components:{
        "组件名"{
          template:"<div>组件内容</div>"
        }
        sss:{
          template:"id名"
        }
      }
      
    • 组件的data

      • 必须是一个方法,且必须是返回一个对象
      • 使用方法和全局data一样,但只能在自己的组件中使用。
      Vue.component('组件名',{
          template:'<h3>我是你大爷{{msg}}</h3>',
          data: function () {
            return{
              msg : 'nia'
            }
          }
        })
      
    • data方法的return{}和外联对象

      • 使用外联的对象,在同一个组件多次调用时,会发生所有组件互相影响的效果(有相应变化)
      • 原因:对象地址相同
      • 使用{}的好处:每次创建组件时,各自的对象分开,互不影响

对template属性值的介绍:
不论哪种创建方式创建的组件,组件的template属性指向的内容模板(值)
有且仅有唯一一个根元素 — 即一个根div或什么的元素,无并接属性。

  • SPA(单页面应用)缺点
    • SEO优化不好(SEO是基于多页面应用的)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值