vue学习笔记

28 篇文章 0 订阅
20 篇文章 0 订阅

1.v-once,只渲染一次

<h1 v-once>{{message}}</h1>

2.v-html,按照html格式渲染

<h2 v-html="url"> {{ url }} </h2>

url : '<a href="http://www.baidu.com">百度一下</a>'

3.v-pre,不解析mustacche语法

 <h1 v-pre>{{ message +' '+ name}}</h1>

4.v-cloak,vue渲染完后再显示mustache变量(项目中使用虚拟dom,一般用不到)

<style>
        div[v-cloak]{
            display: none;
        }
</style>

<div id="app" v-cloak>
        <h1>{{ message +' '+ name}}</h1>
    </div>

5.v-bind对元素动态添加、移除类

<style>
        .redClass{
            color: red;
        }
        .greenClass{
            color: gold;
        }
        .title{
            font-size: 50px;
        }
</style>


 <h1 class="title" :class="{redClass: redClass,greenClass:greenClass}">{{ message +' '}}</h1>

data : {
                message : 'hello Mr tree',
                redClass : true,
                greenClass : true
},

6.虚拟dom复用:

vue在对dom元素进行渲染的时候,会尽可能复用已经存在的元素,而不是重新创建

下面代码如果不加key,则切换登陆的时候,input框会保留原来的值,加key可让vue不复用元素

<div v-if="isShow">
            <label for="account">账号登陆</label>
            <input type="text" id="account" placeholder="账号登陆" key="account">
        </div>
        <div v-else>
            <label for="tel">手机登陆</label>
            <input type="text" id="tel" placeholder="手机登陆" key="tel">
        </div>
        <div @click="isShow=!isShow">切换登陆</div>

6.v-for遍历对象的键、值、索引:

<ul>
     <li v-for="(item,key,index) in obj">{{ key }}.{{ item }}.{{index}}</li>
</ul>

7.Vue.set()/this.$set()响应式修改数据

Vue.set(app.arr,index,33)

this.$set(this.arr,index,6666)

//更深层次的数组对象
this.skuDataChildren.map((item,index)=>{
	item.specValues.map((item2,index2)=>{
		item2.statu=1
		this.$set(this.skuDataChildren[index].specValues,index2,item2)
	})
})

8.组件父传子

<div id="app">
        <cpn :c-movies="movies" :c-message-last="message"></cpn>
    </div>
props : {
                cMovies : {
                type : Array,
                default(){
                    return ["无极","霸王别姬","英雄"]
                },
            },  
            cMessageLast : {
                type : String,
                default : '你好,李焕英',
                required : true
            }
        },

9.组件子传父

<div id="app" >
        <cpn @inc="inc" @dec="dec" :c-movies="movies" :c-message-last="message"></cpn>
    </div>
//子组件methods
methods : {
            inc(){
                this.counter++
                this.$emit("inc",this.counter)
            },
            dec(){
                this.counter--
                this.$emit("dec",this.counter)
            }
        },

//父组件methods
methods : {
            inc(val){
                console.log("父组件",val);
            },
            dec(val){
                console.log(`父组件${val}`);
            }
        },

10.子组件props实时更新传递到父组件

1.v-bind绑定属性,再input监听

<div id="app" >
        <h3>父组件num1:{{num1}}</h3>
        <cpn @inc="inc" @dec="dec" :c-movies="movies" :c-message-last="message" :num1="num1" @childchange="childchange"></cpn>
    </div>

//子组件
<h5>{{ num1 }}</h5>
            <h5>dNum1 : {{ dNum1 }}</h5>
            <input type="text" :value="dNum1" @input="clickChange">
//子组件methods
clickChange($event){
                this.dNum1=$event.target.value
                this.$emit("childchange",this.dNum1)
            }

//父组件methods
childchange(val){
                console.log(val);
                this.num1=Number(val) 
            }

2.v-model双向绑定data内变量,再watch监听

//子组件
<input type="text" v-model="dNum1" >
//子组件data
data(){
            return {
                dNum1 : this.num1
            }
        },

//子组件watch
watch : {
            dNum1(newValue,oldValue){
                this.$emit("childchange",newValue)
            }
        },

11.el与template的区别

//最终vue会将template的内容代替el

new Vue({
    el : '#app',
    template : `
    <div>
        <h1>{{message}}</h1>
        <button @click="btnclick">单击</button>
    </div>
    `,
    data : {
        message : 'hello,树先生'
    },
    methods: {
        btnclick(){
            console.log("click a btn");
        }
    },
})

12.webpack加载vue文件

npm install vue-loader vue-template-compiler -D

module : {
        rules : [
            {
                test : /\.vue$/,
                use : ["vue-loader"]
            }
        ]
    },

plugins : [
        new VueLoaderPlugin()
    ],

13.vue-cli项目历史配置

C:\Users\Administrator\.vuerc

14.修改vue-cli webpack配置

1.指令:vue ui

2.node_modules里面的@vue文件夹里面的webpack.config.js

3.在项目主目录下创建vue.config.js,该配置文件将自动与@vue文件夹里面的webpack.config.js合并

15.路由设置history模式

const router=new createRouter({
    history : createWebHistory(process.env.BASE_URL),
    routes,
    mode : 'history'
})

16.默认页重定向

const routes=[
    {
        path : '/',
        redirect : '/about',
    },
    {
        path : '/home',
        component : Home,
    },
    {
        path : '/about',
        component : About
    }
]

17.所有组件都继承自vue原型

所以Vue.prototype.$router=router后,组件内部能使用this.$router

18.路由守卫

//全局守卫

//前置钩子/前置守卫(guard)
router.beforeEach((to,from,next)=>{
    console.log(from);
    document.title=to.meta.title
    console.log("前置");
    next()
})

//后置钩子(hook)
router.afterEach((to,from)=>{
    console.log("后置",to);
})
//路由独享守卫
const routes=[
    {
        path : '/home',
        component : Home,
        meta : {
            title : '首页',
            abc : 'abc'
        },
        beforeEnter: (to, from, next) => {
            // ...
            next()
        }
    },
]
//组件内守卫

const Foo = {
  template: `...`,
  beforeRouteEnter(to, from, next) {
    // 在渲染该组件的对应路由被 confirm 前调用
    // 不!能!获取组件实例 `this`
    // 因为当守卫执行前,组件实例还没被创建
  },
  beforeRouteUpdate(to, from, next) {
    // 在当前路由改变,但是该组件被复用时调用
    // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
    // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
    // 可以访问组件实例 `this`
  },
  /* 离开组件时,保留路由地址用,使得再次打开页面时显示离开时路由页面  */
  beforeRouteLeave(to, from, next) {
    // 导航离开该组件的对应路由时调用
    // 可以访问组件实例 `this`
  }
}

19.keep-alive

保持组件存在,组件缓存,路由跳转时不被unmounted

注意:vue3的keep-alive方法不兼容vue2的组件

//生命周期函数activated与deactivated函数只有在keep-alive内有效
activated() {
        console.log("actived");
        this.$router.push(this.path)
    },
    deactivated() {
        console.log("deactivated");
    },

//exclude : 被匹配的内部组件不进行缓存
//include : 被匹配的内部组件进行缓存
<router-view v-slot="{ Component }">
      <keep-alive exclude="User,Profile">
        <component :is="Component" />
      </keep-alive>
    </router-view>


//缓存整个组件
<router-view v-slot="{ Component }">
        <keep-alive>
          <component :is="Component" v-if="$route.meta.keepAlive"></component>
        </keep-alive>
        <component :is="Component" v-if="!$route.meta.keepAlive"></component>
      </router-view>

//路由配置
{
    path : '/home',
    component : allRoutes.Home,
    meta : {
      keepAlive : true
    }
  },


//配合记录scrollY,使页面保持原来位置
activated(){
        this.$refs.scroll.refresh()
        this.$refs.scroll.scrollTo(0,this.scrollY,0)
    },
    deactivated(){
        this.scrollY=this.$refs.scroll.getScrollY()
        
    },

20.路径别名

改完必须重新启动项目

module.exports = {
  configureWebpack: {
    resolve : {
      alias : {
        "assets" : "@/assets",
        "components" : '@/components',
        "views" : "@/views",
      }
    }
  }
}

html内写法:

<img src="~assets/img/tabBar/p2.svg" alt="" style="width:30px;height:30px;">

21.组件内监听vuex值变化

可用于监听某组件元素异步加载后,记录在vuex内的变量值,然后组件内监听vuex的变量值做相应动作

例如:监听图片异步加载,修改页面scroll高度

子组件:

<img :src="detail.img" alt="" @load="imgLoad">
imgLoad(){
      this.$store.commit("addImgLoadCount")
}

vuex:

state: {
    imgLoadCount : 0
  },
  mutations: {
    addImgLoadCount(state){
      state.imgLoadCount++
    }
  },

其他组件监听:

watch: {
        "$store.state.imgLoadCount"(newVal,oldVal){
            console.log(newVal,oldVal,"组件监听");
            this.$refs.scroll.refresh()
        }
    },

22.mixins

Mixin 提供了一种非常灵活的方式,来分发 Vue 组件中的可复用功能。一个 mixin 对象可以包含任意组件选项。当组件使用 mixin 对象时,所有 mixin 对象的选项将被“混合”进入该组件本身的选项。(官网原话)

//使用方法

//common/mixins.js
export const mixins={
    mounted(){
        console.log("混入对象执行");
    }
}

//组件内引入
import { mixins } from "common/mixins"
data(){
    return {
    
    }
},
mixins : [mixins],

23.封装插件

1.编写组件 Toast.vue


<template>
    <div class="toast" v-show="isShow">
        <div>{{ msg }}</div>
    </div>
</template>
 
<script>
export default {
    name: 'Toast',
    data(){
        return {
            msg : "",
            isShow : false
        }
    },
    methods : {
        show(msg="nihao",duration=2000){
            this.msg=msg

            this.isShow=true

            setTimeout(()=>{
                this.isShow=false
                this.msg=""
            },duration)
        }
    }
}
</script>
 
<style scoped lang = "scss">
    .toast{
        position: fixed;
        top: 50%;
        left: 50%;
        transform: translate(-50%,-50%);
        div{
            padding: 8px 10px;
            color: #fff;
            background-color: rgba($color: #000000, $alpha: 0.6);
        }
    }
</style>

2.编写封装文件 index.js,与组件同一个目录

import Toast from "./Toast"
import { createApp } from 'vue'
const obj={
    install: function(app){
            const toast=createApp(Toast)
            const instance=toast.mount(document.createElement("div"))
            document.body.appendChild(instance.$el)
            app.config.globalProperties.$Toast=instance
        }
}

export default obj

3.调用插件

this.$Toast.show()

24.px2vw

npm install postcss-px-to-viewport --save-dev

//postcss.config.js,与vue.config.js同目录
module.exports = {
    plugins: {
        "autoprefixer": {
            path: ['./src/*']
        },
        "postcss-import": {},
        "postcss-px-to-viewport": {
            "viewportWidth": "375", //视窗的宽度,对应的是我们设计稿的宽度
            "viewportHeight": "667", // 视窗的高度
            "unitPrecision": 2, //指定`px`转换为视窗单位值的小数位数(很多时候无法整除)
            "viewportUnit": "vw", //指定需要转换成的视窗单位,建议使用vw
            "fontViewportUnit": 'vw',
            "selectorBlackList": ['#nprogress'], //指定不转换为视窗单位的类
            "minPixelValue": 1, // 小于或等于`1px`不转换为视窗单位
            "mediaQuery": false, // 允许在媒体查询中转换`px`
             //"exclude": [/TabBar/,/ItemList/]
        },
    }
}
  

25.项目布置到服务器

1.vue.config.js配置publicPath,否则css,js文件引用路径不对

module.exports={
    publicPath : "./",
}

2.路由配置哈希模式,否则router-view页面显示空白

//router/index.js
const router = createRouter({
  //history: createWebHistory(process.env.BASE_URL),
  history: createWebHashHistory(process.env.BASE_URL),
  routes
})

export default router

26.nextTick

vue内的Dom元素是异步更新的,改变data值后,Dom元素需要通过nextTick获取,否则得到的是原值

<div ref="msgDiv">{{msg}}</div>
<div v-if="msg2">Message got inside $nextTick: {{msg2}}</div>
this.msg = "Hello world."
this.$nextTick(() => {
     this.msg2 = this.$refs.msgDiv.innerHTML
})

  • 在Vue生命周期的created()钩子函数进行的DOM操作一定要放在Vue.nextTick()的回调函数中

created()钩子函数执行的时候DOM 其实并未进行任何渲染,而此时进行DOM操作无异于徒劳,所以此处一定要将DOM操作的js代码放进Vue.nextTick()的回调函数中。与之对应的就是mounted()钩子函数,因为该钩子函数执行时所有的DOM挂载和渲染都已完成,此时在该钩子函数中进行任何DOM操作都不会有问题 。

  • 在数据变化后要执行的某个操作,而这个操作需要使用随数据改变而改变的DOM结构的时候,这个操作都应该放进Vue.nextTick()的回调函数中。

27.vue-cli4在Vue上绑定原型链属性

//main.js

import * as echarts from 'echarts'

const app = createApp(App)
app.use(store).use(router)
app.config.globalProperties.$echarts = echarts
app.mount('#app')
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

y_w_x_k

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值