Vue学习大全

 

 一、Vue基础

1.vue-cli2.x初始化一个vue项目:vue init webpack xxx,之后进入项目npm install、npm run dev

   vue3.0初始化:vue create xxx

2.router

  <router-view/>展示页面,创建路由:

const routes = [...];
const router = new Router({
    routes,
})
// 挂载
new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')

路由通过this.$router访问,this.$route访问当前路由,当使用路由参数时,例如从 /user/foo 导航到 /user/bar原来的组件实例会被复用。因为两个路由都渲染同个组件,比起销毁再创建,复用则显得更加高效。不过,这也意味着组件的生命周期钩子不会再被调用,想对路由参数的变化作出响应的话可以简单地 watch (监测变化) $route 对象或者beforeRouteUpdate钩子

router方法:push(),注意如果提供了path则params无效,可以用{path: `/user/${userId}`}或者用路由的name+params解决,而replace()方法会替换history对象的记录,go(n)

// 字符串
router.push('home')

// 对象
router.push({ path: 'home' })

// 命名的路由
router.push({ name: 'user', params: { userId: '123' }})

// 带查询参数,变成 /register?plan=private
router.push({ path: 'register', query: { plan: 'private' }})

route属性:path、params(路由参数)、query(查询参数)

动态路由匹配:

模式匹配路径$route.params
/user/:username/user/evan{ username: 'evan' }
/user/:username/post/:post_id/user/evan/post/123{ username: 'evan', post_id: '123' }

嵌套路由:一个被渲染组件同样可以包含自己的嵌套 <router-view>,需要在这个路由下设置children[],

精确匹配:exact

重定向:redirect,可以在具体路由里添加props属性来将路由和组件解耦

 {
      path: '/user/:id',
      components: { default: User, sidebar: Sidebar },
      props: { default: true, sidebar: false }
 }

路由模式:hash模式带#号,而history模式没有,用mode属性控制,base表示基础路由前缀

const router = new VueRouter({
  mode: 'history',
  routes: [...]
})

 路由守卫:参数或查询的改变并不会触发进入/离开的导航守卫,一定要有next(),参数可以是路由对象  

const router = new VueRouter({ ... })

router.beforeEach((to, from, next) => {
  // ...
})

路由独享守卫:beforeEnter在route数组里面的具体路由内定义,与全局守卫类似

组件内的守卫:

const Foo = {
  template: `...`,
  beforeRouteEnter (to, from, next) {
    // 不能获取组件实例 `this`,因为当守卫执行前,组件实例还没被创建
  },
  beforeRouteUpdate (to, from, next) {
    // 在当前路由改变,但是该组件被复用时调用
    // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
    // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
    // 可以访问组件实例 `this`
  },
  beforeRouteLeave (to, from, next) {
    // 导航离开该组件的对应路由时调用
    // 可以访问组件实例 `this`
    const answer = window.confirm('Do you want to leave? you have unsaved changes!')
    if (answer) {
      next()
    } else {
      next(false)
    }
  }
}

 完整的导航解析过程:

  1. 导航被触发。
  2. 在失活的组件里调用离开守卫。
  3. 调用全局的 beforeEach 守卫。
  4. 在重用的组件里调用 beforeRouteUpdate 守卫 (2.2+)。
  5. 在路由配置里调用 beforeEnter
  6. 解析异步路由组件。
  7. 在被激活的组件里调用 beforeRouteEnter
  8. 调用全局的 beforeResolve 守卫 (2.5+)。
  9. 导航被确认。
  10. 调用全局的 afterEach 钩子。
  11. 触发 DOM 更新。
  12. 用创建好的实例调用 beforeRouteEnter 守卫中传给 next 的回调函数。

路由元信息:meta:{requiresAuth:true},常用于需要登录后才能进入的页面

过渡动画:<transition>,缓存组件:<keep-alive>

<transition>
  <keep-alive>
    <router-view></router-view>
  </keep-alive>
</transition>

切换路由的滚动行为:

const router = new VueRouter({
  routes: [...],
  scrollBehavior (to, from, savedPosition) {
    // return 期望滚动到哪个的位置
    if (savedPosition) {
        return savedPosition
    } else {
        return { x: 0, y: 0 } // 滚动到顶部
    }
  }
})

路由懒加载:const home = ()=>  import('../home.vue')

3.组件构造器:

// 创建构造器
var Profile = Vue.extend({
  template: '<p>{{firstName}} {{lastName}} aka {{alias}}</p>',
  data: function () {
    return {
      firstName: 'Walter',
      lastName: 'White',
      alias: 'Heisenberg'
    }
  }
})
// 创建 Profile 实例,并挂载到一个元素上。
new Profile().$mount('#mount-point')

4.注册全局组件:

// 注册组件,传入一个扩展过的构造器
Vue.component('my-component', Vue.extend({ /* ... */ }))

// 注册组件,传入一个选项对象 (自动调用 Vue.extend)
Vue.component('my-component', { /* ... */ })

5.安装vue插件:Vue.use( plugin ),例如UI框架,import之后要use一下

6.data返回的是一个函数:data() { return {...}};

7.props接收父组件传来的数据,简单数据用数组接收,复杂的用对象接收
 

// 简单的用数组接收
props: ['size', 'myMessage']

// 复杂的用对象接收
 props: {
    height: Number,// 检测类型
    age: {
      type: Number,// 检测类型
      default: 0,// 默认值
      required: true,// 是否必传
      validator: function (value) {// 函数验证
        return value >= 0
      }
    }
  }

8.computed计算属性

var vm = new Vue({
  data: { a: 1 },
  computed: {
    // 仅读取
    aDouble: function () {
      return this.a * 2
    },
    // 读取和设置
    aPlus: {
      get: function () {
        return this.a + 1
      },
      set: function (v) {
        this.a = v - 1
      }
    }
  }
})
vm.aPlus   // => 2
vm.aPlus = 3
vm.a       // => 2
vm.aDouble // => 4

9.methods:不要使用箭头函数,否则this将不会指向vue实例

var vm = new Vue({
  data: { a: 1 },
  methods: {
    plus () {
      this.a++
    }
  }
})
vm.plus()
vm.a // 2

10.watch

var vm = new Vue({
  data: {
    a: 1,
    c: 3,
    d: 4,
    e: {
      f: {
        g: 5
      }
    }
  },
  watch: {
    a: function (val, oldVal) {
      console.log('new: %s, old: %s', val, oldVal)
    },
    // 该回调会在任何被侦听的对象的 property 改变时被调用,不论其被嵌套多深
    c: {
      handler: function (val, oldVal) { /* ... */ },
      deep: true
    },
    // 该回调将会在侦听开始之后被立即调用
    d: {
      handler: 'someMethod',
      immediate: true
    },
    // watch vm.e.f's value: {g: 5}
    'e.f': function (val, oldVal) { /* ... */ }
  }
})
vm.a = 2 // => new: 2, old: 1

11.el、template、render:优先级el < template < render

①只有el:let vm = new Vue({el:"#app",data:{age:12}});

②只有template:不行,vue不知道把template放在哪里

③只有render:不行,vue不知道render函数执行后的结果放哪里

④el和template:template的内容会替代el的内容

let vm = new Vue({
	el:"#app",
	template:"<div><p>我template出来的,年龄{{age}}</p></div>",
	data:{
		age:12
	}
});

⑤el、template和render都有:只会使用render的结果

let vm = new Vue({
	el:"#app",
	template:"<div><p>我template出来的,年龄{{age}}</p></div>",
	data:{
		age:12
	},
	render:function(createElement){
	  // return createElement('h1', '我是render出来的HTML,年龄{{age}}');//不能使用“Mustache”语法 (双大括号)
	   return createElement('h1', '我是render出来的HTML,年龄'+this.age);
	}
});

12.生命周期

beforeCreate:无法使用data数据

created:常用与数据请求,此时可以使用data数据,但是还无法使用dom即this.$el

               生成顺序:props => methods =>data => computed => watch

mounted:可以使用nextTick,在所有视图渲染完毕后自动调用,可以使用dom即this.$el

beforeUpdate:移除事件监听器

updated:

activated:keep-alive 缓存的组件激活时调用,deactivated: keep-alive 缓存的组件停用时调用

13.mixin:接收一个混入对象的数组

var mixin = {
  created: function () { console.log(1) }
}
var vm = new Vue({
  created: function () { console.log(2) },
  mixins: [mixin]
})
// => 1
// => 2

14.name:允许组件模板递归地调用自身,并且便于工具调试

15.实例属性:this.$data.xxx,vue实例代理后一般直接使用this.xxx;this.$props.xxx,vue实例代理后一般直接使用this.xxx,

         this.$el:根dom元素;this.$parent:父实例;this.$root:根实例;this.$children:子组件实例;this.$slots.xxx可以找到

        具名插槽;this.$refs.xxx:持有注册过ref=‘xxx’属性的所有 DOM 元素和组件实例;this.$attrs:通过v-bind="$attrs" 传入

        内部组件;this.$listener:可以通过v-on="$listeners"传入子组件

16.方法this.$set(target,属性名/index,value):可以改变data数据;this.$delete(target,属性名/index)

this.student.age = 15 // 视图层无法更新
this.$set(this.student, 'age', '15') 
// 或者 this.student.age = 15
//     this.student = Object.assign({}, this.student)

17.this.$on(event,callback):监听当前实例的自定义事件,可以由 this.$emit触发。回调函数会接收所有传入的额外参数

vm.$on('test', function (msg) {
  console.log(msg)
})
vm.$emit('test', 'hi')
// => "hi"

18.this.$emit(eventName,arguments)触发事件

Vue.component('welcome-button', {
  template: `
    <button v-on:click="$emit('welcome', 'haha')">
      Click me to be welcomed
    </button>
  `
})

<div id="emit-example-simple">
  <welcome-button v-on:welcome="sayHi"></welcome-button>
</div>

new Vue({
  el: '#emit-example-simple',
  methods: {
    sayHi: function (aa) {
      alert('Hi!', aa)
    }
  }
})

19.this.$nextTick:将回调延迟到下次 DOM 更新循环之后执行。在修改数据之后立即使用它,然后等待 DOM 更新

new Vue({
  // ...
  methods: {
    // ...
    example: function () {
      // 修改数据
      this.message = 'changed'
      // DOM 还没有更新
      this.$nextTick(function () {
        // DOM 现在更新了
        // `this` 绑定到当前实例
        this.doSomethingElse()
      })
    }
  }
})

20.指令

v-text:<span v-text="msg"></span>

v-html:更新视图的innerHtml,危险一般不用

v-show:类似于css属性display

v-if:在切换时元素及它的数据绑定 / 组件被销毁并重建,v-else

v-for:<div v-for="(item, index) in items" :key="item.id"></div>需要提供key,一般不使用数字index做key

v-on:简写@,用在普通元素上时,只能监听原生dom事件。用在自定义元素组件上时,也可以监听子组件触发的自定义事件

  • .stop - 调用 event.stopPropagation()
  • .prevent - 调用 event.preventDefault()
  • .{keyCode | keyAlias} - 只当事件是从特定键触发时才触发回调。
  • .native - 监听组件根元素的原生事件。
  • .once - 只触发一次回调。

<!-- 内联语句 -->
<button @click="doThat('hello', $event)"></button>  // doThat方法中可以使用例如e.target

<!-- 缩写 -->
<button @click="doThis"></button>

<!-- 动态事件缩写 (2.6.0+) -->
<button @[event]="doThis"></button>

<!-- 停止冒泡 -->
<button @click.stop="doThis"></button>

<!-- 阻止默认行为 -->
<button @click.prevent="doThis"></button>

<!-- 阻止默认行为,没有表达式 -->
<form @submit.prevent></form>

<!--  串联修饰符 -->
<button @click.stop.prevent="doThis"></button>

<!-- 键修饰符,键别名 -->
<input @keyup.enter="onEnter">

<!-- 键修饰符,键代码 -->
<input @keyup.13="onEnter">

<!-- 点击回调只会触发一次 -->
<button v-on:click.once="doThis"></button>

<!-- 对象语法 (2.4.0+) -->
<button v-on="{ mousedown: doThis, mouseup: doThat }"></button>



<my-component @my-event="handleThis"></my-component>

<!-- 内联语句 -->
<my-component @my-event="handleThis(123, $event)"></my-component>

<!-- 组件中的原生事件 -->
<my-component @click.native="onClick"></my-component>

 v-bind:缩写:

<!-- 绑定一个 attribute -->
<img :src="imageSrc">

<!-- 动态 attribute 名 (2.6.0+) -->
<button :[key]="value"></button>

<!-- 内联字符串拼接 -->
<img :src="'/path/to/images/' + fileName">

<!-- class 绑定 -->
<div :class="{ red: isRed }"></div>
<div :class="[classA, classB]"></div>
<div :class="[classA, { classB: isB, classC: isC }]">

<!-- style 绑定 -->
<div :style="{ fontSize: '20px' }"></div>
<div :style="[styleObjectA, styleObjectB]"></div>

<!-- 绑定一个全是 attribute 的对象 -->
<div v-bind="{ id: someProp, 'other-attr': otherProp }"></div>

<!-- 通过 prop 修饰符绑定 DOM attribute -->
<div v-bind:text-content.prop="text"></div>

<!-- prop 绑定。“prop”必须在 my-component 中声明。-->
<my-component :prop="someThing"></my-component>

<!-- 通过 $props 将父组件的 props 一起传给子组件 -->
<child-component v-bind="$props"></child-component>

<!-- XLink -->
<svg><a :xlink:special="foo"></a></svg>

v-model:在表单控件或组件上创建双向绑定,.lazy取代input监听change事件.number输入字符串转为数字.trim首尾空格过滤

v-slot:仅限于templa和组件

<!-- 具名插槽 -->
<base-layout>
  <template v-slot:header>
    Header content
  </template>

  Default slot content

  <template v-slot:footer>
    Footer content
  </template>
</base-layout>

<!-- 接收 prop 的具名插槽 -->
<infinite-scroll>
  <template v-slot:item="slotProps">
    <div class="item">
      {{ slotProps.item.text }}
    </div>
  </template>
</infinite-scroll>

<!-- 接收 prop 的默认插槽,使用了解构 -->
<mouse-position v-slot="{ x, y }">
  Mouse position: {{ x }}, {{ y }}
</mouse-position>

v-pre、v-cloak、v-once:只渲染元素和组件一次

21.特殊属性

key:主要用于虚拟dom的diff算法,提高性能,最长用于v-for,或者完整地触发组件的生命周期钩子、触发过渡

ref:给元素或子组件注册引用信息,会注册到this.$refs上

22.内置组件

①transition:

    name:用于自动生成 CSS 过渡类名,例如name=‘fade’,将自动生成.fade-enter等类

    appear:是否在初始渲染时使用过渡,默认false

    css:是否使用 CSS 过渡类,默认为true

    type:指定过渡事件类型,侦听过渡何时结束,可选transition和animation

    mode:控制离开/进入过渡的时间序列,可选out-in和in-out,默认同时

    duration:指定过渡的持续时间

    事件:例如before-enter、enter、leave等事件

    transition-group和transition类似

②keep-alive:会激活activated和deactivated两个钩子 

    include:字符串或正则表达式。只有名称匹配的组件会被缓存,可用逗号隔开或者数组,用组件的name属性

    exclude: 字符串或正则表达式。任何名称匹配的组件都不会被缓存

    max:最多缓存多少个组件

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值