vue3自学笔记

创建项目:
npm init vue@latest
拿到项目 看看有没有node modules
没有的话先nmp install 安装
启动 npm run serve/ npm run dev

1.模板语法
双括号:文本中的数据绑定仅仅支持单一表达式(就是能被求值的JS代码), 简单判断方法:是否可以放在return后面

2.属性绑定
v-bind,简写是 :

<!-- 绑定属性 -->
<a v-bind:href="url">点击这里</a>

<!-- 简写形式 -->
<a :href="url">点击这里</a>

eg:

new Vue({
  el: '#app',
  data: {
    url: 'https://www.example.com'
  }
});
<div id="app">
  <a :href="url">点击这里</a>
</div>

双括号 ({{ }}):适合简单的数据绑定,例如显示文本内容。
v-bind:适合需要动态绑定属性值的场景,如动态改变链接地址、类名、样式等

3.条件渲染

<template>
    <h3>条件渲染</h3>
    <div v-if="flag">can u see me</div>
    <div v-else>还是看我</div>

    <div v-if="type ==='A' ">A</div>
    <div v-else-if="type ==='B'">B</div>
    <div v-else-if="type ==='C'">C</div>
    <div v-else>not ABC</div>

    <div v-show="flag" >can u see me</div>
</template>


<script>

export default{
    data()
    {
        return{
            flag:false,
            type:"D"
        }
    }
}

</script>

显示

条件渲染
还是看我
not ABC

v-if 和 v-show 的区别

  • v-if 是“真正的”条件渲染,因为它会确保在切换过程中,条件块内的事件监听器和子组件适当地被销毁和重建。
  • v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。

相比较下,v-show 就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。

  • 一般来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。

4.列表渲染

<template>
<h3>列表渲染</h3>
<p v-for="name in names">{{ name }}</p>

<div>
    <p v-for="(value,key,index) of userinfo" >{{ value }}-{{ key }}-{{ index }}</p>
</div>

</template>


<script>
    export default
    {
        data()
        {
            return {
                names:["小红","小王","小芳"],
                userinfo:{
                name:"sdas",
                age:21,
                sex:"男"
        }
            }
        },

        
    }
</script>

输出

列表渲染
小红

小王

小芳

sdas-name-0

21-age-1

男-sex-2
<p v-for="(value, key, index) in userinfo" :key="key">{{ value }} - {{ key }} - {{ index }}</p>

v-for:这是 Vue.js 中的指令,表示循环遍历。
(value, key, index):这三个是循环的变量。
value:当前遍历到的属性的值。
key:当前遍历到的属性的键。
index:当前遍历的索引,从 0 开始。

key的“就地更新”的策略

当 Vue 正在更新使用 v-for 渲染的元素列表时,它默认使用“就地更
新”的策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素
来匹配数据项的顺序,而是就地更新每个元素,并且确保它们在每
个索引位置正确渲染。
为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和
重新排序现有元素,你需要为每项提供一个唯一的 key attribute:

2024.7.4

5.事件处理
我们可以使用 v-on 指令 (通常缩写为 @ 符号) 来监听 DOM 事件,
并在触发事件时执行一些 JavaScript。用法为v-on:click="methodName"
使用快捷方式 @click="methodName"

事件处理器 (handler) 的值可以是:

内联事件处理器:事件被触发时执行的内联 JavaScript 语句 (与 onclick 类似)。

方法事件处理器:一个指向组件上定义的方法的属性名或是路径。

<template>
<h3>内联事件处理器1</h3>

<!-- button按钮实现累加的操作 -->
<button v-on:click="count++">Add</button>
<p>{{count}}</p>

</template>



<script>
export default{
    data()
    {
        return{
            count:0
        }
    }
}

</script>

<template>
    <h3>内联事件处理器2</h3>
    
    
    <button v-on:click="addcount">Add</button>
    <p>{{count}}</p>
    
    </template>
    
    
    
    <script>
    export default{
        data()
        {
            return{
                count:0
            }
        },

        methods: {
            addcount()
            {
                this.count+=1,
                console.log("点击了")
            }
        },
    }
    
    </script>


<template>
    <h3>内联事件处理器3</h3>
    
    <!-- 获取event对象 -->

    <button v-on:click="addcount">Add</button>
    <p>{{count}}</p>
    
    </template>
    
    
    
    <script>
    export default{
        data()
        {
            return{
                count:0
            }
        },

        methods: {
            addcount(e)
            {
                this.count++;
                e.target.innerHTML = "Add" +this.count;
                
            }
        },
    }
    
    </script>


<template>
    <h3>内联事件处理器4传递参数</h3>
    <!-- 点击哪个名字就获取哪个 -->    <p @click= "getNameHandler(item)"  v-for="(item,index) of names" :key="index">{{ item }}</p>
 

   
    
    </template>
    
    
    
    <script>
    export default{
        data()
        {
            return{
                names:["iwe","sad","sda"],
            }
        },

        methods: {
            getNameHandler(name)
            {
                console.log(name);
            }
        },
    }
    
    </script>

6.事件修饰符

常用事件修饰符:
1.prevent:阻止浏览器默认事件(常用);
​ 2.stop:阻止事件冒泡(常用);
​ 3.once:事件只触发一次(常用);
​ 4.capture:使用事件的捕获模式;
​ 5.self:只有 event.target 是当前操作的元素时才触发事件;
​ 6.passive:事件的默认行为立即执行,无需等待事件回调执行完毕;
<template>
<h3>事件修饰符</h3>
<a @click.prevent = "clickhandle" href="https://cn.vuejs.org/">vue官网</a>


<!-- 触发子元素的同时也触发了父元素,所以需要阻止冒泡 -->
<div @click="clickdive">

    <p @click.stop="clickp">测试冒泡</p>
</div>
</template>

<script>

export default
{
    data(){
        return{

        }
    },
    methods:{
        clickhandle(e)
        {
            //通过event对象阻止默认事件
           // e.preventDefault();//成功打印文本信息
            
            console.log("点击了");
        },
        clickDiv()
        {
            console.log("div");
        },
        clickp(e)
        {
            //e.stopPropagation();
            
            console.log("p");
        }
    }
}

</script>

7数组变化侦测

1.数组变更方法
Vue 将被侦听的数组的变更方法进行了包裹,所以它们也将会触发视图更新。这些被包裹过的方法包括:
push()
pop()
shift()
unshift()
splice()
sort()
reverse()
2.数组替换方法
不能引起UI界面变化
filter()
concat()
slice()

<template>
<h3>数组变化侦听</h3>


<button @click="addlistHandle">添加数据</button>
<ul>

    <li v-for="(item,index) of names" :key="index">{{ item }}</li>

</ul>

</template>

<script>
export default{
    data()
    {
        return {
            names:["aaa","bbb","ccc"],
        }
    },
    methods: {
        addlistHandle()
        {
            //变更方法
            //引起ui自动更新
            //this.names.push("ddd");
            

            //替换方法
            //不会引起ui自动更新s
            // this.names.concat(["ddd"]);
            // console.log(this.names.concat(["ddd"]));

            //若是想ui依然发生变化那么赋值给原数组
            this.names = this.names.concat(["ddd"]);
        }
    },
}
</script>

8计算属性
计算属性(computed properties)是基于响应式数据的派生值,它们的结果会被缓存,并且只有在相关依赖项发生变化时才会重新计算。计算属性的主要作用是简化模板中的逻辑,将复杂的操作抽离出来,并且提高性能。

计算属性缓存 vs 方法:

虽然计算属性和方法都可以实现同样的功能,但计算属性有缓存机制,而方法每次调用都会重新执行。
计算属性适用于依赖于响应式数据的复杂计算,而方法适用于不需要缓存的逻辑。

<template>
<h3>计算属性</h3>

<!-- 计算一次 -->
<p>{{computeshuxing}}</p>
<p>{{computeshuxing}}</p>

<!-- 计算俩次 -->
<p>{{computedmethod()}}</p>
<p>{{computedmethod()}}</p>


</template>

<script>

export default{
    data()
    {
        return{
            itaaa:{
                name:"sad",
                content:["aaa","vvv","sss"],
            }
        }
    },
    //计算属性
    computed:{
        computeshuxing()
        {
            return this.itaaa.content.length >0 ? 'yes' : 'no';
        }
    },
    methods:{
        computedmethod()
        {
            return this.itaaa.content.length >0 ? 'yes' : 'no';
        }
    }
}

</script>

9class绑定
数据绑定的一个常见需求场景是操纵元素的 CSS class 列表和内联样式。因为 class 和 style 都是 attribute,我们可以和其他 attribute 一样使用 v-bind 将它们和动态的字符串绑定。但是,在处理比较复杂的绑定时,通过拼接生成字符串是麻烦且易出错的。因此,Vue 专门为 class 和 style 的 v-bind 用法提供了特殊的功能增强。除了字符串外,表达式的值也可以是对象或数组。

2024.7.5

<template>
<p :class="{'active' : isActive, 'text-danger' :hasError}">class绑定</p>
<p :class="classObject">class绑定2</p>

<p :class="[arractive,arrhaserror]">class绑定3数组</p>
</template>


<script>
export default{
    data()
    {
        return{
            isActive:false,
            hasError:true,
            //绑定多个属性
            classObject:{
                'active':true,
                'text-danger':true
            },
            arractive:'active',
            arrhaserror:'text-danger'
        }
    }
}

</script>

<style>

.active{
   
    font-size: 30px;
}

.text-danger{
    color: red;
}
</style>

10.style绑定
基本同class绑定

<template>
<h3 :style="{color:activecolor,fontSize:fontSize+'px'}">style绑定</h3>
<h3 :style="styleobejct">style绑定2</h3>
</template>


<script>
export default{
    data()
    {
        return{
            activecolor:"green",
            fontSize:30,
            styleobejct:{
                color:"red",
                fontSize:"30px"
            }
        }
    }
}

</script>

11.watch侦听器

它之所以叫侦听器,是因为它可以侦听一个或多个响应式数据源数据,并再数据源变化时调用所给的回调函数。
就是你传给watch侦听器一个响应式变量,然后当这个变量变化时,自动触发一个你定义的函数,
就像一个人被监控了一样,只要这个人一动,摄像头就会报警

我们可以只用watch选项在每次响应式属性发生变化时触发一个函数
(函数名必须与侦听对象保持一致,如下面中的message)

<template>
<h3>侦听器</h3>

<p>{{ message }}</p>

<button @click="updateHandle">修改数据</button>
</template>


<script>
export default{
    data()
    {
        return{
            message:"hello",
        }
    },
    methods:{
        updateHandle(){
            this.message = "world";
        }
    },
    watch:{
        message(newval,oldvel)
        {
            console.log(newval,oldvel);
        }
    }
}

</script>

**12.v-model 表单输入绑定 **
v-model 可以在组件上使用以实现双向绑定。

双向绑定的核心在于数据流的双向传递。在 Vue.js 中,这种数据流可以分为两个方向:

数据模型到视图(Model to View):当数据模型发生变化时,Vue.js 会自动更新视图。这是通过 Vue 的响应式系统实现的。
视图到数据模型(View to Model):当用户在视图上进行输入时,Vue.js 会自动更新数据模型。这是通过事件监听和数据更新实现的。

v-model修饰符:
.lazy 修饰符:
.lazy 修饰符用于延迟数据更新,只在输入框失去焦点时才将数据同步到模型。这对于减少数据更新频率,以避免频繁的计算和渲染非常有用。
<input v-model.lazy="message">
.number 修饰符:
.number 修饰符用于将用户输入的值转换为数值类型。这对于处理需要数字计算的输入框(如计数器)非常有用。
<input v-model.number="counter">
.trim 修饰符:
.trim 修饰符用于去除用户输入的首尾空格,以保持数据的干净性。这在处理用户输入时非常有用,尤其是文本输入框。
<input v-model.trim="username">

<template>
<h3>表单输入绑定</h3>
<form>

    <input type="text" v-model="message">
    <p>{{ message }}</p>

    <input type="checkbox" id="checkbox" v-model="checked" />
    <label for="checkbox">{{ checked }}</label>
</form>


</template>


<script>
export default{
    data()
    {
        return{
            message:"",
            checked:false,
        }
    }
}

</script>

13模板引用(其实就是获取DOM操作)
虽然 Vue 的声明性渲染模型为你抽象了大部分对 DOM 的直接操作,但在某些情况下,我们仍然需要直接访问底层 DOM 元素。要实现这一点,我们可以使用特殊的 ref attribute:
<input ref="input">

ref 是一个特殊的 attribute,和 v-for 章节中提到的 key 类似。它允许我们在一个特定的 DOM 元素或子组件实例被挂载后,获得对它的直接引用。这可能很有用,比如说在组件挂载时将焦点设置到一个 input 元素上,或在一个元素上初始化一个第三方库。

<template>
<h3>ref模板引用</h3>

    <div ref="container">{{content}}</div>
    <button @click="getelementHandle">获取元素</button>

</template>

<script>

/*
内容改变:{{}}
属性改变:b-bind
事件: v-on:click
*/

export default{
    data()
    {
        return{
            content:"内容"
        }
    },
    methods:{
        getelementHandle()
        {
            console.log(this.$refs.container.innerHTML = "改变后");
        }
    }
}
</script>

14组件组成

创建组件及引用关系

项目中新建pages文件夹,然后添加如下组件
Hearder,Main,Aside
Article,Item

Header.vue

<template>
    <h3>Header</h3>
</template>

<style scoped>
    h3{
        width:100%;
        height: 100px;
        border: 5px solid #999;
        text-align: center;
        line-height: 100px;
        box-sizing: border-box;
    }
</style>

Main.vue

<template>
    <div class="main">
        <h3>Main</h3>
        <Article></Article>
        <Article></Article>
    </div>

</template>

<script>
import Article from './Article.vue';
export default{
    components:{
        Article
    }
}
</script>
<style scoped>
.main{
    float: left;
    width: 70%;

    height: 400px;
    border: 5px solid #999;
    box-sizing: border-box;
}
</style>

Aside.vue

<template>
    <div class="aside">
        <h3>Aside</h3>
        <Item></Item>
        <Item></Item>
        <Item></Item>
    </div>
</template>
<script>
import Item from './Item.vue';

export default{
    components:{
        Item
    }
}
</script>
<style scoped>
.aside{
    float: right;
    width:29%;
    height: 400px;
    border: 5px solid #999;
    box-sizing: border-box;

}
</style>

Article.vue

<template>
    <h3>Article</h3>
</template>
<style scoped>
h3{
    width:80%;
    margin:0 auto;
    text-align: center;
    line-height: 100px;
    box-sizing: border-box;
    margin-top: 50px;
    background: #999;
}
</style>

Item.vue

<template>
    <h3>Item</h3>
</template>
<style scoped>
h3{
    width:80%;
    margin:0 auto;
    text-align: center;
    line-height: 100px;
    box-sizing: border-box;
    margin-top: 10px;
    background: #999;
}
</style>

App.vue

<template>

<!-- 第三步:显示组件 -->
<Header></Header>
<Main></Main>
<Aside></Aside>
</template>

<script>
//第一步:引入组件
import Header from "./pages/Header.vue";
import Main from "./pages/Main.vue";
import Aside from "./pages/Aside.vue";

//第二步:注入组件
export default{
  components:{
    Header,
    Main,
    Aside
  }
}

</script>

15组件传递数据
1.父组件向子组件传递数据,使用props属性;子组件向父组件中传递数据,在子组件中使用$emit派发事件,父组件中使用v-on监听事件;缺点:组件嵌套层次多的话,传递数据比较麻烦。

2.祖先组件通过依赖注入(inject / provide)的方式,向其所有子孙后代传递数据;缺点:无法监听数据修改的来源,不支持响应式。

3.通过属性$root / $parent / $children /ref,访问根组件、父级组件、子组件中的数据;缺点:要求组件之间要有传递性。

4.通过事件总线(eventbus)的方式,可以实现任意两个组件间进行数据传递;缺点:不支持响应式,这个概念是vue1.0版本中的,现在已经废弃。

5.通过 VueJs 的状态管理模式 Vuex,实现多个组件进行数据共享,推荐使用这种方式进行项目中各组件间的数据传递。

2024.7.7

16插槽slots
插槽:简单理解就是组件内部留一个或多个的插槽位置,可供组件传对应的模板代码进去。插槽的出现,让组件变的更加灵活。
父组件

// home.vue

<template>
  <div class="home">
    <footerComponent>
    	<p>我是匿名插槽</p>
    </footerComponent>
  </div>
</template>

<script>
import footerComponent from '@/components/footerComponent.vue'
export default {
  components: {
    footerComponent,
  }
}
</script>

子组件

// footerComponent.vue
<template>
  <div>
  	<h1>子组件</h1>
    <slot></slot>	//  替换为 <p>我是匿名插槽</p>
  </div>
</template>

2024.7.8

17Vue的生命周期
vue生命周期分为四个阶段
第一阶段(创建阶段):beforeCreate,created
第二阶段(挂载阶段):beforeMount(render),mounted
第三阶段(更新阶段):beforeUpdate,updated
第四阶段(销毁阶段):beforeDestroy,destroyed

2024.7.9

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值