Vue 学习记录二

组件化:

全局组件:
1、创建组件构造器(template 只能有一个根元素)
var Profile = Vue.extend({
  template: "<div><p>标题</p><p>内容</p></div>"
})
2、注册已经创建好的组件
// 第一个参数:组件名称
// 第二个参数:组件构造器
Vue.component('my-component',Profile)
3、使用注册好的组件
<my-component></my-component>

创建组件的其他写法简写
// 1、直接将一个对象作为第二个参数,这时内部会自动创建组件构造器
Vue.component('my-component-2',{
  template: "<div><p>标题2</p><p>内容2</p></div>"
})

// 2、template 的内容写在 script 中
Vue.component('my-component-3',{
  template:"#info"
})
    <script id='info' type="text/html">
      <div>
        <div>标题3</div>
        <div>内容3</div>
      </div>
    </script>

//3、template 的内容写在 template 标签中
Vue.component('my-component-4',{
  template:"#info"
})
    <template id='info'>
      <div>
        <div>标题4</div>
        <div>内容4</div>
      </div>
    </template>

局部组件:
  // 自定义组件属性key
  components: {
    "my-component-5": {
      template: "#info",
    },
  },

动态组件

// v-bind:is='' 通过这种方式切换组件可以保存组件的状态
<!-- 失活的组件将会被缓存!-->
<keep-alive>
  <component v-bind:is="要展示的组件名称"></component>
</keep-alive>

父子组件

//首先弄两个组件
<template id="fater">
      <div>
        <p>我是你爹</p>
        <son></son>
      </div>
    </template>

    <template id="son">
      <div>
        <p>我是儿子</p>
      </div>
    </template>

// 注册组件
Vue.component('father',{
  template:'#fater',
  // father 组件里面存在子组件 son。
  components:{
    'son':{
      template:'#son',
    }
  }
})

// 父组件给子组件传数据
// 子组件添加 props 字段,弄个数组,接受的字段全写进去就好啦。
'son':{
      template:'#son',
      props:['name','age']
    }
//使用的地方,用 :name 就可以将参数传递过来
<son :name='name' :age='age'></son>

//父组件的方法传递给子组件
// 1、将父组件的方法 fatherFn,通过约定的事件名 sonclick,传递给子组件
<son :name='name' :age='age' @sonclick='fatherFn'></son>
// 2、子组件添加自己的事件,调用自己方法。
<p @click='sonFn'>点击事件</p>
// 3、子组件在自己的方法中,通过以下方式调用父组件。
        sonFn(){
          this.$emit('sonclick')
        }

//子组件给父组件传递参数
通过调用父组件方法,传递参数。
this.$emit('sonclick','哈哈哈哈')

*** 传递参数的时候不能用驼峰命名,用 - 连接,接受到的就是驼峰命名
*** 传递方法的时候不能用驼峰命名,只能用 - 连接

插槽

默认情况下是不能在组件中添加子元素的。要想添加就需要用到 slot。

匿名插槽
    <template id="son">
      <div>
        <div>头部</div>
        <!-- 如果将来不在组件中添加子元素,则显示下面的内容。否则将会替换这一块儿内容 -->
        <slot>默认数据</slot>
        <div>尾部</div>
      </div>
    </template>

具名插槽
    <template id="son">
      <div>
        <div>头部</div>
        <slot name='body'>默认数据</slot>
        <div>尾部</div>
      </div>
    </template>

        <son>
          <!-- 通过名字替换对应的 slot-->
          <div slot="body">啦啦啦啦啦啦</div>
        </son>

        <son>
          <!-- v-slot指令替换对应的 slot,v-slot指令只能用于 template 标签-->
          <template v-slot:body>
            <div>hahahahahah</div>
          </template>
        </son>

作用域插槽

    <template id="son">
      <div>
        <div>头部</div>
        <!-- v-bind:sonName="sonName" 将子组件的数据暴露给父组件 -->
        <slot v-bind:sonname="sonName">默认数据{{sonName}}</slot>
        <div>尾部</div>
      </div>
    </template>

        <son>
          <!-- 通过 obj 接收子组件的相关数据 -->
          <template slot-scope='obj'>
            <div>hahahahahah{{obj.sonname}}</div>
          </template>
        </son>

          <!-- v-slot: default(插槽名称,匿名插槽为default) obj(参数传递) -->
          <template v-slot:default='obj'>
            <div>hahahahahah{{obj.sonname}}</div>
          </template>

数据共享(Vuex)

// 1.创建 Vuex 对象
const store = new Vuex.Store({
  // 用于保存共享数据
  state:{
    msg:'我是共享数据'
  }
})

Vue.component('father', {
  template: '#fater',
  // 2.在父组件添加这个对象,子组件也可以进行使用
  store: store,
//...

    <template id="fater">
      <div>
        <!-- 3.通过以下格式使用就OK -->
        <p>{{this.$store.state.msg}}</p>
      </div>
    </template>


修改共享数据
// 创建 Vuex 对象
const store = new Vuex.Store({
  // 用于保存共享数据
  state:{
    msg:'我是共享数据',
    count: 0
  },
  // 修改共享数据要通过这个统一的方法,方便排查错误
  mutations:{
    mAdd(state){
      state.count = state.count + 1
    }
  }
})
//使用
this.$store.commit('mAdd')

//计算属性
// 创建 Vuex 对象
const store = new Vuex.Store({
  // 用于保存共享数据
  state:{
    msg:'我是共享数据',
  },
  // 和组件中的计算属性一样的(computed)
  getters:{
    format(state){
      return "格式化数据" + state.msg
    }
  }
})
//使用
<p>{{this.$store.getters.format}}</p>

Vue Router:

// 基本步骤
       // 1、定义组件
        const one = {
            template: '#one'
        }

        const two = {
            template: '#two'
        }
        // 2、定义路由规则
        const routes=[
            {path:'/one', component: one},
            {path:'/two', component: two},
        ]

        // 3、创建路由对象
        const router = new VueRouter({
            routes: routes
        })

        var app = new Vue({
            el: '#app',
            // 4、路由对象绑定Vue实例
            router:router,

            components: {
                one: one,
                two: two
            }
        })

        <!-- 5、路由匹配的组件渲染的位置 -->
        <a href="#/one">第一个页面</a>
        <a href="#/two">第二个页面</a>
        <router-view></router-view>

         // router-link  to:指定路由 tag:指定渲染的标签(默认是<a>)
        <router-link to='/one' tag='button'>第一个页面</router-link>>
        <router-link to='/two'>第二个页面</router-link>

// router-link 激活样式
        const router = new VueRouter({
            routes: routes,
            // 指定激活状态的 router-link 样式
            linkActiveClass:'wjj-link-active'
        })


//页面重定向
        const routes=[
            // 重定向根路径重定向到具体页面
            {path:'/', redirect: '/one'},
            {path:'/one', component: one},
            {path:'/two', component: two},
        ]

//参数传递
        //通过连接传递参数
        <router-link to='/one?name=zs&age=18' tag='button'>第一个页面</router-link>
        //获取参数
        this.$route.query

       //通过占位符来传递
        const routes=[
            {path:'/two/:name/:age', component: two},
        ]
        <router-link to='/two/zs/18' tag='button'>第一个页面</router-link>
        //获取参数
        this.$route.params

//嵌套路由
        const routes = [
            {
                path: '/one',
                component: one,
                children: [{
                    path: 'sub1',
                    component: subOne
                }, {
                    path: 'sub2',
                    component: subTwo
                }]
            },
        ]

//监听路由地址变化
        var app = new Vue({
            //省略代码
            data:{
                one:1
            },
            watch:{
                one:function(newValue, oldValue){

                },
                "$route.path":function(newValue, oldValue){

                }
            },
            //省略代码
        })

生命周期:

//Vue 创建期间的生命周期方法
            beforeCreate(){
                //仅仅代表 Vue 实例刚刚被创建,还没有初始化好 Vue 实例的数据和方法,因此不能访问 Vue 的数据和方法。
            },
            created(){
                //Vue 实例数据和方法已经初始化成功
            },
            beforeMount(){
                //编译好最终模板,但是没有将最终的模板渲染到界面上
            },
            mounted(){
                //完成最终的渲染,可以拿到最终的数据(界面上渲染的数据)
            },

            //Vue 运行期间的生命周期方法
            beforeUpdate(){
                //保存的数据发生变化就会调用,数据已经修改但是界面还没有同步
            },
            update(){
                //界面同步更新之后就会调用
            },

            //Vue 销毁期间的生命周期方法
            beforeDestroy(){
                //表示组件即将被销毁,最后一个可以获取 Vue 实例数据和方法的生命周期方法。
            },
            destroyed(){
                //当前组件已经被销毁
            }

Plugin 开发:

第一步:需要搞一个组件。
第二部:编写插件对应的JS文件。
其结构如下图:


插件结构图.png

插件的配置文件:

import Vue from 'vue'
import Toast from './Toast.vue'

export default {
    //  组件封装成为插件,必须提供一个 install 方法,在 install 中注册对应的组件。
    install:function(){
        Vue.component(Toast.name, Toast)
    }
}

我们为啥要把组件封装成插件呢?因为插件更方便进行扩展。
下面我们对插件进行如下修改。

import Toast from './Toast.vue'

export default {

  // 这个方法可以接收两个参数(Vue对象,参数)
  install: function (Vue, options) {
      //1、根据组件生成构造函数
      let Contructor = Vue.extend(Toast)

      //2、创建对应的实例对象
      let taostInstance = new Contructor()

      //3、随便创建一个标签
      let oDiv = document.createElement('div')

      //4、将标签添加到界面上
      document.body.appendChild(oDiv)

      //5、将创建好的对象挂载到创建好的元素上
      taostInstance.$mount(oDiv)

      //处理传入的参数(Toast 对象中已经添加 title, isShow 的属性)
      if (options){
          if (options.title){
            taostInstance.title = options.title
          }
      }

      //添加全局方法
      //显示toast
      Vue.showToast = function(){
        taostInstance.isShow = true
      }

      //隐藏toast
      Vue.hideToast = function(){
        taostInstance.isShow = false
      }

      //添加实例方法
      Vue.prototype.$toast =  function(isShow){
        taostInstance.isShow = isShow
      }
  }
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,214评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,307评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,543评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,221评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,224评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,007评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,313评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,956评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,441评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,925评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,018评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,685评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,234评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,240评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,464评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,467评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,762评论 2 345

推荐阅读更多精彩内容

  • 目标:了解Vue, 了解常用的Vue的一些工具,用vue cli搭建一个测试用例,在浏览器上面运行起来。 了解Vu...
    JASONGAOJS阅读 277评论 0 0
  • 题前话:之前接手了我们公司的半成品Vue项目,由于自己不是做网页前端的,自己初步看了下Vue相关东西,今天才算是把...
    临川慕容吹雪阅读 447评论 1 2
  • Vue安装 安装脚手架,使用全局安装就可以 安装完使用这个命令查看vue cli的版本 初始化一个Vue项目 然后...
    爱吃胡萝卜的小白兔阅读 171评论 0 0
  • 我之前一直使用的React,最近到了新公司,需要使用Vue,虽然之前自己写过一些小demo,但是缺乏系统的学习,且...
    grain先森阅读 5,886评论 0 8
  • 久违的晴天,家长会。 家长大会开好到教室时,离放学已经没多少时间了。班主任说已经安排了三个家长分享经验。 放学铃声...
    飘雪儿5阅读 7,493评论 16 22