Vue学习笔记---------Vue2

Vue学习笔记---------Vue2

1. Hello,world!

  1. 插值语法: 用 {{ xxx }} 插入一个值 ,该值在data中自定义内容.
<body>

    <div id="app">
        <h1> 插值语法: </h1>
        <h1> {{ info }} </h1>
    </div>

</body>

<script type="text/javascript">
    new Vue({
        el:'#app',   // 绑定Vue实例  第二种写法: Vue实例.$mount('#app')
        data:{
            info: 'Hello,World!',
        }
    })
</script>
  1. 指令语法: 在标签内使用vue指令解析标签包括标签属性,绑定事件等
<body>

    <div id="app">
        <h1> 指令语法: </h1>
        <a v-bind:href="url">地址</a>
    </div>

</body>

<script type="text/javascript">
    new Vue({
        el:'#app',
        data:{
            url: 'www.bilibili.com'
        }
    })
</script>

2. 点击事件

​ 点击事件需要Vue的指令语法: v-on:click=“method” 或是简写 @click=“method”.method是点击执行的具体函数名,该函数在下方Vue实例中的 methods 中定义.在 methods 中 this 指的是Vue实例.

<body>
    <div id="root">
        <button v-on:click="clickFun">点击事件</button>
    </div>
</body>
<script TYPE="text/javascript">
    new Vue({
        el:'#root',
        methods:{
            clickFun(){
                alert("点击事件!")
            }
        }
    })
</script>

2.1 事件修饰符

  • prevent : 阻止默认事件
  • stop : 阻止冒泡事件
  • once : 事件只触发一次
  • capture : 使方法在捕获阶段就执行
  • self : 只有当调用该方法时 event.target 是当前元素才会执行方法
  • passive : 优先执行事件默认方法,无需等待事件回调函数的执行

2.2 键盘事件

​ 使用指令语法@keyup.xxx 或是 @keydow.xxx 可以绑定键盘事件.


3. 计算属性

​ 计算属性和 data 类似也是属性,但是计算属性在computed中定义.

​ 计算属性有缓存,只有初次读取计算属性时 get() 方法才会被调用,或者计算属性所依赖的值发生变化时 ( 与watch效果类似 ) 才会被调用,并不是每次读取计算属性的值使都会进行计算.

<script TYPE="text/javascript">
    new Vue({
        el:'#root',
        data:{
            firstName:'张',
            lastName:'三'
        },
        computed:{
            fullName(){
                return this.firstName + '-' + this.lastName
            }
        }
    })
</script>

4. 监视属性

​ 使用 watch 来监视目标, handler 函数当被监视的值发生改变时被调用

<script TYPE="text/javascript">
    new Vue({
        el:'#root',
        data:{
            isWin: false,
        },
        watch:{
            isWin(newValue,oldValue){
                console.log(newValue,oldValue)
            }
        }
    })
</script>

4.1 深度监视

​ 通过deep配置是否开启深度监视, watch 默认是不能监视被监视对象内部值的变化,通过immediate配置让被监视属性的执行体直接执行一次.

deep:true,

5. 条件渲染

​ 使用指令语法 v-if 或 v-show 可以条件的渲染指定元素,其区别在于前者为 false 时结构中也不存在,后者在结构中一直存在,只是显示与不显示的区别.所以在需要频繁切换显示与否的情况下用v-show更合适.

<body>
    <div id="root">
        <div v-show="isShow">能看到我吗?</div>
        <button @click="changeShow">点我试试</button>
    </div>
</body>
<body>
    <div id="root">
        <div v-if="isShow">能看到我吗?</div>
        <button @click="changeShow">点我试试</button>
    </div>
</body>

6. 循环指令

​ 可以使用指令语法 v-for 循环遍历元素.

<body>
    <div id="root">
        <ul>
            <li v-for="p in person">
                姓名: {{p.name}};
                年龄: {{p.age}};
            </li>
        </ul>
    </div>
</body>
<script TYPE="text/javascript">
    new Vue({
        el:'#root',
        data:{
            person:[
                {name:'张三',age:18},
                {name:'李四',age:19}
            ]
        },
    })
</script>

​ 建议在使用 v-for 遍历时同时使用 key 以保证被遍历元素的唯一性.

<body>
    <div id="root">
        <ul>
            <li v-for="(p,index) in person" :key="index">
                姓名: {{p.name}};
                年龄: {{p.age}};
            </li>
        </ul>
    </div>
</body>
<script TYPE="text/javascript">
    new Vue({
        el:'#root',
        data:{
            person:[
                {name:'张三',age:18},
                {name:'李四',age:19}
            ]
        },
    })
</script>

7. Vue的生命周期

​ 生命周期又叫生命周期回调函数,就是钩子函数,钩子函数名是固定的,调用时机也是固定的.只有函数体可以自定义,然后会在固定时间点被执行.

  • beforeCreate 此时未进行数据代理,无法通过vue实例获取data中的内容.
  • Created 此时数据代理,数据监测已完成
  • beforeMount 此时页面呈现的是虚拟DOM,此时对DOM的所有操作最终都不会生效.
  • mounted 此时已经编译成为了真实DOM,初始化过程结束.
  • beforeUpdate 当数据更新时会被调用,此时数据是更新后的数据,但未被渲染,即页面与数据不同步,页面是旧页面.
  • Updated 数据已经更新,且页面也是新的.
  • beforeDestroy data,method等都还存在,即将销毁.但是无法对数据进行修改.
  • destroyed vue实例被销毁

8. 组件化编程

组件:实现页面局部功能的代码和资源的集合.提高代码的复用率.

使用组件的三个步骤:

  1. 创建组件 : 使用Vue.extend()创建组件,为了保证组件的复用,组件中data必须写成函数式,使用template配置组件页面结构.
  2. 注册组件 : 局部注册: new Vue实例时使用components进行注册;全局注册: Vue.component(‘组件名’,组件).
  3. 使用组件 : 通过组件名标签使用.
    // 1. 创建组件
    <script TYPE="text/javascript">
        const people = Vue.extend({
            template:`
                <div>
                    <h1>你好,{{name}}!</h1>
                </div>
            `,
            data(){
                return{
                    name:'王也'
                }
            }
        })
    </script>
    // 2. 注册组件  
    <script TYPE="text/javascript">
        new Vue({
            el:'#root',
            // 键值对:key:组件名,value:创建的组件变量名
            components:{
                people,people
            }
        })
    </script>
    // 3. 使用组件   
		<body>
        <div id="root">
            <people></people>
        </div>
    </body>

9. Vue脚手架

  1. 编写vue组件,在components包下创建 组件名.vue 文件.
<template>
  <div>
    <h1>武当{{name}},拜见老天师!</h1>
  </div>
</template>

<script>
export default {
  name: 'WuDangPeople',
  data(){
    return{
      name:'王也'
    }
  }
}
</script>
  1. 注册并使用组件,在src目录下创建 App.vue 文件.App组件统管其他所有组件.
<template>
  <div>
    <wu-dang-people></wu-dang-people>
  </div>
</template>

<script>
import WuDangPeople from './components/People'

export default {
  name: 'App',
  components: {
    WuDangPeople
  }
}
</script>
  1. 创建Vue实例,并绑定App容器,在src目录下创建 main.js 文件.
import Vue from 'vue'
import App from './App.vue'

Vue.config.productionTip = false

new Vue({
  el:'#app',
  render: h => h(App),
})
  1. 编写主页面,在主页面放置APP组件 ( App组件内部嵌套使用着其他组件 ).在public目录下创建 index.html 文件.
<!DOCTYPE html>
<html lang="">
  <head>

  </head>
  <body>
    <div id="app"></div>
  </body>
</html>

10. 组件间传递值

10.1 props

​ props可以让组件接收从外部传进来的值.

  1. 在接收值的组件内部配置props
<template>
  <div>
    <h1>{{dept}}{{name}},拜见老天师!</h1> <br/>
  </div>
</template>

<script>
export default {
  name: "People",
  props:{
    dept:{
      type:String,
      required: true
    },
    name:{
      type:String,
      required: true
    },
  },
  data(){
    return{
      newAge:this.age
    }
  },
}
</script>
  1. 在调用组件时进行传值
<template>
  <div>
    <People dept="武当" name="王也" :age="20"></People>
    <People dept="哪都通" name="张楚岚" :age="23"></People>
  </div>
</template>

注意: vue底层会监视通过props传进组件的值,如果进行修改就会发出警告.

10.2 组件自定义事件

10.2.1 通过 ref 绑定

​ 通过 ref 绑定组件后,可以通过 $refs 获取到这个组件.当 People 这个组件的 ’ getName ’ 事件被触发时,就会调用 showName()方法.

<template>
  <div>
    <People ref="people"></People>
  </div>
</template>

<script>
import People from './components/People'

export default {
  name: "App",
  components:{People},
  methods:{
    showName(name){
      alert(name)
    }
  },
  mounted() {
    this.$refs.people.$on('getName',this.showName)
  },
}
</script>

​ 在组件内通过 $emit 可以触发事件.同时可以将值传递出去.

<template>
  <div>
    <h1>{{dept}}{{name}},拜见老天师!</h1> <br/>
    <button @click="btn">who are you?</button>
  </div>
</template>

<script>
export default {
  name: "WuDangPeople",
  data(){
    return{
      dept: '武当',
      name: '王也'
    }
  },
  methods:{
    btn(){
      this.$emit('getName',this.name)
    }
  }
}
</script>
10.2.2 通过v-on 绑定
<template>
  <div>
    // 当'getName'事件被触发时,就会调用 showName 方法.
    <People @getName="showName"></People>
  </div>
</template>

<script>
import People from './components/People'

export default {
  name: "App",
  components:{People},
  methods:{
    showName(name){
      alert(name)
    }
  },
}
</script>

通过 $off 可以解绑事件


11. mixin

​ 通过配置mixin可以提取多个组件中相同的配置项,在src目录下创建 xxx.js 文件.编写可提取的公共配置项.

export const mixin = {
    methods:{
        show(){
            alert("罗天大醮")
        }
    }
}

​ 在组件内配置mixin配置项引入并使用共同的配置.( show方法在mixin.js文件中定义,组件内引入后就可以使用 )

<template>
  <div>
    <button @click="show">点我了解比赛名称</button>
  </div>
</template>
<script>
import {mixin} from '../mixin'
export default {
  name: "People",
  mixins:[mixin]
}
</script>

12. 全局事件总线

​ 除了在父子组件中传值,还可以通过全局事件总线在同级组件间传值.

​ 在 new Vue 实例时,给Vue实例的原型对象添加 b u s , 这个 bus ,这个 bus,这个bus全局可见,所有组件都可以找到,那么就可以通过这个$bus在多个组件中建立联系,互相传值.

  1. 在 main.js 文件中创建 Vue 实例的时候利用钩子 beforeCreate 创建全局事件总线.
new Vue({
    el:'#app',
    render: h => h(App),
    beforeCreate() {
        // 创建全局事件总线
        Vue.prototype.$bus = this
    }
})
  1. 在需要接收值的组件里绑定自定义事件( 将接收值的组件与 $bus 绑定 ),记得在组件销毁前解绑时间.
<script>
export default {
  name: "AnotherComponent",
  methods:{

  },
  mounted() {
    this.$bus.$on("giveName",(name)=>{
      alert('我在Another组件里,Another组件已经收到值了,名字是: ' + name)
    })
  },
  beforeDestroy() {
    this.$bus.$off('giveName')
  }
}
</script>
  1. 在需要传值的组件里设置事件触发,并传值.
<template>
  <div>
    <button @click="give">我是People组件的里的按钮,点我给Another组件传值</button>
  </div>
</template>

<script>
export default {
  name: "WuDangPeople",
  data(){
    return{
      name: '王也'
    }
  },
  methods:{
    give(){
      this.$bus.$emit('giveName',this.name)
    }
  }
}
</script>

这样就通过Vue实例的原型对象身上的$bus实现了任意组件间的通信.


13. 插槽

13.1 默认插槽

在需要插入不确定元素的地方保留一个占位 <slot></slot> ,当有需要填充的元素出现时,就会插入该插槽.

<template>
  <div>
    <h3>我喜欢的游戏</h3>
    <slot>当没有元素需要插入本插槽时,显示本默认内容</slot>  // 提前占位,设置插槽位置
  </div>
</template>

<script>
  export default {
    name: "MyGames"
	}
</script>

在使用组件时,组件内部出现需要插入的元素就会找到slot标签位置并插入.

<template>
  <div>
    <my-games>
      // 该元素即为需要插入的元素,vue会自动找到插槽位置插入该元素.
      <li v-for="game in games" :key="game"> {{game}} </li>
    </my-games>
  </div>
</template>

<script>
import MyGames from './components/Games'
export default {
  name: "App",
  components: {MyGames},
  data(){
    return{
      games:['盗贼之海','命运2','Apex','Valorant','英雄联盟','WallPaper']
    }
  }
}
</script>

13.2 具名插槽

当出现多个插槽位置的时候,给插槽配置name属性,在插入的的时候可以寻找对应属性的插槽插入.

<template>
  <div>
    <my-games>
      <h1 slot="first">我就是个臭打游戏的</h1>
      <li slot="second" v-for="game in games" :key="game"> {{game}} </li>
    </my-games>
  </div>
<template>
  <div>
    <h3>我喜欢的游戏</h3>
    <slot name="first">我是第一个插槽</slot>
    <slot name="second">我是第二个插槽</slot>
  </div>
</template>

13.3 作用域插槽

当插槽的使用者需要用到插槽所在的组件内的数据时,可以通过配置 scope ,将数据从插槽所在的组件传到插槽使用者手里. scope属性拿到的是一个对象,其包含定义插槽时标签体内配置的属性.

<template>
  <div>
    <h3>我喜欢的游戏</h3>
    <slot :games="games">我是第二个插槽</slot>
  </div>
</template>

<script>
export default {
  name: "MyGames",
  data(){
    return{
      games:['盗贼之海','命运2','Apex','Valorant','英雄联盟','WallPaper']
    }
  }
}
</script>
<template>
  <div>
    <my-games>
      // gamesInfo拿到的是一个对象,内容是 games.
      <template scope="gamesInfo">
        <li v-for="game in gamesInfo.games" :key="game">{{game}}</li>
      </template>
    </my-games>
  </div>
</template>

<script>
import MyGames from './components/Games'
export default {
  name: "App",
  components: {MyGames},
}
</script>

14. 路由

14.1 简单路由

​ 在单页面应用中,根据Vue Router的配置,实现多组件切换展示,而不用刷新或打开新页面.

  1. 编写路由目标组件( 一般把通过路由展示的组件放在src目录下的pages包下 )
<template>
  <div>
    <h1>我是斩月,你的斩魄刀,黑崎一护!</h1>
  </div>
</template>
<template>
  <div>
    <h1>我是冰轮丸,你的斩魄刀,日番谷冬狮郎!</h1>
  </div>
</template>
  1. 在 src 下创建 router 包,包中创建 index.js 文件,编写路由配置.
  • 引入 VueRouter 插件,并且 Vue.use 这个插件.
  • 引入路由目标组件
  • new VueRouter: 配置routes,配置路径和目标组件.
import VueRouter from "vue-router";
import Vue from "vue";
import Black from "@/components/Black";
import Ice from "@/components/Ice";

Vue.use(VueRouter)

export default new VueRouter({
    routes:[
        {
            path:'/black',
            component:Black
        },
        {
            path:'/ice',
            component:Ice
        }
    ]
})
  1. 在 main.js 文件中引入路由插件并且Vue.use ,在Vue实例中配置route.
import Vue from 'vue'
import App from './App'
import VueRouter from "vue-router";
import router from './router/index'

Vue.use(VueRouter)

Vue.config.productionTip = false

new Vue({
    el:'#app',
    render: h => h(App),
    router
})
  1. 在 App.vue 文件中,使用<router-link to="/black"> xxx </router-link>编写路由起点,以及使用<router-view></router-view>占位路由目标组件的展示布局.路由布标组件将在<router-view></router-view>处展示.

注意 : 在使用<router-link>时,可以配置replace属性,以改变浏览器的历史记录模式,replace模式下,在路由新的组件时,浏览器添加新的历史记录的同时会干掉上一个记录,也就是在路由的过程中始终保持只有一条历史记录.

<template>
  <div>
    <div>
      <router-link replace to="/black">黑崎一护</router-link>
      <router-link replace to="/ice">日番谷冬狮郎</router-link>
    </div>
    <div>
      <router-view></router-view>
    </div>
  </div>
</template>

14.2 嵌套路由

  1. 在router路径下的index.js文件中配置多级路由.在父级路由配置下配置children,在其中嵌套子级路由.
export default new VueRouter({
    routes:[
        {
            path:'/black',
            component:Black
        },
        {
            path:'/ice',
            component:Ice,
            children:[
                {
                    path:'super',
                    component:Super
                }
            ]
        }
    ]
})
  1. 在父级组件中编写子级组件的路由布局.依旧是<router-link><router-view>.

注意: 在多级路由中,父级组件中使用<router-link>链接子组件时, to 属性的的路径要带上父级路径.

<template>
  <div>
    <h1>我是冰轮丸,你的斩魄刀,日番谷冬狮郎!</h1>
    <div>
      <router-link to="/ice/super">卍解</router-link>
    </div>
    <div>
      <router-view></router-view>
    </div>
  </div>
</template>
  1. 编写子级组件.
<template>
  <div>
    <h1>端坐于霜天吧,冰轮丸!</h1>
  </div>
</template>

14.3 路由传参

14.3.1 通过query传参
  1. 在使用<router-link>的时候,通过配置 query 可以传递参数.
<template>
  <div>
    <h1>护廷十三队</h1>
    <ul>
      <li v-for="n in name" :key="n.id">
        <router-link :to="{
          path:'/number',
          query:{
            id:n.id,
            name:n.name,
            sword:n.sword
          }
        }">{{n.name}}</router-link>
      </li>
    </ul>
  </div>
</template>

<script>
export default {
  // eslint-disable-next-line vue/multi-word-component-names
  name: "Title",
  data(){
    return{
      name:[
        {
          id:'六番队队长',
          name:'朽木白哉',
          sword:'千本樱'
        },
        {
          id:'十番队队长',
          name:'日番谷冬狮郎',
          sword:'冰轮丸'
        },
        {
          id:'一番队总队长',
          name:'山本元柳斋重国',
          sword:'流刃若火'
        }
      ]
    }
  }
}
</script>
  1. 在路由目标组件内可以通过 $route.query.xxx 来接收参数.
<template>
    <ul>
      <li>姓名:{{$route.query.name}}</li>
      <li>职称:{{$route.query.id}}</li>
      <li>斩魄刀:{{$route.query.sword}}</li>
    </ul>
</template>

也可以通过params传参,写法和query大致一样

14.3.2 通过props传
  1. 传递还是一样的写法,<router-link>中配置path和query,只不过多了一步就是在路由配置文件中配置props.
export default new VueRouter({
    routes:[
        {
            name:'number',
            path:'/number',
            component:Detail,
            props($route){
                return{
                    id:$route.query.id,
                    name:$route.query.name,
                    sword:$route.query.sword
                }
            }
        }
    ]
})
  1. 接收时即可直接接收,不用在组件中使用$route.query.xxx了.
<template>
    <ul>
      <li>姓名:{{name}}</li>
      <li>职称:{{id}}</li>
      <li>斩魄刀:{{sword}}</li>
    </ul>
</template>

<script>
export default {
  name: "detail",
  props:['id','name','sword']
}
</script>

14.4 命名路由

  1. 可以再路由配置文件中给路由起个名字
export default new VueRouter({
    routes:[
        {
            name:'number',
            path:'/number',
            component:Detail
        }
    ]
})

2.在调用路由的时候就可以不用写请求路径,直接写名字,在多级路由中可以简化代码.

<router-link :to="{
	name:'number',
	query:{
		id:n.id,
    name:n.name,
    sword:n.sword
  }
}">
  {{n.name}}
</router-link>
14.5 编程式路由
  1. 写成函数去触发路由, $router.push .
<button @click="banKai(n)">卍解</button>
<script>
export default {
  name: "Title",
  methods:{
    banKai(n){
      this.$router.push({
        name:'number',
        query:{
          banKai:n.banKai,
        }
      })
    }
  }
}
</script>

14.6 两个钩子函数

  • activated 被路由的组件激活时触发,

  • Deactivated 离开该组件时失活,

    <keep-alive>标签配合使用.

14.7 路由守卫

  1. 全局前置: 在路由触发时会调用,路由切换之前会调用.

    Router.beforeEach((to,from,next) => {
      xxxxx;
      xxx;
    })
    
  • to:目标组件;
  • from:出发点;
  • next: 拦截放行;

可以对next进行条件控制已达到权限拦截的效果.

  1. 全局后置: 在路由触发时会调用,路由切换之后会调用.
Router.afterEach((to,from) => {
  xxxxx;
  xxx;
})
  1. 独享路由守卫: 只控制单个路由组件的守卫

​ 在路由配置文件中,单个路由组件配置对象中,配置beforeEnter ,就可以实现对单个路由组件的路由拦截控制.

routes:[
        {
            name:'number',
            path:'/number',
            component:Detail,
            props($route){
                return{
                    id:$route.query.id,
                    name:$route.query.name,
                    sword:$route.query.sword,
                    banKai:$route.query.banKai
                }
            },
            beforeEnter:(to,from,next) => {
                next()
            }
        }
    ]
  1. **组件内路由:**通过路由规则切换的组件内部的路由守卫.
  • beforeRouteEnter: 通过路由规则进入该组件时被调用.
  • beforeRouteLeave:通过路由规则离开该组件时被调用.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值