随笔 - 65  文章 - 0 评论 - 0 阅读 - 28638
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

一 vm对象的生命周期

每个vm对象在创建时都要经过一系列的初始化过程。在这个过程中Vue.js会自动运行一些叫做生命周期的的钩子函数,我们可以使用这些函数,在对象创建的不同时间阶段加上我们需要的自动执行代码,就实现特定的功能。

代码示例

复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://unpkg.com/vue@next"></script>

</head>
<body>
    <div id="app">
        <p ref="p1">{{message}}</p>
        <input type="text" v-model="message">
    </div>
    <script>
        var vm = Vue.createApp({
          data(){
            return {
                message: "hello",
            }
          },
          beforeCreate(){
            // 当前函数执行时,vm还没有初始化完成。
            console.log("beforeCreate>>>", this.$data);
            console.log("beforeCreate>>>", this.$el);
            console.log("beforeCreate>>>", this.$refs);
          },
          created(){
            // 当前函数执行时,vm对象已经初始化完成
            console.log("created>>> $data=", this.$data);  // 此时data选项中的数据已经被注入到vm对象中
            console.log("created>>> $el=", this.$el);
            console.log("created>>> $refs=", this.$refs);
            // 在开发中,我们可以在这个函数中进行初始化数据相关的操作,例如:使用ajax从服务器中读取数据,并赋值给data
          },
          beforeMount(){
            // 已经把对应的vue语法的变量替换成了html内容了,但是并没有挂载到el标签的内容中
            console.log("beforeMount>>> $el=", this.$el);
            console.log("beforeMount>>> template=", this.$options.template);
            console.log("beforeMount>>> $refs=", this.$refs);
          },
          mounted(){
            // vue生成的HTML内容已经挂载到了$el属性中
            console.log("mounted>>>", this.$el);
            console.log("mounted>>>", this.$refs);
          },
          beforeUpdate(){
            // 变量更新前,data选项中的数据发生了改变,但是没有重新生成虚拟DOM,所以HTML中的变量值没有被同步
            console.log("beforeUpdate>>>", this.$data);
            console.log("beforeUpdate>>>", this.$el.parentElement.innerHTML);
            // 修改数据前,判断本次修改是否合法?发送ajax,
          },
          updated(){
            // 变量更新后,html内容已经与data选项中的数据同步了,因为重新生成了虚拟DOM
            console.log("updated>>>", this.$el.parentElement.innerHTML);
            // 修改数据后,发送ajax,同步数据库
          }
        }).mount("#app")
    </script>
</body>
</html>
vm对象生命周期的钩子函数
复制代码

说明

1
2
3
在vue使用的过程中,如果要初始化操作,把初始化操作的代码放在 mounted 中执行。
mounted阶段就是在vm对象已经把data数据实现到页面以后。一般页面初始化使用。例如,用户访问页面加载成功以后,就要执行的ajax请求。
另一个就是<strong>created</strong>,这个阶段就是在vue对象创建以后,mounted之前。把ajax请求后端数据的代码放进 created 

二 选项API

1 过滤器【Vue3.0已淘汰过滤器选项】

Vue3.0已经被淘汰了过滤器这个选项,所以以下使用2.6.11版本来完成代码的编写。

过滤器,是vue允许开发者自定义的文本格式化函数,可以使用在两个地方:输出内容和操作数据中。定义过滤器的方式有两种:全局过滤器和局部过滤器。

1.1 使用Vue.filter进行全局定义

./assets/filter.js

1
2
3
4
5
// 定义一个全局过滤器,定义在vm对象的外部,提供给整个项目都可以调用。
// Vue.filter("过滤器函数名", 匿名函数);
Vue.filter("money", (data)=>{
    return `${data.toFixed(2)}元`
})

1.2 在vm对象中通过filters选项api来局部定义

代码:

复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./assets/vue@2.7.8.js"></script>
    <script src="./assets/filter.js"></script>
</head>
<body>
    <div id="app">
        <p>{{price|money}}</p>
        <p>{{price|mon}}</p>
        <p>{{money_format(price)}}</p>
    </div>
    <script>
        var vm = new Vue({  // 相当于vue3.x的 Vue.createApp()
          el: "#app",  // 相当于vue3.x的mount绑定视图方法
          data(){
            return {
                // message: "hello, vue2.x",
                price: 3.55555
            }
          },
          methods: {
            money_format(data){ // 过滤器完全可以被methods选项中定义的函数所代替,所以在vue3.x以后成为了废弃特性
                return `¥${data.toFixed(2)}`
            }
          },
          filters: { // 局部过滤器,是当前vm对象的属性方法存在,所以无法被外界使用
            mon(data){
                return `¥${data.toFixed(2)}`
            }
          }
        })
    </script>
</body>
</html>
filter选项api定义
复制代码

2 计算属性

计算属性,是vue提供给我们开发者用于编写代码时保存计算出新的数据结果的变量。主要通过computed选项进行声明的。

复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://unpkg.com/vue@next"></script>
</head>
<body>
    <div id="app">
        <input type="text" v-model.number="num1">+
        <input type="text" v-model.number="num2">={{result}}
    </div>
    <script>
        var vm = Vue.createApp({
            data(){
                return{
                    num1:10,
                    num2:20,
                }
            },
            computed: {
                result(){
                    return this.num1 + this.num2
                }
            }
        }).mount("#app")
    </script>
</body>
</html>
计算属性computed
复制代码

 

3 侦听属性 

侦听属性,可以帮助我们侦听data某个数据的变化,从而做相应的自定义操作

侦听属性是一个对象,它的键是要监听的对象或者变量,值一般是函数,当侦听的data数据发生变化时,会自定执行的对应函数,这个函数在被调用时,vue会传入两个形参,第一个是变化前的数据值,第二个是变化后的数据值。

代码:

复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://unpkg.com/vue@next"></script>
    <style>
        input{
            outline: none;
            border: 1px solid #333;
        }
    </style>
</head>
<body>
    <div id="app">
        账号:<input ref="username" type="text" v-model="username" @blur="check_username"><br>
        密码:<input ref="password" type="text" v-model="password"><br>
    </div>
    <script>
        var vm = Vue.createApp({
            data(){
                return{
                    username:"",
                    password:"",
                }
            },
            methods: {
                    check_username(){
                        console.log("check_username执行了。")
                }
            },
            watch: {
                username(new_data, old_data) {
                    console.log(`old_data>>${old_data},new_data>>${new_data}`)
                    let length = this.username.length;
                    if (length > 6 && length < 16) {
                        this.$refs.username.style.border = "1px solid blue";
                    } else {
                        this.$refs.username.style.border = "1px solid red";
                    }
                },
                password(new_vuale, old_value) {
                    if (/^\d+$/.test(this.password)) {
                        this.$refs.password.style.block = "1px solid red";
                    } else {
                        this.$refs.password.style.block = "1px solid blue";
                    }
                }
            },

        }).mount("#app")
    </script>
</body>
</html>
侦听属性watch
复制代码

 

三 组合API

Vue3.0在原来2.0版本基础上进行升级的时候,进行语法上的扩展与兼容。

选项API的特点:
数据与操作数据的方法是分开在不同的选项中存放的。当一个页面组件中数据多了,方法多了,维护成本会增加
组合API的特点: 提供了一个setup的初始方法和两个声明数据方法ref和derective,可以让我们把数据的声明以及操作数据的方法写到一块的新方法。

1 基本语法声明

响应式变量:

ref函数的作用是用于声明vue的基本数据类型[Number,String,Boolean/undefined/Array等]的响应式变量,可以进行双向数据绑定

reactive 函数的作用是用于声明vue的复杂数据类型[Object]的响应式变量,可以进行双向数据绑定。

代码:

复制代码
<template>
  <h2>变量声明</h2>
  <p>num1={{num1}}</p>
  <input type="text" v-model="num1">
  <hr>
  <p>num2={{num2}}</p>
  <input type="text" v-model="num2">
  <ul>
    <li v-for="item in data">{{item}}</li>
  </ul>
  {{student_info}}<br>
  {{student_info.name}}<br>
  <hr>
  <h2>修改变量</h2>
  <button @click="change_data1">修改ref数据</button>
  <button @click="change_data2">修改reactive数据</button>

  <hr>
  <h2>计算属性</h2>
  <input type="text" size="1" v-model.number="data1"> + <input type="text" v-model.number="data2"> = {{result}}

</template>

<script setup>
import {ref, reactive, watch, onMounted, computed} from "vue";
/**
 * 声明只读变量
 */
let num1 = 10;  // 声明一个只读变量,无法在template中进行双向数据绑定

/**
 * 声明响应式变量
 * ref函数的作用就是用于声明vue的基本数据类型[Number,String,Boolean/undefined/Array等]的响应式变量,可以进行双向数据绑定
 * reactive 函数的作用就是用于声明vue的复杂数据类型[Object]的响应式变量,可以进行双向数据绑定
 */
let num2 = ref(100);
let data = ref([
  {"id":1, "name": "小明", "age": 11},
  {"id":2, "name": "小白", "age": 18},
  {"id":3, "name": "小华", "age": 17},
  {"id":4, "name": "小绿", "age": 18},
]);

let student_info = reactive({
  "id": 1,
  "name": "小白",
  "age": 16
})

/**
 * 修改变量的操作
 */
const change_data1 = ()=>{
  // 修改ref响应式变量的值,需要通过value来改动
  num2.value = 30000;
  console.log(num2);
}
const change_data2 = ()=>{
  // 修改reactive响应式变量的值,不能修改变量本身,可以修改变量内部的属性,直接赋值即可。
  student_info.age = 20;
}

// 监听属性写法
watch(
    num2,  // 监听ref响应式变量,参数1是一个函数,返回值是被监听的ref变量的value属性
    ()=>{
      // 值发生改变时自动调用的代码
      console.log("num2改变了", num2);
    }
)

watch(
    student_info,  // 监听reactive响应式变量,参数1就是被监听的reactive变量
    ()=>{
      console.log("student_info改变了", student_info)
    }
)
/**
 * 钩子方法
 */
// created 钩子,vue初始化完成时自动自动的。但是在组合API中时没有created钩子的
// 原因开发者在 <script setup>标签中缩写的所有所有代码,默认都是在created钩子中执行的。
console.log("created执行了,此时vue刚完成初始化,还是渲染template")

// mounted钩子方法,在组合API中叫onMounted
onMounted(()=>{
  // 视图被渲染以后,执行代码。
  console.log("Mounted执行了,此时vue已经渲染了html内容");
})

/**
 * computed 计算属性
 */
let data1 = ref(10);
let data2 = ref(20);

let result = computed(()=>{
  return data1.value+data2.value;
});

</script>

<style scoped>

</style>
GroupApi.vue
复制代码
复制代码
<script setup>
import GroupApi from "./views/GroupApi.vue"
</script>

<template>
<GroupApi></GroupApi>
</template>

<style scoped>

</style>
App.vue
复制代码

2 参数传递

传递方向 描述 代码
父传子

在父组件中,传递数据需要通过组件标签名的属性进行传递,

而子组件中,通过defineProps接受父组件传递过来的数据。

复制代码
<template>
  <hi>User父组件</hi>
  <title>User</title>
  <input type="text" v-model="str_data">
  <input type="text" v-model.number="num_data">
  <!--    传递值-->
  <Info :str_message="str_data"
  :num_message="num_data"
  :obj_data="obj_data"
  @num_change="get_num"
  ></Info>
</template>

<script setup>
import {reactive,ref} from "vue";
// 引入
import Info from "./Info.vue";
let str_data=ref("hello world");
let num_data=ref(10);
let obj_data=reactive({
  id:1,
  name:"小明",
  age:16,
})

const get_num = (data)=>{
  console.log("父组件中接收数据data=", data.value);
}
</script>

<style scoped>

</style>
父组件User.vue
复制代码

 

复制代码
<template>
  <p>Info子组件</p>
  <p>子组件中接收来自父组件的数据</p>
  <p>{{props.str_message}}</p>
  <p>{{props.num_message}}</p>
  <p>{{props.obj_data}}</p>
  num=<input type="text" v-model="num">
</template>

<script setup>
import {defineProps,ref,watch} from "vue"
// 使用defineProps来接收父组件的数据
const props = defineProps({
  str_message:{
    type:String,
    default:"没有数据"
  },
  num_message:{
    type:Number,
    default:0,
  },
  obj_data:Object
})

// 注册事件源
const emits = defineEmits(['num_change'])
let num = ref(10);

watch(
    num,
    ()=>{
      console.log(num.value);
      emits("num_change", num)
    }
)
</script>

<style scoped>

</style>
子组件Info.vue
复制代码
子传父

在子组件中通过defineEmits先声明要注册的事件源,然后通过defineEmits的返回值emits进行调用事件源进行参数传递,

在父组件中,直接声明方法绑定到子组件标签名中即可。

 

四 指令和事件修饰符

4.1 常用指令

指令 描述
v-model.trim 用于去除字符串两边的空白字符,常用于密码
v-model.lazy 用于减少触发watch侦听选项的频率,从原来的input输入事件的侦听切换成了change值改变事件的监听
v-model.number 表示把变量作为数值来进行转换提取,能转的都会转换

代码示例

复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://unpkg.com/vue@next"></script>
</head>
<body>
    <div id="app">
        <input type="password" v-model.trim="password"><br>
        <input type="text" v-model.lazy="mobile"><br>
        <input type="text" v-model.number="num">+500=<span>{{ num+500 }}</span>
    </div>
    <script>
        const vm=Vue.createApp({
            data(){
                return{
                    passsword: " ",
                    mobile:"",
                    num:0,
                }
        } ,
            watch:{
                passsword(){
                    console.log(this.passsword);
                },
                mobile(){
                    console.log("发送http请求验证手机号是否在服务端注册了");
                    console.log(this.mobile)
                }
            }
        }).mount("#app");
    </script>
</body>
</html>
v-model示例
复制代码

4.2 事件修饰符

子元素的同类事件触发以后,会自动触发父类元素的同类事件,这就是事件冒泡。

事件修饰符 描述
@事件名.stop 用于阻止事件冒泡
@事件名.prevent 用于阻止标签本身拥有的页面跳转功能,例如:a标签被点击,form标签提交表单

 

代码示例

复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://unpkg.com/vue@next"></script>
</head>
<body>
    <div id="app">
        <div @click="show('div')">
            <button @click.stop="show('button')">点击</button>
            <a  @click="show('a')" href="http://www.baidu.com">点击</a>
        </div>
    </div>
    <script>
        var vm=Vue.createApp({
            data(){
                return{
                }
            },
            methods: {
                show(msg){
                    console.log(`${msg}被点击了`)
                }
            }
        }).mount("#app")
    </script>
</body>
</html>
事件修饰符.stop和.prevent
复制代码

 

五 webStorage本地存储

webStorage是HTML5提供的用于在本地实现离线存储的一种技术方案。HTML5中提供了2个全局对象用于保存数据到本地浏览器或者移动端的webapp中,分别是:localStorage和sessionStorage。这2个对象,使用方式一致,区别仅仅是存储数据的有效期不同。这个对象保存数据时,都是域名进行区分保存的,不同的域名保存在本地存储的相互之间是互不干扰,互不影响的。

webStorage本地存储 描述 用法
localStorage 永久存储,不主动删除,会一直保存在本地。
1
2
3
4
5
6
7
8
9
10
11
12
13
// 保存一个数据
localStorage.setItem("变量名", "变量值");
// localStorage.变量名="变量值"
 
// 获取一个数据
localStorage.getItem("变量名");     // 返回值:变量值
// 变量值 = localStorage.变量名
 
// 删除一个数据
localStorage.removeItem("变量名");
 
// 清空当前域名下所有的数据
localStorage.clear();
sessionStorage 会话存储,当浏览器重启以后,数据则会丢失。
1
2
3
4
5
6
7
8
9
10
11
12
13
// 保存一个数据
sessionStorage.setItem("变量名", "变量值");
// sessionStorage.变量名="变量值"
 
// 获取一个数据
sessionStorage.getItem("变量名");     // 返回值:变量值
// 变量值 = sessionStorage.变量名
 
// 删除一个数据
sessionStorage.removeItem("变量名");
 
// 清空当前域名下所有的数据
sessionStorage.clear();

 

实例代码:

复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>todolist</title>
    <style>
        .list_con{
            width:600px;
            margin:50px auto 0;
        }
        .inputtxt{
            width:550px;
            height:30px;
            border:1px solid #ccc;
            padding:0px;
            text-indent:10px;
        }
        .inputbtn{
            width:40px;
            height:32px;
            padding:0px;
            border:1px solid #ccc;
        }
        .list{
            margin:0;
            padding:0;
            list-style:none;
            margin-top:20px;
        }
        .list li{
            height:40px;
            line-height:40px;
            border-bottom:1px solid #ccc;
        }

        .list li span{
            float:left;
        }

        .list li a{
            float:right;
            text-decoration:none;
            margin:0 10px;
        }
    </style>
    <script src="assets/vue.global.3.2.20.js"></script>
</head>
<body>
    <div class="list_con" id="todolist">
        <h2>To do list</h2>
        <input type="text" v-model="text" id="txt1" class="inputtxt">
        <input type="button" value="增加" id="btn1" class="inputbtn" @click="add_item">
        <ul id="list" class="list">
            <!-- javascript:; # 阻止a标签跳转 -->
            <li v-for="(item,key) in item_list">
                <span>{{item}}</span>
                <a href="" class="up"  @click.stop.prevent="up_item(key)"></a>
                <a href="javascript:;" @click.stop.prevent="down_item(key)"class="down"></a>
                <a href="" class="del" @click.stop.prevent="remove_item(key)">删除</a>
            </li>
        </ul>
    </div>
    <script>
  var vm = Vue.createApp({
    data(){
      return {
        text: "",
        item_list: [
            "学习html",
            "学习css",
            "学习javascript",
        ]
      }
    },
    methods: {
      add_item(){
        // 添加计划
          this.load_data();
        this.item_list.splice(0,0,this.text);
        this.text = "";
      },
      remove_item(key){
        // 删除计划
        this.item_list.splice(key,1);
      },
      up_item(key){
        // 计划向上移动
        if( key === 0) return; // 如果当前计划已经在最上方,则不能继续向上移动
        let del_list = this.item_list.splice(key,1);
        this.item_list.splice(key-1, 0, del_list[0]);
      },
      down_item(key){
        // 计划向下移动
        let del_list = this.item_list.splice(key,1);
        this.item_list.splice(key+1, 0, del_list[0])
      },
            save_data(){
                let content = JSON.stringify(this.item_list)  //保存为字符串
                localStorage.setItem("todolist", content);

      },
            load_data(){
          if  ( localStorage.getItem("todolist")!== true){
              localStorage.setItem("todolist",JSON.stringify(this.item_list));
          }
          let content = localStorage.getItem("todolist")
                try {
                        this.item_list = JSON.parse(content);  //JSON数据->JS对象
                }catch (e) {
                        console.log("转换json数据出错!")
                }
            }
    },
        created(){
            this.load_data();
        },
        updated(){
        this.save_data();
        }
  }).mount("#todolist")
    </script>
</body>
</html>
基于本地存储实现前端页面的离线数据保存
复制代码

  

posted on   大明花花  阅读(733)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示