vue的双向绑定

147 阅读3分钟

1.什么是mvc

M:model 数据模型层(数据的定义)

v:view 视图 -渲染层

c:controller 控制层 (业务处理层)

只是设计思想和架构模式,并不能帮助我们简化代码,可以让代码有规范和层次结构

2.MVVM原理

M:Moodel 数据模型 v:view 试图渲染层 vm:viewmodel 试图和数据模型的双向绑定

vue当中 修改数据之后 并没有 去调用render 函数 再次渲染,vue 自动帮助我们渲染了,潜在的自动调用的方法:数据一旦发生改变,会自动触发 调用render重新渲染页面。---【双向绑定的核心 部分】

vue2.x Object.defineProperty 【掌握】

vue3.x Object.proxy() 【了解】

3.object.definepropety数据挟持

他的作用将一个对象中的属性或者数组中的元素,进行挟持,

definepropety有两个方法,set(),get()

get()获取数据时自动触发,并返回一个数据出去。

set()是修改数据时自动触发,修改挟持的数据,同时调用render函数

特点:如果一个对象的属性被挟持了,对象的属性直接赋值的方式就失效了。

4.双向绑定

双向绑定是:数据发生改变页面发生改变,页面发生改变数据发生改变。

在vue中通过一个方法definepropety方法对所有的数据进行挟持,挟持的数据一旦发生改变,触发set方法,自动渲染页面。

在vue中对所有的dom进行事件监听,dom如果发生改变会自动触发事件,获取改dom最新数据,通过defineproperty set方法 修改挟持数据。【直接修改挟持的数据造成栈溢出问题:定义一个三方变量set 和get 都操作这个三方变量】。

  • 数据响应式原理 数据驱动原理 响应式原理

数据改 页面怎么自动的渲染

  //Model  数据模型
        const data = {
            name: "张麻子"
        }
        //view 视图层
        function render() {
            let app = document.querySelector('#app');
            app.innerHTML = `
                <p > ${data.name}</p>
                <input type="text" onchange="updateData(this)" value="${data.name}" >
            `
        }
        //初始化渲染
        render()
        //VM ViewModel 
        //双向绑定:数据挟持----在数据挟持的set方法自动调用 render渲染函数
        //定义三方变量接收 最新数据【解决问题:栈溢出】
        let _name = data.name;
        Object.defineProperty(data, 'name', {
            //获取值时自动触发,返回一个新的数据
            get() {
                return _name;
            },
            //修改值时自动触发
            // 获取到最新数据 赋值给 
            // 调用render函数
            set(newVal) {
                _name = newVal
        // data.name = newVal;  // / 获取到最新数据 赋值给  挟持的变量【死循环-栈溢出】 
               render()
           }
       })

    //以前的思路: 监听input的事件 ----获取到input的最新数据--更改data.name ---重新渲染页面
       function updateData(dom) {
           data.name = dom.value;
       // render()  vue中没有修改数据就反复调用render
    }

5.v-model 原理

问:v-model 作用原理?

答:v-model 是vue from表单元素的数据双向绑定指令,其实v-model底层就是一个语法糖@input="xxx=子组件的值" :value="xxx"

语法糖 @input="data=$event.target.value" :value="data"

     <input type="text"   @input="name=$event.target.value" :value="name">
     
       <input type="text"   v-model="name">

6.vuex的状态管理

状态管理: 全局变量的仓库管理,整个项目中所有的组件都可以 数据修改 获取当前仓库最新的数据

五大核心配置

{
    //状态的定义
    state:{
    },
    //定义 修改自己的状态的 方法  
    // 同步修改state 数据的方法    
    mutations:{
        
    },
    //异步修改state数据的方法 ---用户登录接口之后的数据存储
    actions:{
        
    },
    //装饰器 getters
    //state 原本数据 进行一次加工 再返回出去
    getters:{
        
    },
    //模块化
    modules:{
        
    }
}

7.vuex配置

yarn add vuex@3.6.2

在src下面创建一个目录叫 store文件夹 在这个文件夹创建一个index.js

配置文件

import Vue from 'vue';
import Vuex from 'vuex'

//全局注册
Vue.use(Vuex);
//实例化 store 配置
const store = new Vuex.Store({
    //五大核心配置
})
export default store;

在main.js

import store from '@/store/index.js'

new Vue({
  store,  //将store 实例挂载到vue顶级实例对象上
  render: h => h(App)
}).$mount('#app')

8. vuex使用

他们的导入 map 小写首字母五个都是大写

import { mapState,mapMutations } from "vuex";

state是在计算属性中用的 ...mapState(["list"]),

mutations 是在methods里展开

错误的 ...mapMutations(["addtocart"],【"deldtl"】)

注意方法不能连到只能一个一个 正确的...mapMutations(["addtocart"]) ...mapMutations(["deldtl"])

9. state使用

所有存储的数据的变量名及 初始值 的定义

在这个里面定义的值所有页面都可以拿到

定义变量

state{
    属性名:value
}
取值1
this.$store.state.属性名
取值2映射 简写computed+映射mapState+展开运算
注意5大配置的首字母都要大写
computed:{
    keyValue(){
        return this.$store.state.key
    }
}
//使用 this.ketValue
在想用的页面导入
import {mapState} from 'vuex'
computed:{
   ...mapState(['name']) 
    //使用: this.name
}

10.mutations 同步修改数据的方法定义

注意这里有一个大坑

  mutations:{
        //修改属性名的方法
        // state===state对象
        //data===提交时传递过来的数据
        changeName(state,data){
            //修改state.name 
            state.属性名 = data
        }
    },
    //修改数据
    this.$store.commit('changeName',传递新数据)
    简写 methods +映射+展开
    import {mapMutations}  from 'vuex'
methods:{
    ...mapMutations(['changeName']);
    //this.changeName('新数据')   调用修改数据的方法
}