Vue基础知识

Vue基础知识

1.对于MVVM的理解

MVVM就是Model-View -ViewModel的缩写,Model就是数据模型,View就是用户操作界面,View-Model就是业务逻辑层。当View需要什么数据时,ViewModel要提供这个数据,当View需要进行某个操作时,ViewMode需要相应,可以说它就是model for view 。MVVM 在使用中,利用双向绑定技术,使得Model变化时,ViewModel发生更改,ViewModel发生更改时,View发生更改。

2.组件中的传值

1.父传值给子:props / 状态管理器 / 中央控制总线 / solt
父组件在调用子组件的地方,添加一个自定义的属性,属性的值就是你要传递给子组件的数据,如果值是一个变量,那么需要使用到绑定属性,在子组件定义的地方,添加一个props选项接收数据
接收数据有3种方法:
props: ['tip'], //不校验数据的格式
props: {  //校验数据的格式
	tip: Number
}
props: {
	tip: {
		type: Number,//校验数据格式
		default: 0 //默认值如果为数组或者对象,需要使用函数实现
		/**
		*type: Array,
		*default: function (){
		*	return [1,2,3]
		*}
		*/
	}
}
2.子传值给父

子组件的某一个事件内部,通过this.$emit('事件名',传递的值)传递数据

子组件内写一个事件例如:<button @click="sendData">传值给父组件</button>
methods:{
	sendData () {
		this.$emit('get','hahah')
	}
}

父组件在调用子组件的地方,绑定了子组件自定义的事件名,函数体不要加()

定义父组件的地方,实现函数体,函数体会带有默认的参数,参数值就是子组件传递的值

 父组件内获取这个事件:<my-banner @get='getData'></my-banner>
   methods: {
       getData (str) {
         console.log(str)
       }
   },
3.非父子组件间的传值
// 理解:  我们声明了一个bus的Vue实例,跟我们声明的app实例是同一级别的,bus实例相当于一个车,也就是第三方,方便数据交换的。相当于都在全局中
  //  bus实例中有2个方法bus.$on(),负责监听,bus.$emit()负责触发,
  // 当index中的changIndex方法发生改变的,我们把这个改变告诉bus车,
  //车收到改变的指令就会触发这个事件,将值发生更改,当this指向它的时候,值就改变了。达到传值的效果。
  // 中央事件总线(new Vue()),一方负责监听bus.$on(),一方负责触发bus.$emit()
 const bus = new Vue()
  const Index = {
    template: '#indexTem',
    data () {
      return {
        index: 1
      }
    },
    mounted () {
      // 2、监听事件
      bus.$on('changeIndex', (index) => { // 如果不用箭头函数  that = this 
        console.log(index)
        // 4、后续业务逻辑
        this.index = index
      })
    }
  }
  const Banner = {
    template: '#bannerTem',
    methods: {
      getIndex (index) {
        // 3、触发事件
        bus.$emit('changeIndex', index)
      }
    }
  }
*滚动文档视图或元素时触发事件

EventTarget事件 - scroll

滚动文档视图或元素时会触发scroll事件。

scrollFn () {
      if (event.target.scrollTop > 150) {  //当滚动的文档视图距离
        this.flag = true
      } else {
        this.flag = false
      }
    }
  },

3.编程式导航和声明式导航

编程式跳转:用于在js中处理逻辑后需要页面进行跳转

vue的路由我们可以看做是一个数组,每次添加一个页面可以看成是向数组中push一个地址,当点击返回时就是向数组中的上一个值查找。

编程式跳转其实就是调用: this.$router.push( )

li 标签中加入点击函数@click="goDetail(item.id)"

<!-- 编程式跳转 -->
    <li class="proitem" v-for="(item, index) of prolist" @click="goDetail(item.id)" :key="index">
      <div class="itemimg">
        <img :src="item.images.small" :alt="item.alt" />
      </div>
      <div class="iteminfo">
        <h3>{{ item.title }} --- {{ item.rating.average }}</h3>
        <div class="directors">
          导演:<span v-for="(itm, idx) of item.directors" :key="idx">{{ itm.name }}/</span>
        </div>
        <div class="casts">
          演员: <span v-for="(itm, idx) of item.casts" :key="idx">{{ itm.name }}/</span>
        </div>
        <Rating :rating="(item.rating.average / 2).toFixed(1)"/>
      </div>
    </li>

在export default中的methods中加入

goDetail(id) {
    //this.$router.push( '/detail/' + id ) //string类型的参数
    //this.$router.push( { name: 'detail', params: { id } } ) //object类型参数
    this.$router.push( { path: '/detail/' + id } ) //object类型 
声明式导航:用于直接渲染到页面中,

声明式跳转中的to参数怎么写,编程式跳转中参数就怎么写

<router-link tag="li" :to="{ name: 'detail', params: { id: item.id } }" class="proitem" v-for="(item, index) of prolist" :key="index">
</router-link>

4.slot内容分发-----插槽

插槽决定了组件中的内容显示还是不显示,如何显示。--------------提高组件复用性

<template>
  <header class="header">
    <ul>
      <li @click="back">
        <slot name="left"></slot>
      </li>
      <li>
        <slot></slot>
      </li>
      <li>
        <slot name="right"></slot>
      </li>
    </ul>
  </header>
</template>
<Header>
      <div class="searchBox">
        <span class="iconfont icon-ai65"></span>
        <span class="text">请输入您要搜索的内容</span>
      </div>
      <p slot="right">消息</p>
      <p slot='left'>logo</p>
</Header>
路由别名:alias: '/ho', // 别名 --- 当你访问 /ho 时,其实和访问 /home是一致的

5.动态组件

动态组件让多个组件可以使用同一个挂载点,并动态切换。默认情况下切换时都是先销毁掉原来的组件,再创建新的组件

加入需要保留上一次的结果,避免组件的重新渲染,

可以使用包裹component --- 手机中使用完某款软件,你按了一下HOME按键,此时应用并没有完全关闭

但是此时又有问题了,之前是全部都销毁了,现在是全部都缓存了

能不能只缓存需要的呢?

定义组件时添加name选项,keep-alive 添加include属性,值为name选项,需要缓存的写进去

keep-alive 会伴随有两个生命周期钩子函数 activated deactivated

activated () { // 激活 后台应用程序正在使用}

deactivated () { // 影藏 在后台应用中,但不是关闭了的(按了home键的)}

<div id="app">
    <button @click="type = 'v-aaa'">A组件</button>
    <button @click="type = 'v-bbb'">B组件</button>
    <button @click="type = 'v-ccc'">C组件</button>
    <keep-alive include="aaa,bbb">
      <component :is="type"></component>
    </keep-alive>
  </div>
<keep-alive>
      <!-- 如果路由设置了meta,并且keepAlive为true,避免组件的重新渲染 -->
      <router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
     <router-view v-if = "!$route.meta.keepAlive"></router-view>

在对应的路由位置加上
meta: {
        keepAlive: true
   }

6.axiso能够拦截请求和响应,自动转化json,客户端支持防XSRF攻击

1.使用axios先安装依赖

$ npm install axios -S

2.多请求并发,可以使用axios.all

function getUserAccount() {
  return axios.get('/user/12345');
}

function getUserPermissions() {
  return axios.get('/user/12345/permissions');
}

axios.all([getUserAccount(), getUserPermissions()])
  .then(axios.spread(function (acct, perms) {
    // 两个请求现在都执行完成
  }));

3.axios.post请求跨域问题

请求中遇到跨域问题:(解决跨域问题,一是反向代理,而是后端设置。aixos不用写请求头)

最好的办法遇到跨域问题直接交给后端,后端解决跨域。

axios.post('/api/admins', {
          username: this.form.username,
          password: this.form.password
        }).then(res => {

接口中app.js中加入如下代码:

app.all("*",function (req,res,next) {
  res.header("Access-Control-Allow-Origin","*");
  res.header("Access-Control-Allow-Headers", "X-Requested-With");
  res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
  res.header("X-Powered-By",' 3.2.1');
  res.header("Content-Type", "application/json;charset=utf-8");
  next();
});

4.封装axios,实现拦截请求和响应

import axios from 'axios';
// 开发环境(start)   生产环境(build)   测试环境(test)
// 如果运行的是 npm run start 则为真其余为假
const isDev = process.env.NODE_ENV === 'developement';
// 自定义配置axios
const ajax = axios.create({
  // baseURL: idDev ? 'http://10.11.56.148:3000' : 'https://www.daxunxun.com'
  baseURL: isDev ? 'https://www.daxunxun.com' : 'https://www.daxunxun.com',
  timeout: 6 * 1000 
})
// 添加请求拦截器
ajax.interceptors.request.use(function (config) {
  // 在发送请求之前做些什么
  // 设置请求头、设置loading动画
  console.log('开始加载数据了')
  return config;
}, function (error) {
  // 对请求错误做些什么
  console.log('没有请求到数据')
  return Promise.reject(error);
});
// 添加响应拦截器
ajax.interceptors.response.use(function (response) {
  // 对响应数据做点什么
  console.log('接收到数据了')
  return response;
}, function (error) {
  // 对响应错误做点什么
  console.log('数据接收错误')
  return Promise.reject(error);
});
export default ajax;

7.vue设置反向代理

1.直接在config->index.js->proxyTable

proxyTable: {
      '/api': {
        target: 'http://10.11.56.96:4000', // 跨域地址
        changeOrigin: true, // 是否跨域
        // secure: false, // 是否使用https
        pathRewrite: {
          '^/api': ''
        }
      }
    },

2.如果上面方法不行,就去跟目录下引入vue.config

8.首页引导页

动画与定位相关,定位与层级相关,层级与书写顺序相关,后来居上

9.一般在那些情况下使用到vuex

1.当项目中有一些数据需要共享的时候

2.当后端接口还没有写完的时候,我们把数据临时存到vuex中

Vue中遇到的坑

1.路由中路径加斜杆与不加斜杆的区别:

1562766861340

加斜杆表示的是绝对路径,加点表示当前目录下的路径

2.返回到原来页面的位置,页面没有刷新,当是我又需要在一定时间后刷新,怎么去做,比如新闻直播软件,看新闻时间超过一定时间后,首页面更新,不然短时间浏览不更新
3.$.route和this.$router区别

$.route表示当前路由,this.$router表示项目的所有路由数组

this.$router.back(),就是向这个路由数组中找上一个路由$.route

4.user-scable='no'不允许用户点击放大
5.watch侦听

watch侦听的是进入路由后侦听属性的改变,比如说user->user/login这样会侦听到路由的改变,但是如果user->home页面这样离开了user页面就不能侦听了,它可以侦听这个路由下的属性,和子路由的变化。而beforeRouteEnter侦听的是跳转到其他路由前的钩子函数。

posted @ 2019-08-15 11:00  机智的小恐龙  阅读(337)  评论(0编辑  收藏  举报