vue复习


前言

vue学习


提示:以下是本篇文章正文内容,下面案例可供参考

一、过滤器(filter)

filter:过滤器的作用就是对我们输入的内容做一次处理之后再展示,接受的数据为管道符号前面的值(包括全局过滤器和局部过滤)

<div id="app">
  <input type="text" placeholder="请输入价格" v-model="price" />
  <p>{{price|formatePrice|format}}</p>
</div>
<script>
  // 全局过滤器
  Vue.filter('format',(v)=>{
    return v+'$'
  })
  new Vue({
    el: '#app',
    data: {
      price: '',
    },
    filters: {
      formatePrice(v) {
        return '$' + v
      },
    },
  })

二、监听(watch)

watch:watch监听某一个数据的改变,数据改变之后引起一些其他的操作

<div id="app">
  <input type="text" placeholder="请输入年龄" v-model="msg" />
</div>
<script>
  new Vue({
    el: '#app',
    data: {
      msg: '',
    },
    watch: {
      msg(v) {
        if (v.indexOf('sb') !== -1) {
          alert('你输入了不合适的内容')
        }
      },
    },
  })
</script>
//深度监听--
new Vue({
  el: '#app',
  data: {
    userObj: {
      username: 'chen',
      age: 18,
    },
  },
  watch: {
    userObj: {
      deep: true,
      handler(v) {
        console.log('您修改了值')
      },
    },
  },
})

三、计算属性(computed)

计算属性:当依赖的值发生变化,重新计算结果 计算属性有缓存效果,当依赖的值没有发生变化,不会重新计算

<div id="app">
  <input type="text" v-model="keyName" />
  <ul>
    <li v-for="(item) in filterList" :key="item.id">{{item.name}}</li>
  </ul>
</div>
<script>
  new Vue({
    el: '#app',
    data: {
      keyName: '',
      list: [
        { id: 1, name: '喜羊羊' },
        { id: 2, name: '美羊羊' },
        { id: 3, name: '懒羊羊' },
        { id: 4, name: '沸羊羊' },
      ],
    },
    computed: {
      filterList() {
        return this.list.filter(
          (item) => item.name.indexOf(this.keyName) !== -1
        )
      },
    },
  })
</script>

计算属性中set和get

  • get():1.当需要读取当前属性值时调用(初始化)/当依赖项变化时也调用该回调函数 2.根据相关数据计算并返回当前属性值
  • set():监视:1.当属性值变化时调用该回调函数 2.根据最新的属性值计算相关数据
const vm = new Vue ({
	data: {
		firstName;A’,
		lastName: 'B'
	},
	computed: {
		fullName: {
			get () {
				return firstName + ' ' + lastName;
			},
			set (value) {   //fullName是要监听的属性,value是fullName的最新属性值
				this.firstName = value.split(' ').[0];
				this.lastName = value.split(' ').[1];
			}
		}
	}
})

四、路由

  • 路由分为hash模式和history模式
  • hash模式就是url中有#;好用但是不好看
  • history模式没有#,在发布之后需要在web服务器上做特殊配置;好看但是不好用
  • vue路由默认是hash模式的

1.路由的基本使用

//npm install vue-router
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
import home from '../pages/home.vue'

const router = new VueRouter({
  routes: [
    {
      path: '/', //表示url中访问的地址
      component: home, //表示对应的组件
      name: 'Home', //名字
    },
    {
      path: '/cart',
      // 路由懒加载,
      // 第一次页面初始化的时候不会加载这个js文件,
      //当页面跳转到当前页的时候会请求这个文件。建议只用这种方式
      component: () => import('../pages/cart.vue'),
      name: 'Cart',
    },
    {
      path: '/list',
      component: () => import('../pages/list.vue'),
      name: 'List',
    },
    {
      path: '/user',
      component: () => import('../pages/user.vue'),
      name: 'User',
    },
    //当路径路由不正确,配置展示404页面
    {
    path: "*", // 匹配所有的
    component: () => import("../views/PageNotFound"),
 	},
  ],
})
export default router

2.在vue路由中使用的标签

(1)router-link

router-link:最终被渲染成a标签

//通过路由跳转
<router-link to="/">【首页】</router-link>
<router-link to="/products">【列表】</router-link>
//通过name跳转--推荐使用
<router-link :to="{name:'List'}">
  <i class="iconfont icon-bianji"></i>
  <span>详情页</span>
</router-link>

(2)router-view

router-view:所有路由对应的组件都会被渲染到这个节点

<router-view></router-view>

3.路由跳转方式

(1)声明式路由跳转–router-link

1. 不带参数
 
<router-link :to="{name:'home'}"> 
<router-link :to="{path:'/home'}"> //name,path都行, 建议用name  
// 注意:router-link中链接如果是'/'开始就是从根路由开始,如果开始不带'/',则从当前路由开始。
 
2.带参数
 
<router-link :to="{name:'home', params: {id:1}}">  
 
// params传参数 (类似post)
// 路由配置 path: "/home/:id" 或者 path: "/home:id" 
// 不配置path ,第一次可请求,刷新页面id会消失
// 配置path,刷新页面id会保留
 
// html 取参  $route.params.id
// script 取参  this.$route.params.id
 

<router-link :to="{name:'home', query: {id:1}}"> 

(2)编程式路由跳转–>this.$router.push()

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

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

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

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

1.  不带参数
 
this.$router.push('/home')
this.$router.push({name:'home'})
this.$router.push({path:'/home'})
 
2. query传参 
 
this.$router.push({name:'home',query: {id:'1'}})
this.$router.push({path:'/home',query: {id:'1'}})
 
// html 取参  $route.query.id
// script 取参  this.$route.query.id
 
3. params传参
 
this.$router.push({name:'home',params: {id:'1'}})  // 只能用 name
 
// 路由配置 path: "/home/:id" 或者 path: "/home:id" ,
// 不配置path ,第一次可请求,刷新页面id会消失
// 配置path,刷新页面id会保留
 
// html 取参  $route.params.id
// script 取参  this.$route.params.id
 
4. query和params区别
query类似 get, 跳转之后页面 url后面会拼接参数,类似?id=1, 非重要性的可以这样传, 密码之类还是用params刷新页面id还在
 
params类似 post, 跳转之后页面 url后面不会拼接参数 , 但是刷新页面id 会消失

(3)query和params传参的区别

  • query 传参配置的是path,而params传参配置的是name,在params中配置path无效
  • query在路由配置不需要设置参数,而params必须设置
  • query传递的参数会显示在地址栏中
  • params传参刷新会无效,但是query会保存传递过来的值,刷新不变

(4)其他编程式路由跳转方法的区别

  • this.$router.replace()
  • this.$router.go(n)
this.$router.go(n)
向前或者向后跳转n个页面,n可为正整数或负整数

ps : 区别

this.$router.push
跳转到指定url路径,并想history栈中添加一个记录,点击后退会返回到上一个页面
this.$router.replace
跳转到指定url路径,但是history栈中不会有记录,点击返回会跳转到上上个页面 (就是直接替换了当前页面)

this.$router.go(n)
向前或者向后跳转n个页面,n可为正整数或负整数

(5)通过this.$route可以获取传递的参数

4.路由嵌套

(1)路由嵌套

{
    path: '/user',
    component: () => import('../views/user/index.vue'),
    name: 'User',
    children: [
      {
        path: 'orders',
        component: () => import('../views/user/orders.vue'),
        name: 'Orders',
      },
      {
        path: 'info',
        component: () => import('../views/user/info.vue'),
        name: 'Info',
      },
      {
        path: 'score',
        component: () => import('../views/user/score.vue'),
        name: 'Score',
      },
    ],
  },

(2)命名视图

同时展示多个视图,非嵌套展示

//路由配置
{
    path: '/many',
    name: 'Many',
    component: () => import('../views/many.vue'),
    // 一个页面显示多个路由,可以使用属性components
    children: [
      {
        path: '',
        components: {
          test1: () => import('../views/many/test1.vue'),
          test2: () => import('../views/many/test2.vue'),
          test3: () => import('../views/many/test3.vue'),
        },
      },
    ],
  },
  <-! 页面展示->
  <div>
    <h2>这里添加多页面(many)</h2>
    <router-view name="test1"></router-view>
    <router-view name="test2"></router-view>
    <router-view name="test3"></router-view>
  </div>

5.路由导航守卫

(1)全局前置守卫

  • 所有的页面跳转之前执行
  • 回调函数中有三个参数
    • to 到哪里去
    • from 从哪里来
    • next 是一个方法,需要调用。如果不调用,页面就不会执行
  • beforeEach表示路由的前置守卫,路由跳转之前执行
router.beforeEach((to, form, next) => {
  //判断当前页面是否需要登录--在路由中加meta:{needLogin:true}
  if (to.meta.needlogin) {
  //判断用户是否登录
    if (localStorage.getItem('token')) {
      next()
    } else {
      next({ name: 'User' })
    }
  }
  next()
})

(1)全局后置钩子

router.afterEach((to, from) => {
  console.log('路由跳转之后执行')
})


五、vueX学习

定义:VueX 是一个专门为 Vue.js 应用设计的状态管理架构,统一管理和维护各个vue组件的可变化状态
可以通过import { mapState, mapMutations, mapActions } from "vuex"获取;

1.State

vuex的基本数据,用来存储变量

state: {
    count: 1,
    cart: [
      { id: 1, name: 'chen1' },
      { id: 2, name: 'chen2' },
      { id: 3, name: 'chen3' },
    ],
  },
  • 通过$store.state.count获取
  • 通过 …mapState([“count”])映射到计算属性(computed)获取

2.Getters

从基本数据(state)派生的数据,相当于store的计算属性

 // 相当于计算属性
  getters: {
    cartLength(state) {
      return state.cart.length
    },
  },
  • store.getters.cartLength
    //在组件中,则要写在计算属性中,
    computed: {
    doneTodos () {
    return this.$store.getters.cartLength;
    }
    }
  • …mapGetters([‘cartLength’])获取

3.Mutations

提交更新数据的方法,必须是同步的(如果需要异步使用action)

mutations: {
  addCount(state, payload) {
    state.count += payload.step
  },
  reduceCount(state, payload) {
    state.count -= payload.step
  },
  // 接口
  getDataEnd(state, payload) {
    console.log(payload)
  },
},
  • <button @click=“addCount({step:2})”>增加
    …mapMutations([‘addCount’]),
  • reduce () {
    this.$store.commit(‘reduceCount’, { step: 2 })
    }

4.Actions

和mutation的功能大致相同,不同之处在于:

  • Action 提交的是 mutation,而不是直接变更状态;
  • Action 可以包含任意异步操作。
  • 不推荐在此处修改数据,在此处修改的数据不能被vue-devtools工具记录
// 此处添加异步请求
actions: {
	addAsync(context, payload) {
      console.log(context);
      console.log(payload);
      // 不建议在action中改变数据
      // context.state.count += payload.step;
      setTimeout(() => {
        context.commit("add", payload);
      }, 3000);
    },
  async getData({ commit }) {
    try {
      let result = await axios.get('http://localhost:1337/api/v1/products')
      commit('getDataEnd', result)
    } catch (error) {
      console.log(error)
    }
  },
},
  • …mapActions([‘getData’])
  • this.$store.dispatch(“addAsync”, {
    step: 3,
    });

5.Modules

模块化vuex,可以让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,管理更为方便


六、引入图片问题

1.引入图片路径问题

如果图片路径参数写在js代码中,图片需要通过require进行引入,require会自动调用webpack的文件解析功能

import img from "./assets/logo.png";
 data() {
    return {
      img: img, //require("./assets/logo.png"),
    };
  },

七、组件化开发

1.定义局部组件

可以使用一下两种方式定义局部组件 ,局部组件需要先注册在使用

  1. 在html结构中定义template模版
  2. 在script结构中使用模板字符串
<body>
    <div id="app">
      <selfcom></selfcom>
      <con></con>
    </div>
    <template id="define">
      <h2>添加一个自定义组件模版</h2>
    </template>
    <script>
      // 自定义组件命名规则---不能出现大些字母--需要先注册在使用
      const selfcom = {
        template: `<div>妈呀</div>`,
      }
      const con = {
        template: '#define',
      }
      new Vue({
        el: '#app',
        data: {},
        components: {
          selfcom,
          con,
        },
      })
    </script>
  </body>

2.定义全局组件

全局组件不需要注册,可以直接使用可以在全局组件中添加conponents注册局部组件在全局组件中使用

<div id="app">
  <con></con>
</div>
<script>
  // 自定义组件
  const self = {
    template: '<em>这里是自定义组件的内容</em>',
  }
  Vue.component('con', {
    template: '<div>添加全局组件<self></self></div>',
    components: {
      self,
    },
  })

3.创建动态组件

使用组件<component :is=“current”><component>

<div id="app">
  <button @click="current='index'">首页</button>
  <button @click="current='info'">详情</button>
  <button @click="current='user'">我的</button>
  <component :is="current"></component>
</div>
<script>
  const index = {
    template: '<h1>这是首页<h1>',
  }
  const info = {
    template: '<h1>这是详情<h1>',
  }
  const user = {
    template: '<h1>这是我的<h1>',
  }
  new Vue({
    el: '#app',
    data: {
      current: 'index',
    },
    components: {
      index,
      info,
      user,
    },
  })

4.组件传参问题

(1)父传子

在父组件中可以通过v-bind绑定属性,传递给子组件,可以传递的数据包括数字,对象,数组等

//接收父组件传值
props['data']
//可以自定义接收过来的数据类型,对传递的数据进行默认的配置
props: {
  data: {
    type: Object,
    default: '默认值',
    required: true,
  },
},

(2)子传父

父子组件的关系可以总结为prop向下传递,事件向上传递。父组件通过prop给子组件下发数据,子组件通过事件给父组件发送信息。

//在子组件中通过事件派发
this.$emit('change-num', this.count)
//传递的父组件中通过事件监听 触发回调函数
this.$on('change-num',this.numHandel())
numhandle(v){
//此时v为子组件中派发的数据
}

(3)非相关组件传参(事件总线)

创建一个空白的vue实例,只用来做事件派发和监听,实现数据的通信和传递

const busEvent=new Vue()
//事件派发
busEvent.$emit('changEvent',this.num)
//事件监听
busEvent.$on('changeEvent',this.changeHandle())
//此时触发回调函数 changeHandle()
//在创建的项目的main.js配置事件总线
const busEvent=new Vue()
Vue.prototype.$busEvent=busEvent
//在其他组件中可以通过this使用该事件总线
this.$busEvent.$emit()
this.$busEvent.$on()

5.keep-alive

保证组件不被销毁,该页面不再被重新渲染 ,在<keep-alive><keep-alive>组件上可以添加两个属性include 表示包含, exclude 表示不包含,逗号分隔字符串

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值