Vue前端vue

VUE2基础知识

2021-07-04  本文已影响0人  王果果

什么是Vue

vue全家桶

辅助vue开发的工具

vue特性

MVVM

VUE指令

内容渲染指令


属性绑定指令

事件绑定指令

  1. 没有参数,回调函数参数e
  2. 有参数,就用$event占位,在回调中e接收
  1. .prevent 阻止浏览器默认行为(@click.prevent="clickFn")
  2. .stop 阻止冒泡(@click.stop="clickFn")
  1. .enter 回车(@keyup.enter="keyupFn")
  2. .esc (@keyup.esc="keyupFn")

双向绑定指令

  1. .number 自动将用户输入的值转化为数字类型
  2. .trim 自动过滤输入的空白字符
  3. .lazy 在输入框失去焦点时才更新

条件渲染指令


  1. 为false时隐藏为true时显示
  2. v-if 的原理是销毁和重建标签
  3. v-show 的原理是给标签添加display:"none"属性
  4. 频繁切换时用v-show性能高
  5. v-if v-else 判断是否为ture为ture显示,否则隐藏
<div v-if="i>90">优秀</div>
<div v-else="i>80">良好</div>
<div v-else="i>70">中等</div>
<div v-else>差劲</div>

循环渲染指令

v-for指令中的key理解

  1. push( ) 末尾添加元素
  2. pop( ) 末尾删除元素
  3. shift( ) 删除数组第一个元素
  4. unshift( ) 添加数组第一个元素
  5. splice( ) 从数组中添加/删除项目,然后返回被删除的项目。
  6. sort( ) 对数组的元素进行排序
  7. reverse( ) 翻转数组


  1. 同级比较根元素发生变化就会删除整个dom树重新创建
  2. 根元素没有变化,只是属性变了,那就只更新属性
  3. 子元素变化 v-for更新分有key和无key

动态class绑定

style动态绑定

:style="{属性名:属性值}"

计算属性-computed

注意: 计算属性使用时不能加( ),计算属性必须return一个结果

computed:{
    "计算属性名"( ){
        return "值"
   }
}

计算属性完整写法

computed:{
   "计算属性名":{
           set(改变后的值){
         },
           get(){
           return "值"
     }
  }
}

vue监听器watch

watch:{
       "被侦听的属性名"(newval,lodval){
          console.log(newval,lodval)
      }  
}
watch:{
       "要侦听的属性名":{
           immediate: true,   //立即执行
           deep: true,     //深度监听
           handler (newval) {   //侦听函数
               console.log(newval)    
      }
   }
}

vue组件

  1. 创建组件,封装要复用的标签,样式,js代码
  2. 导入组价(import 组件对象 from 文件路径)
  3. 注册组件
  4. 使用组件, 把组件名当自定义标签使用
    (1)全局注册- min.js中
// main.js
import Vue from 'vue'
import  组件对象 from 'vue组件路径'

Vue.component("组件名",组件对象)

(2)局部注册 - 使用组件的vue文件中

// 要使用组件的vue文件
import  组件对象 from 'vue组件路径'

export  default {
     components:{
          "组件名":组件对象
  }
}

  1. 大驼峰命名 例如:MyProduct -->推荐使用大驼峰
  2. 烤串法 例如: my-product
  1. 大驼峰命名 例如:MyProduct
  2. 烤串法 例如: my-product -->推荐使用烤串法
    结论:组件命名用大驼峰,组件使用时用烤串法



  1. 作用:使当前组件的css样式只在当前组件中生效,不会影响全局
  2. 原理:会在当前组件的标签上生成一个data-v-hash:8, 每个组件内的data-v-hash:8都是不同的,今后它会配合我们自己写的选择器上加一个属性选择器,从而保证了这个选择器在组件内部的唯一性,而不会影响其他组件

组件之间传值

父传子

  1. 子组件中通过props属性接收数据
//子组件定义
props:{
  变量名:{
     type:变量数据类型,
     default: 默认值
 }
}
  1. 父组件,通过属性的方式传值
<B :变量名="值"> </B>

子传父

  1. 父传给子的数据在子中是只读的不能更改
  2. 从父到子的数据流向,叫 单向数据流
  3. 子想修改父组件传过来的数据只能通过子传父的方式通知父组件修改
  4. 子传父语法:

(1)父组件内,绑定自定义事件和事件处理函数

  <son  @自定义事件名="事件处理函数"  >

(2)子组件内部在合适的时机触发父组件的自定义事件

this.$emit('父组件中的自定义事件名',传参,传参)


两个没有关系或者兄弟组件之间传值

  1. 创建一个空白Vue对象,封装到EventBus.js文件
  2. A: 引入空白的vue对象,EventBus.$on("自定义事件名" ,事件处理函数)
  3. B: 引入相同的这个空白Vue对象, EventBus.$emit("自定义事件名",值)

Vue组件中的生命周期

钩子函数

  1. 初始化
    beforeCreate
    created

  1. 挂载
    beforeMount
    mounted

  1. 更新
    beforeUpdate
    updated

  1. 销毁
    beforeDestroy
    destroyed

v-for循环

<p v-for="(item,index) in 数组" :key="item.id">

axios发送axjx请求



axios的使用

1.下载引入axios(yarn add axios)

//引入
import axios from 'axios'
  1. 发送请求
axios({
    method:"请求方式",  //get &put & post...
    url:"请求的路径",  //http://123.57.109...
    data:{  
      XXX:XXX     //请求体参数
  },
     params:{
      XXX:XXX     //查询参数,会拼接到url路径后
  }
}).then(res={
    //请求成功的回调
}).catch(err={
    //请求失败的回调
})

$refs获取DOM&组件

  1. 标签定义ref属性和值
  2. this.$refs.值 - 原地获取DOM

$nextTick获取更新后的DOM

  1. 在setTimeOut延时器中获取DOM
  2. 在Vue中提供$nextTick方法(等待DOM更新后再执行此方法中的回调函数)
this.$nextTick(()=>{
   getElementById("myp").innerHTML
})

<keep-alive>组件缓存

<keep-alive>
    <!-- vue内置的组件component, 可以动态显示组件 -->
    <component :is="comName"></component>
</keep-alive>

组件插槽

  1. 组件内用<slot></slot>占位
  2. 使用组件时<template></template>夹着的地方, 传入标签替换slot
  1. 在slot标签上用name属性命名
 <slot name="one"></slot>
 <slot name="two"></slot>

2.在template标签上用 v-slot:插槽名 传入具体标签 , v-slot:可以简写成 " # "

 <template #one>
        <div>
            <p>寒雨连江夜入吴,</p>
            <p>平明送客楚山孤。</p>
            <p>洛阳亲友如相问,</p>
            <p>一片冰心在玉壶。</p>
        </div>
    </template>
    <template #two>
        <img src="../assets/mm.gif" alt="" />
    </template>
  1. 创建组件, 准备slot, 在slot上绑定属性和子组件值
  2. 使用组件, 传入自定义标签, 用template和v-slot="自定义变量名"
  3. 自定义变量名会自动绑定slot上所有属性, 就可以使用子组件内值, 并替换slot位置
<template>
  <div>
    <p>这里是个Pannel3-子组件, 下面是插槽位置</p>
    <slot name="one" :row="slotDefault">{{ slotDefault.default1 }}</slot>
  </div>
</template>

<script>
export default {
  data(){
    return {
      slotDefault: {
        default1: "无名氏",
        default2: "孙红雷"
      }
    }
  }
}
</script>
<template>
  <div>   
    <!-- 想要改变默认内容, 但是默认数据在子组件里, 想让插槽使用就使用插槽作用域 -->
    <!-- 
      口诀: 1.创建组件, 准备slot, 在slot上绑定属性和子组件值
      2. 使用组件, 传入自定义标签, 用template和v-slot="自定义变量名"
      3. 自定义变量名会自动绑定slot上所有属性, 就可以使用子组件内值, 并替换slot位置
     -->
    <Pannel3>
      <template #one="scope">
        {{ scope.row.default2 }}
      </template>
    </Pannel3>
  </div>
</template>

<script>
import Pannel3 from './Pannel3'
export default {
  components: {
    Pannel3
  }
}
</script>

自定义指令

<template>
  <div>
    <input type="text" v-focus />
  </div>
</template>

<script>
export default {
  // 局部注册
  directives: {
    focus: { // 自定义指令名
        inserted(el){ // 固定配置项 - 当指令插入到标签自动触发此函数
            el.focus()
        }
    },
  },
};
</script>
Vue.directive("fofo", {
  inserted(el){
    el.focus()
  }
})

自定义指令-接值

main.js定义处修改一下

Vue.directive("color", {
  inserted(el, binding){ // 插入时触发此函数
    el.style.color = binding.value;
  },
  update(el, binding){ // 更新时触发此函数
    el.style.color = binding.value;
  }
})
<p v-color="theColor" @click="changeColor">使用v-color指令控制颜色, 点击变蓝</p>

<script>
  data() {
    return {
      theColor: "red",
    };
  },
  methods: {
    changeColor() {
      this.theColor = 'blue';
    },
  },
</script>

router 路由

  1. 终端下载
    yarn add vue-router
  2. 导入路由
import VueRouter from 'vue-router'
  1. 注册
// 在vue中,使用使用vue的插件,都需要调用Vue.use()
Vue.use(VueRouter)
  1. 创建规则数组
const routes = [
  {
    path: "/find",
    component: Find
  },
  {
    path: "/my",
    component: My
  },
  {
    path: "/part",
    component: Part
  }
]
  1. 创建路由对象 - 传入规则
const router = new VueRouter({
  routes
})
  1. 关联到vue实例
new Vue({
  router
})
  1. 设置路由挂载点
<router-view></router-view>

vue路由 - 声明式导航

  1. router-link-exact-active (精确匹配) url中hash值路径, 与href属性值完全相同, 设置此类名
  2. router-link-active (模糊匹配) url中hash值, 包含href属性值这个路径
<template>
  <div>
    <div class="footer_wrap">
      <router-link to="/find">发现音乐</router-link>
      <router-link to="/my">我的音乐</router-link>
      <router-link to="/part">朋友</router-link>
    </div>
    <div class="top">
      <router-view></router-view>
    </div>
  </div>
</template>

声明式导航 - 跳转传参

  1. /path?参数名=值
  2. /path/值 – 需要路由对象提前配置 path: “/path/参数名”

创建components/Part.vue - 准备接收路由上传递的参数和值

<template>
  <div>
      <p>关注明星</p>
      <p>发现精彩</p>
      <p>寻找伙伴</p>
      <p>加入我们</p>
      <p>人名: {{ $route.query.name }} -- {{ $route.params.username }}</p>
  </div>
</template>

路由定义

{
    path: "/part",
    component: Part
  },
  {
    path: "/part/:username", // 有:的路径代表要接收具体的值
    component: Part
  },

导航跳转, 传值给MyGoods.vue组件

<router-link to="/part?name=小传">朋友-小传</router-link>
<router-link to="/part/小智">朋友-小智</router-link>

vue路由 - 重定向&模式&404页面

路由 - 重定向

const routes = [
  {
    path: "/", // 默认hash值路径
    redirect: "/find" // 重定向到/find
    // 浏览器url中#后的路径被改变成/find-重新匹配数组规则
  }
]

404页面

  1. 创建NotFound页面
<template>
  <img src="404图片路径" alt="">
</template>

<script>
export default {

}
</script>

<style scoped>
    img{
        width: 100%;
    }
</style>

在main.js - 修改路由配置

import NotFound from '@/views/NotFound'

const routes = [
  // ...省略了其他配置
  // 404在最后(规则是从前往后逐个比较path)
  {
    path: "*",
    component: NotFound
  }
]

路由 - 模式设置

  1. hash路由例如: http://localhost:8080/#/home
  1. history路由例如: http://localhost:8080/home (以后上线需要服务器端支持, 否则找的是文件夹)

router/index.js

const router = new VueRouter({
  routes,
  mode: "history" // 打包上线后需要后台支持, 模式是hash
})

vue路由 - 编程式导航

main.js - 路由数组里, 给路由起名字

{
    path: "/find",
    name: "Find",
    component: Find
},
{
    path: "/my",
    name: "My",
    component: My
},
{
    path: "/part",
    name: "Part",
    component: Part
},

App.vue - 换成span 配合js的编程式导航跳转

<template>
 <div>
   <div class="footer_wrap">
     <span @click="btn('/find', 'Find')">发现音乐</span>
     <span @click="btn('/my', 'My')">我的音乐</span>
     <span @click="btn('/part', 'Part')">朋友</span>
   </div>
   <div class="top">
     <router-view></router-view>
   </div>
 </div>
</template>

<script>
// 目标: 编程式导航 - js方式跳转路由
// 语法:
// this.$router.push({path: "路由路径"})
// this.$router.push({name: "路由名"})
// 注意:
// 虽然用name跳转, 但是url的hash值还是切换path路径值
// 场景:
// 方便修改: name路由名(在页面上看不见随便定义)
// path可以在url的hash值看到(尽量符合组内规范)
export default {
 methods: {
   btn(targetPath, targetName){
     // 方式1: path跳转
     this.$router.push({
       // path: targetPath,
       name: targetName
     })
   }
 }
};
</script>

编程式导航 - 跳转传参

<template>
  <div>
    <div class="footer_wrap">
      <span @click="btn('/find', 'Find')">发现音乐</span>
      <span @click="btn('/my', 'My')">我的音乐</span>
      <span @click="oneBtn">朋友-小黑</span>
      <span @click="twoBtn">朋友-小白</span>
    </div>
    <div class="top">
      <router-view></router-view>
    </div>
  </div>
</template>

<script>
// 目标: 编程式导航 - 跳转路由传参
// 方式1:
// params => $route.params.参数名
// 方式2:
// query => $route.query.参数名
// 重要: path会自动忽略params
// 推荐: name+query方式传参
// 注意: 如果当前url上"hash值和?参数"与你要跳转到的"hash值和?参数"一致, 爆出冗余导航的问题, 不会跳转路由
export default {
  methods: {
    btn(targetPath, targetName){
      // 方式1: path跳转
      this.$router.push({
        // path: targetPath,
        name: targetName
      })
    },
    oneBtn(){
      this.$router.push({
        name: 'Part',
        params: {
          username: '小黑'
        }
      })
    },
    twoBtn(){
      this.$router.push({
        name: 'Part',
        query: {
          name: '小白'
        }
      })
    }
  }
};
</script>

vue路由 - 守卫

// 目标: 路由守卫
// 场景: 当你要对路由权限判断时
// 语法: router.beforeEach((to, from, next)=>{//路由跳转"之前"先执行这里, 决定是否跳转})
// 参数1: 要跳转到的路由 (路由对象信息)    目标
// 参数2: 从哪里跳转的路由 (路由对象信息)  来源
// 参数3: 函数体 - next()才会让路由正常的跳转切换, next(false)在原地停留, next("强制修改到另一个路由路径上")
// 注意: 如果不调用next, 页面留在原地

// 例子: 判断用户是否登录, 是否决定去"我的音乐"/my
const isLogin = true; // 登录状态(未登录)
router.beforeEach((to, from, next) => {
  if (to.path === "/my" && isLogin === false) {
    alert("请登录")
    next(false) // 阻止路由跳转
  } else {
    next() // 正常放行
  }
})
上一篇下一篇

猜你喜欢

热点阅读