vue2.x 技术胖学习总结

这里对自己学习技术胖vue2.x的部分过程做出记录。

1.v-if和v-show区别

v-if:判断是否加载dom点
优点:减轻了服务器的压力
v-show:判断是否展示,调整了css的display属性
优点:使客户端操作更加流畅

2.v-text和v-html

①使用场景:
v-text:{{xxx}}有一定的弊端,当js代码出错的时候会显示出源码,v-text,就是解决这个问题的。
<span>{{ message }}</span>等同于<span v-text="message"></span>

v-html:当内容含有html标签的时候v-text无法解析,此时需要使用v-html。涉及到起安全性问题以及使用场景,在生产环境中动态渲染HTML是非常危险的,因为容易导致XSS攻击。所以只能在可信的内容上使用v-html,永远不要在用户提交和可操作的网页上使用。
ps:cookie安全策略
在服务器端设置cookie的时候设置 http-only, 这样就可以防止用户通过JS获取cookie。对cookie的读写或发送一般有如下字段进行设置:
http-only: 只允许http或https请求读取cookie、JS代码是无法读取cookie的(document.cookie会显示http-only的cookie项被自动过滤掉)。发送请求时自动发送cookie.
使用方法:response.setHeader( "Set-Cookie" , "cookiename=httponlyTest;Path=/;Domain=domainvalue;Max-Age=seconds;HTTPOnly");
secure-only: 只允许https请求读取,发送请求时自动发送cookie。
host-only: 只允许主机域名与domain设置完成一致的网站才能访问该cookie。

3.内部指令(v-pre、v-clock 、v-once)

v-pre:跳过编译,以{{xxx}}的形式展现在页面上
v-cloak:和css配合使用,渲染完指定的整个dom再显示
css:

[v-cloak] {
  display: none;
} 

html/template:

<div v-cloak>
  {{message}}
</div>

v-once:指定部分只渲染一次,再渲染时为静态,不参与之后的渲染,在静态内容很多的页面能明显提高页面渲染效率,但是需要在编程前提前计算好哪些是只渲染一次的元素。

4.自定义指令Vue.directive

<div id="app">
    <span v-jcolor="color">{{num}}</span>
</div>
<script type="text/javascript">
    Vue.directive('jcolor', function (el, binding, vnode) {
        el.style = 'color:' + binding.value;
    });
    var app = new Vue({
        el: "#app",
        data: {
            num: 10,
            color: "green"
        }
    })
</script>

自定义指令三个重要参数:

  • el: 指令所绑定的元素,可以用来直接操作DOM。

  • binding: 一个对象,包含指令的很多信息。


    该例中的binding
  • vnode: Vue编译生成的虚拟节点。

5.Vue.set(绑定在Vue的构造函数上)/this.$set(绑定在Vue的原型上)

存在意义:
由于js的限制,无法检测以以下两种情况动态变化的数组:
①通过索引改变数组某项变化的值得情况
②改变数组长度的情况
使用场景:

<div id="app">
    <ul>
        <li v-for=" aa in arr">{{aa}}</li>
    </ul>
    <button @click="add()">外部添加</button>
</div>
<script type="text/javascript">
    var app = new Vue({
        el: '#app',
        data() {
            return {
                arr : ['aaa', 'bbb', 'ccc']
            }
        },
        methods: {
            add() {
                console.log("我已经执行了");
                this.arr[1] = 'ddd';//情况①,通过数组索引改变值
                this.arr.length = 2;//情况②,改变数组长度
                //    Vue.set(this.arr,1,'ddd');//情况①解决方案通过set实现/replace
                //    this.arr.splice(2);//情况②通过splice直接增删数组,改变数组长度
            }
        }
    })
</script>

页面原效果以及点击外部添加之后数据没有变化

set后生效

这里有一个现象:如果这里放开赋值的注释,将arr[1]set为'ddd',前面的this.arr.length = 2也会生效,这里涉及到Vue.set的实现原理,留下问题,日后研究。

6.delimiters

有时用到其他系统自带标签也为{{}},vue默认{{}}插值,产生冲突,此时就需要用delimiters修改插值符号,数组形式,一前一后,如:delimiters:['${','}']
此时插值符号为${}

7.vue-router

(1)带参数
①params传参(通过<router-link> 标签中的to传参 )
父组件中:

<router-link :to="{name:xxx,params:{username:'test'}}">valueString</router-link>

子组件中
通过{{$route.params.username}}直接获取
②url传参(router/index.js中配置)
在router/index.js文件中:

export default new Router({
  routes: [
    {
      path: '/',
      component: Hello
    },{
      path:'/params/:newsId(\\d+)/:newsTitle', 
      component:Params//带参数(拼接url且newsId为整数)
    }
 ]
})

在Params组件中:
{{$route.params.newsId}}/{{$route.params.newsTitle}}可取到相应值
(2)重定向(redirect、alias两种方法)

export default new Router({
  routes: [
    {
      path: '/',
      component: Hello
    },{
      path:'/goback',
      redirect:'/'//重定向改变url
    },{
      path:'/goParams/:newsId(\\d+)/:newsTitle',
      redirect:'/params/:newsId(\\d+)/:newsTitle'//重定向时传参
    },{
      path: '/hi1',
      component: Hi1,
      alias:'/bieming'
      //别名,配合<router-link to="/bieming">重定向</router-link>使用,重定向不改变url只改变router-view,更                      加友好,但是不支持path为'/'的情况
   }
 ]
})

(3)路由加动画过渡效果
①给过渡效果标签:name、mode(非必须)
mode:

  • in-out:新元素先进入过渡,完成之后当前元素过渡离开。
  • out-in:当前元素先进行过渡离开,离开完成后新元素过渡进入。
<transition name="fade" mode="out-in">
  <router-view ></router-view>
</transition>

②给过渡效果定义css样式
name:
fade-enter:进入过渡的开始状态,元素被插入时生效,只应用一帧后立刻删除。
fade-enter-active:进入过渡的结束状态,元素被插入时就生效,在过渡过程完成后移除。
fade-leave:离开过渡的开始状态,元素被删除时触发,只应用一帧后立刻删除。
fade-leave-active:离开过渡的结束状态,元素被删除时生效,离开过渡完成后被删除。

eg:透明动画过渡效果

.fade-enter {
  opacity:0;
}
.fade-leave{
  opacity:1;
}
.fade-enter-active{
  transition:opacity .5s;
}
.fade-leave-active{
  opacity:0;
  transition:opacity .5s;
}

(4)路由mode设置以及404页面设置
①mode:包括history和hash两种,两者区别即url上是否有#,history无#,比较美观,推荐使用。

export default new Router({
  mode: 'history',
  routes: [
    {
      path: '/',
      component: Hello
    }
 ]
})

②404页面配置
如果用户在url上输入的页面不存在,前端做出处理即显示404页面,给用户以提示,对用户更加友好。
实现方式:
第一步:在router/index.js文件下给出未配置路由(即不存在url)的情况

{
   path:'*',
   component:Error
}

第二步:写error组件,当访问到页面不存在时显示该页面
(5)路由钩子
两种位置可以使用:
①router/index.js
路由中仅可以使用beforeEnter。
eg:

    {
      path: '/testGouzi',
      name: 'TestGouzi',
      component: TestGouzi,
      beforeEnter: (to, from, next) => {
        console.log('to', to);
        console.log('from', from);
        next();
      }

②要对离开或进入该路由进行判断的组件中。

eg:

export default {
  name: "HelloWorld1",
  data() {
    return {};
  },
  beforeRouteEnter: (to, from, next) => {
    alert("我进来了1");
    next();
  },
  beforeRouteLeave: (to, from, next) => {
    alert("我走了1");
    next();
  },
};

(6)编程式导航
①返回上一级:this.$router.go(-1);
②返回下一级:this.$router.go(1);
③跳转到某页面(此例为跳转为home页):this.$router.push('/');
ps:在使用push进行路由跳转的时候存在一个问题,即在一个页面重复调用该函数会报如下错误:

路由重复报错

解决方案:在router/index.js中对Router原型上的push进行处理,此种方法事实上只是将报错catch,使之不在控制台飘红报错。

import Router from 'vue-router'
Vue.use(Router)

//获取原型对象上的push函数
const originalPush = Router.prototype.push
//修改原型对象中的push方法
Router.prototype.push = function push(location) {
  return originalPush.call(this, location).catch(err => err)
}

④带参数跳转

      this.$router.push({ path: "/", query: { msg: "我带着path的参数query回家啦" } });
      this.$router.push({ name: "HelloWorld", query: { msg: "我带着不太规范的name的query参数回家啦" } });
      this.$router.push({ name: "HelloWorld", params: { msg: "我带着参数params回家啦" } });

以上三种写法均可行,query带参数会体现在url上,params不会,params传参仅可用name指向路由。

8.vuex

vuex的使用主要需要掌握以下5点:

  • state访问状态
  • mutations修改状态
  • getters计算过滤操作
  • actions异步修改状态
  • module模块组
    准备工作

①利用npm安装vuex

npm install vuex --save

②建vuex文件夹,建store.js文件,并在文件中进行vuex引用

import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);

(1)state访问状态
需要引用vuex状态管理的组件,这里统一叫做count.vue。
①store.js

const state = {  
  count: 1
}
export default new Vuex.Store({
  state
})

②count.vue(共有3种方法可以取state)

<template>
    <div>
    <!--state 法一 -->
    <!-- <h3>{{ $store.state.count }}</h3> -->
    <!-- 法二 computed返回的count/法三 (写法1、2)mapstate-->
    <h3>{{ count }}</h3>
    </div>
</template>
<script>
    import store from '@/vuex/store'
    export default{
        data(){
            return{
            }
        },
  //  法二
  //   computed: {
  //     count() {
  //         return this.$store.state.count;
  //     },
  //   },
  //  法三 mapstate 写法一箭头函数
  //   computed: mapState({
  //     count: (state) => state.count,
  //   }),
  //  法三 mapstate 写法二数组
        computed: mapState(["count"]),
        store
    }
</script>

(2)mutations修改状态
Vuex提供commit方法来修改状态:$store.commit( )
①store.js

const mutations = {
    // 传参
    add(state, n) {
        state.count += n;
    },
    reduce(state) {
        state.count--;
    }
}
export default new Vuex.Store({
  state,mutations
})

②count.vue(两种方法)

<template>
    <div>
      <!--mutations 法一 -->
      <!-- <button @click="$store.commit('add', 10)">+</button> -->
      <!-- <button @click="$store.commit('reduce')">-</button> -->
      <!-- mutations 法二 -->
      <button @click="reduce">-</button>
    </div>
</template>
<script>
import store from "@/vuex/store";
// 这里注意一定要加大括号
import { mapMutations, mapState } from "vuex";
export default {
  data() {
    return {
    };
  },
  //由于vue构造器里面只能有一个methods属性所以用对象展开符对其进行修改
  //   mutations 法二
  methods: {
     ...mapMutations(["reduce"]),
  }
  },
  store,
};
</script>

(3)getters计算过滤操作
这里以在它输出前+100作为操作示例,下图为刚进入页面时的效果,已知$store.state.count初始值为1,可见其刚开始进入页面的时候就执行了getters+100的操作,可通过点击加减按钮看到getters的处理。

初始图

①store.js

const getters = {
    count: function (state) {
        return state.count += 100;
    }
}
export default new Vuex.Store({
  state,getters
})

②count.vue(两种方法)

<template>
    <div>
    <h3>{{ count }}</h3>
    <div>
      <button @click="$store.commit('add', 10)">+</button>
      <button @click="$store.commit('reduce')">-</button>
    </div>
    </div>
</template>
<script>
import store from "@/vuex/store";
// 这里注意一定要加大括号
import { mapState, mapGetters } from "vuex";
export default {
  data() {
    return {
    };
  },
  computed: {
    // ...mapState(["count"]),
    // getters 法一
    //   count() {
    //       return this.$store.getters.count
    //   }
    // getters 法二 mapGetters
    ...mapGetters(["count"]),
  },
  store,
};
</script>

(4)actions异步修改状态
此块存在的灵魂在于异步,所以这里使用setTimeout进行异步操作,这里点击add执行的顺序应是先加10,两秒后再减1,控制台输出文字的顺序应该在count减一之前。
①store.js(两种写法)

const actions = {
    // context上下文/commit对象作为参数两种写法
    addActions(context) {
        console.log(context);
        context.commit('add', 10);
        // 异步看看
        setTimeout(() => { context.commit('reduce') }, 2000)
        console.log('我比异步那个先执行了')
    },
    reduceActions({ commit }) {
        commit('reduce')
    }
}

②count.vue
触发组件中addActions方法来感受异步。

<template>
  <div>
    <h3>{{ count }}</h3>
    <p>异步看看</p>
    <p>
      <button @click="addActions">+</button>
      <button @click="reduceActions">-</button>
    </p>
  </div>
</template>

<script>
import store from "@/vuex/store";
import { mapState,mapActions } from "vuex";
export default {
  data() {
    return {
    };
  },
  methods: {
    // actions
    ...mapActions(["addActions", "reduceActions"]),
  },
  computed: {
    ...mapState(["count"]),
  },
  store,
};
</script>

(5)module模块组
建议在项目比较复杂的情况用module模块
①store.js

const moduleA={ state,mutations,getters,actions}
export default new Vuex.Store({
    modules:{a:moduleA}
})

②count.vue(两种引用方法)

<!-- 法一 -->
<h3>{{$store.state.a.count}}</h3>
<!-- 法二 -->
computed:{
    count(){
        return this.$store.state.a.count;
    }
},
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,560评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,104评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,297评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,869评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,275评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,563评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,833评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,543评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,245评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,512评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,011评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,359评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,006评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,062评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,825评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,590评论 2 273
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,501评论 2 268

推荐阅读更多精彩内容