vue项目实战:实战技巧总结(中)

简介: vue项目实战:实战技巧总结

vue项目实战:实战技巧总结(上):https://developer.aliyun.com/article/1483347


十一、引入接口文件暴露到全局


11.1 在 main.js 里面引入接口暴露到全局'

// 接口暴露在全局
import { server } from './config/api'
Vue.prototype.\$server = server;
//api.js

export const server = {
getContentMenu: (paramObj)=>fetch('/content/menu',paramObj),//内容详情查询
getContentListPort: (paramObj)=>fetch('/content/list/'+paramObj),//入口页面接口
getContentList:(paramObj)=>fetch('/content/list/'+paramObj),//内容详情查询
getPageviews:(paramObj)=>fetch('/webpage/1/view',paramObj)//流量统计接口
}

组件里面使用:
```js
methods: {
  getPageviews() {
    var that = this;
    let params = {
      pageId: that.pageId,
      pageUrl: that.pageUrl,
    };
    that.\$server.getPageviews(params).then(response => {})
  }
}

11.2 axios 方法封装,整个 api.js


import axios from 'axios';

axios.defaults.timeout = 5000;
axios.defaults.baseURL =''; //填写域名

//http request 拦截器
axios.interceptors.request.use(
  config => {
    config.data = JSON.stringify(config.data);
    config.headers = {
      'Content-Type':'application/x-www-form-urlencoded'
    }
    return config;
  },
  error => {
    return Promise.reject(err);
  }
);

//响应拦截器即异常处理
axios.interceptors.response.use(response => {
    return response
}, err => {
    if (err && err.response) {
      switch (err.response.status) {
        case 400:
            console.log('错误请求')
          break;
        case 401:
            console.log('未授权,请重新登录')
          break;
        case 403:
          console.log('拒绝访问')
          break;
        case 404:
          console.log('请求错误,未找到该资源')
          break;
        case 405:
          console.log('请求方法未允许')
          break;
        case 408:
          console.log('请求超时')
          break;
        case 500:
          console.log('服务器端出错')
          break;
        case 501:
          console.log('网络未实现')
          break;
        case 502:
          console.log('网络错误')
          break;
        case 503:
          console.log('服务不可用')
          break;
        case 504:
          console.log('网络超时')
          break;
        case 505:
          console.log('http版本不支持该请求')
          break;
        default:
          console.log(`连接错误${err.response.status}`)
      }
    } else {
      console.log('连接到服务器失败')
    }
    return Promise.resolve(err.response)
})


/**
 * 封装get方法
 * @param url
 * @param data
 * @returns {Promise}
 */

export function fetch(url,params={}){
  return new Promise((resolve,reject) => {
    axios.get(url,{
      params:params
    })
    .then(response => {
      resolve(response.data);
    })
    .catch(err => {
      reject(err)
    })
  })
}


/**
 * 封装post请求
 * @param url
 * @param data
 * @returns {Promise}
 */

 export function post(url,data = {}){
   return new Promise((resolve,reject) => {
     axios.post(url,data)
          .then(response => {
            resolve(response.data);
          },err => {
            reject(err)
          })
   })
 }

/**
 * 官网接口请求封装
 * @param url
 * @param data
 * @returns {Promise}
 */

export const server = {
    getContentMenu: (paramObj)=>fetch('/content/menu',paramObj),//内容详情查询
    getContentListPort: (paramObj)=>fetch('/content/list/'+paramObj),//入口页面接口
    getContentList:(paramObj)=>fetch('/content/list/'+paramObj),//内容详情查询
    getPageviews:(paramObj)=>fetch('/webpage/1/view',paramObj)//流量统计接口
}

十二、provide /inject 完美解决不跳转不闪动页面刷新


原理:此方法使用的是 v-if 来控制 router-view 的显示或隐藏,v-if 从 false 变为 true 时,vue 会重新渲染 router-view 区域,所以当参数变化时,只需让 v-if 从 true => false => true,就能实现页面刷新。


12.1 找到route-view

//App.vue

   <template>
      <div id="app">
        <router-view v-if="isRouterAlive"/>
      </div>
   </template>

   <script>
    export default {
      name: 'App',
      provide() {
        return {
          reload: this.reload//调用reload方法
        }
      },
      data() {
        return {
          isRouterAlive: true//一开始router-view为true
        }
      },
    
      methods: {
        reload() {
          this.isRouterAlive = false
             //在修改数据之后使用 $nextTick,则可以在回调中获取更新后的 DOM
          this.$nextTick(() => {
            this.isRouterAlive = true
          })
        }
      }
    }
   </script>

12.2在页面操作

    export default {
      name: 'newproduct',
      inject:['reload'],//在export default下面加上这一段
      method:{
        //调用App.vue下的this.reload()方法,来改变v-if的状态
        clickDiv(){//刷新按钮调用的方法
          this.reload()
        }
      }

参考文档:如何实现 vue 中不跳转不闪动页面刷新?provide /inject 完美解决方案


十三、vue动态绑定 class


13.1 对象方法

:class="{ 'active': isActive }"

13.2 判断是否绑定一个active

:class="{'active':isActive==-1}"  
或者
:class="{'active':isActive==index}"

13.3绑定并判断多个


第一种(用逗号隔开)
:class="{ 'active': isActive, 'sort': isSort }"
第二种(放在 data 里面)
:class="classObject"
data() {
  return {
    classObject: {
      active: true,
      sort: false
    }
  }
}
第三种(使用 computed 属性)
:class="classObject"
data() {
    return {
      isActive: true,
      isSort: false
    }
  },
  computed: {
    classObject: function() {
      return {
        active: this.isActive,
        sort: this.isSort
      }
    }
  }

13.4数组方法


1.单纯数组
:class="[isActive,isSort]"
data() {
  return {
    isActive: 'active',
    isSort: 'sort'
  }
}

数组与三元运算符结合判断选择需要的class
三元运算符后面的“:”两边的class需要加上单引号

:class="[isActive?'active':'']"

或者

:class="[isActive==1?'active':'']"

或者

:class="[isActive==index?'active':'']"

或者

:class="[isActive==index?'active':'otherActiveClass']"

13.5 数组对象结合动态判断


//前面这个 active 在对象里面可以不加单引号,后面这个 sort 要加单引号

:class="[{ active: isActive }, 'sort']"

或者

:class="[{ active: isActive==1 }, 'sort']"

或者

:class="[{ active: isActive==index }, 'sort']"

应用于组件
如果直接在自定义组件中使用 class 或 :class,那么样式规则就会直接应在这个组件的根元素上。

<div id="app">
    <text-component :class="{'isStrong':isStrong}"></text-component>
</div>
<script>
    Vue.component('text-component', {
        template: '<p class="content">不懂基因测序的学霸不是好的人工智能公司 CEO</p>'
    });
    var app = new Vue({
        el: '#app',
        data: {
            isStrong: true
        }
    });
</script>

参考文档01
参考文档02


style三元表达式

<span v-bind:style="{'display':config.isHaveSearch ? 'block':'none'}" >动态绑定样式</span>

参考文档


也可以使用 v-bind:style 或 :style 直接给 HTML 元素绑定样式,它也有对应的对象语法与数组语法。

<div id="app">
    <div :style="border"></div>
</div>
<script>
    var app = new Vue({
        el: '#app',
        data: {
            border:{
                border:'1px solid #00F',
                textShadow:'0 0 .3em gray'
            }
        }
    });
</script>

因为 JS 属性不支持短横分隔命名,所以我们这里使用 CSS 也支持的驼峰命名法。


参考文档


计算属性computed


例:反转字符串:
<div id="app">
  <p>原始字符串: {{ message }}</p>
  <p>计算后反转字符串: {{ reversedMessage }}</p>
</div>
<script>
var vm = new Vue({
  el: '#app',
  data: {
    message: 'Runoob!'
  },
  computed: {
    // 计算属性的 getter
    reversedMessage: function () {
      // `this` 指向 vm 实例
      return this.message.split('').reverse().join('')
    }
  }
})
</script>

我们可以使用 methods 来替代 computed,效果上两个都是一样的,但是 computed 是基于它的依赖缓存,只有相关依赖发生改变时才会重新取值。而使用 methods ,在重新渲染的时候,函数总会重新调用执行。。换句话说,computed 是局部渲染,而 methods 是全部渲染
区别:


  • 1.methods是个方法,比如你点击事件要执行一个方法,这时候就用methods,
  • 2.computed是计算属性,实时响应的,比如你要根据data里一个值随时变化做出一些处理,就用computed。
  • 3.我们可以将同一函数定义为一个方法而不是一个计算属性。两种方式的最终结果确实是完全相同的。然而,不同的是计算属性是基于它们的依赖进行缓存的。计算属性只有在它的相关依赖发生改变时才会重新求值。这就意味着只要 message 还没有发生改变,多次访问 reversedMessage 计算属性会立即返回之前的计算结果,而不必再次执行函数。
  • 4.methods必须需要一定的条件去触发,而computed则不需要.
  • 5.computed依赖缓存,如果不需要经常变动的用computed,需要经常变动的用methods。如果你需要传参数,就用methods。



computed


computed 属性默认只有 getter ,不过在需要时你也可以提供一个 setter :

var vm = new Vue({
  el: '#app',
  data: {
    name: 'Google',
    url: 'http://www.google.com'
  },
  computed: {
    site: {
      // getter
      get: function() {
        return this.name + ' ' + this.url
      },
      // setter
      set: function(newValue) {
        var names = newValue.split(' ')
        this.name = names[0]
        this.url = names[names.length - 1]
      }
    }
  }
})
// 调用 setter, vm.name 和 vm.url 也会被对应更新
vm.site = 'http://www.runoob.com';
document.write('name: ' + vm.name);
document.write('<br>');
document.write('url: ' + vm.url);

从实例运行结果看在运行 vm.site = 'http://www.runoob.com'; 时,setter 会被调用, vm.name 和 vm.url 也会被对应更新。


十四、style样式绑定


class 与 style 是 HTML 元素的属性,用于设置元素的样式,我们可以用 v-bind 来设置样式属性。
Vue.js v-bind 在处理 class 和 style 时, 专门增强了它。表达式的结果类型除了字符串之外,还可以是对象或数组。


14.1 class 属性绑定


我们可以为 v-bind:class 设置一个对象,从而动态的切换 class:

<style>
.active {
    width: 100px;
    height: 100px;
    background: green;
}
</style>
<div id="app">
  <div v-bind:class="{ active: isActive }"></div>
</div>
<script>
new Vue({
  el: '#app',
  data: {
    isActive: true
  }
})
</script>

例:text-danger 类背景颜色覆盖了 active 类的背景色:


方法一:在对象中传入更多属性用来动态切换多个 class 。
<style>
.active {
    width: 100px;
    height: 100px;
    background: green;
}
.text-danger {
    background: red;
}
</style>
<div id="app">
  <div class="static"
     v-bind:class="{ active: isActive, 'text-danger': hasError }">
  </div>
</div>
<script>
new Vue({
  el: '#app',
  data: {
    isActive: true,
    hasError: true
  }
})
</script>
方法二:直接绑定数据里的一个对象:
<style>
.active {
    width: 100px;
    height: 100px;
    background: green;
}
.text-danger {
    background: red;
}
</style>
<div id="app">
  <div v-bind:class="classObject"></div>
</div>
<script>
new Vue({
  el: '#app',
  data: {
    classObject: {
      active: true,
      'text-danger': true
    }
  }
})
</script>
方法三:绑定返回对象的计算属性:
<style>
.active {
    width: 100px;
    height: 100px;
    background: green;
}
.text-danger {
    background: red;
}
</style>
<div id="app">
  <div v-bind:class="classObject"></div>
</div>
<script>
new Vue({
  el: '#app',
  data: {
  isActive: true,
  error: null
  },
  computed: {
    classObject: function () {
      return {
        active: this.isActive && !this.error,
        'text-danger': this.error && this.error.type === 'fatal',
      }
    }
  }
})
</script>
方法四:数组语法
<style>
.active {
    width: 100px;
    height: 100px;
    background: green;
}
.text-danger {
    background: red;
}
</style>
<div id="app">
    <div v-bind:class="[activeClass, errorClass]"></div>
</div>
<script>
new Vue({
  el: '#app',
  data: {
    activeClass: 'active',
    errorClass: 'text-danger'
  }
})
</script>

还可以使用三元表达式来切换列表中的 class :
errorClass 是始终存在的,isActive 为 true 时添加 activeClass 类:

<style>
.text-danger {
    width: 100px;
    height: 100px;
    background: red;
}
.active {
    width: 100px;
    height: 100px;
    background: green;
}
</style>
<div id="app">
    <div v-bind:class="[errorClass ,isActive ? activeClass : '']"></div>
</div>
<script>
new Vue({
  el: '#app',
  data: {
    isActive: true,
    activeClass: 'active',
    errorClass: 'text-danger'
  }
})
</script>

style样式邦定


v-bind:style直接设置样式:

<div id="app">
    <div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }">菜鸟教程</div>
</div>
<script>
new Vue({
  el: '#app',
  data: {
    activeColor: 'green',
    fontSize: 30
  }
})
</script>

也可以直接绑定到一个样式对象:

<div id="app">
  <div v-bind:style="styleObject">菜鸟教程</div>
</div>
<script>
new Vue({
  el: '#app',
  data: {
    styleObject: {
      color: 'green',
      fontSize: '30px'
    }
  }
})
</script>

v-bind:style 可以使用数组将多个样式对象应用到一个元素上:

<div id="app">
  <div v-bind:style="[baseStyles, overridingStyles]">菜鸟教程</div>
</div>
<script>
new Vue({
  el: '#app',
  data: {
    baseStyles: {
      color: 'green',
      fontSize: '30px'
    },
    overridingStyles: {
      'font-weight': 'bold'
    }
  }
})
</script>

参考文档


十五、vue组件参数传递:


Vue 组件间通信包括:父子组件间通信,兄弟组件间通信以及模块之间通信等。Vue 是数据驱动视图更新的框架, 所以对于 Vue 来说组件间的数据通信非常重要。Vue 实现组件间通信有很多方式,今天我来给大家讲解一下父子组件间通信:props 和$emit。


15.1.子组件向父组件传递参数;


image.png


子组件 A:

    <template>
      <div class="childA-wrapper">
        子组件A
      </div>
    </template>
    <script>
    export default {
      data() {
        return {
          childA: '我是组件A传过来的值'
        }
      },
      created: function() {},
      mounted() {
        this.sendDataParent()
      },
      methods: {
        sendDataParent() {
          // getChildDataA是在父组件on监听的方法
          // 第二个参数this.childA是需要传的值
          this.$emit('getChildDataA', this.childA)
        }
      }
    }
    </script>

子组件 B:

  <template>
  <div class="childB-wrapper">
    子组件B
  </div>
</template>

<script>
export default {
  data() {
    return {
      childB:'我是组件B传过来的值'
    }
  },
  created:function() {
  },
  mounted(){
    this.sendDataParent()
  },
  methods: {
   sendDataParent() {
        // getChildDataB是在父组件on监听的方法
        // 第二个参数this.childB是需要传的值
        this.$emit('getChildDataB', this.childB)
      }
  }
}
</script>

父组件:

  <template>
        <div>
            <v-childA v-on:getChildDataA="getChildDataA"></v-childA>
            <v-childB v-on:getChildDataB="getChildDataB"></v-childB>
            <div>获取组件A传过来的值:{{childAValue}}</div>
            <div>获取组件B传过来的值:{{childBValue}}</div>
        </div>
    </template>

    <script>
    import childA from '@/components/childA.vue'
    import childB from '@/components/childB.vue'
    export default {
      data() {
        return {
            childAValue:'',
            childBValue:'',
        }
      },
      methods: {
       getChildDataA(childA){
        console.log(childA)
        this.childAValue=childA
       },
       getChildDataB(childB){
        console.log(childB)
        this.childBValue=childB
       }
      },
      components: { 'v-childA': childA, 'v-childB': childB}
    }
    </script>


vue项目实战:实战技巧总结(下):https://developer.aliyun.com/article/1483360

相关文章
|
1天前
|
资源调度 JavaScript 前端开发
【vue】vue中的路由vue-router,vue-cli脚手架详细使用教程
【vue】vue中的路由vue-router,vue-cli脚手架详细使用教程
|
1天前
|
JavaScript 前端开发
vue组件化开发流程梳理,拿来即用
vue组件化开发流程梳理,拿来即用
|
1天前
|
JavaScript Go
Vue路由跳转及路由传参
Vue路由跳转及路由传参
|
2天前
|
JavaScript 前端开发 BI
采用前后端分离Vue,Ant-Design技术开发的(手麻系统成品源码)适用于三甲医院
开发环境 技术架构:前后端分离 开发语言:C#.net6.0 开发工具:vs2022,vscode 前端框架:Vue,Ant-Design 后端框架:百小僧开源框架 数 据 库:sqlserver2019
采用前后端分离Vue,Ant-Design技术开发的(手麻系统成品源码)适用于三甲医院
|
4天前
|
监控 JavaScript
Vue中的数据变化监控与响应——深入理解Watchers
Vue中的数据变化监控与响应——深入理解Watchers
|
4天前
|
JavaScript 安全 前端开发
Vue 项目中的权限管理:让页面也学会说“你无权访问!
Vue 项目中的权限管理:让页面也学会说“你无权访问!
14 3
|
4天前
|
JavaScript 前端开发 开发者
Vue的神奇解锁:冒险的开始
Vue的神奇解锁:冒险的开始
5 1
|
JavaScript 测试技术 容器
Vue2+VueRouter2+webpack 构建项目
1). 安装Node环境和npm包管理工具 检测版本 node -v npm -v 图1.png 2). 安装vue-cli(vue脚手架) npm install -g vue-cli --registry=https://registry.
982 0
|
5天前
|
JavaScript
【vue】如何跳转路由到指定页面位置
【vue】如何跳转路由到指定页面位置
8 0
|
5天前
|
JSON JavaScript 前端开发
【vue】假数据的选择和使用
【vue】假数据的选择和使用
11 1