【Vue】2 - 特点、理解、安装、mvvm实现原理


vue - 构建页面的渐进式框架;

1、框架 和 库:

框架: 拥有完整的解决方案。核心是库,框架大一些,我们按别人的规则写好,人家来调用。vue

库:我们调用;jQuery、zepto、animate.css

渐进式框架:通过组合,完成一个完整的框架。就向vue 全家桶:核心是vuejs + vue-router(单页面应用) + vuex(状态管理) + axios(获取数据) ,这一套组合成全家桶;

2、vue特点

  1. 核心只关注视图(view)
  2. 轻量,灵活
  3. 实用移动端项目
  4. 渐进式框架

3、渐进式的理解

  • 声明式渲染(不用关心如何实现)
  • 组件开发
  • 客户端路由(vue-router) -单页面开发
  • 大规模状态管理(vuex) -方便数据管理
  • 构建工具vue-cli

(less/sass/es6 只有chrome支持,要转译成es5/webpack-代码压缩合并)
vue-cli解决了全套方案,包括怎么上线,添加路径前缀,压缩文件,合并文件

4、vue 的两个核心点

  1. 响应式的数据变化-数据驱动
    当数据发生变化 - > 视图自动更新
  2. 组合的视图组件
    ui页面映射为组件树,划分组件可维护、复用、测试

5、MVVM模式

之前是MVC 模式 - 单向
M-model数据、V-view视图 、C-controller 控制器
在这里插入图片描述
上图是一个场景,单项的,用户输入通过控制层取数据库获取数据然后修改视图。不能视图一改就直接修改数据,做不到!

MVVM 模式 - 双向
M-model数据(计划好的数据)、V-view视图(dom) 、VM- viewModel 视图模型
在这里插入图片描述
数据 通过data bindings 直接绑在视图上,视图通过Dom监听实时映射到数据。vue主要做的就是 viewModel

6、安装vue

vue 不支持ie8及以下版本,因为用到了es5的 Object.defineProperty 没有替代方案。

  • cdn方式:引入链接
  • npm 安装:node package manager
  1. 进到目录下,然后初始化 npm init
    初始化,在当前目录下生成一个package.json的文件,这个文件用来描述项目的依赖
    初始化的时候,不能有大写、特殊字符和中文,而且不能和安装的包的名字相同
    npm init -y 按默认初始化,初始化的name是所在文件夹的名字,所以也不能有大写、特殊字符和中文,而且不能和安装的包的名字相同
    license:MIT MIT是开源协议
    vue3安装 参考

  2. 安装vue: npm install vue 默认下载最新版本,安装完后 会在package.json 的 dependencies里记录安装的依赖及版本号。下次没有依赖的话 直接 npm install 就可以了
    安装的文件在node_modules -> src -> dist(目的地) -> vue.js 把源码编译好产生目标文件

  3. 安装axios boostrap等:npm install axios bootstrap
    boostrap 是框架,利用栅格化布局实现响应式,

安装vue-cli

全局生成vue项目的脚手架vue-cli(vue-cli就是一个工具,帮我们生成一个vue项目,就像http-server也是一个工具)

脚手架:保证工作过程顺利进行的工作平台(做事前准备工作)

npm install vue-cli -g
# 全局:只能在命令行用,安装的时候要加 -g  任意一个目录下都可以安装
# mac下:sudo npm install vue-cli -g 

#安装完vue-cli后,命令行上就有一个vue的命令   vue-cli -V查看版本
#安装vue-cli的作用:我们用它来创建一个项目 

vue init webpack  项目名称
#用vue初始化一个带有webpack的项目,项目名是项目名称
#这样生成的项目里面集成了我们需要的文件
npm install   
#安装依赖
npm  run dev

7、vue初始化

引入vue后 会给一个Vue的构造函数,我们new 这个构造函数,new的时候传一个对象,返回的结果是一个vm == viewModel,data中的数据最终会被vm所代理

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <!-- moustache  小胡子语法  表达式:都是取值用的,可以放赋值,取值,三元-->
        {{msg==='hello' ? 1 : 0 }}
    </div>
    <!-- vue 可以像jq一样引入 -->
    <script src="./node_modules/vue/dist/vue.js"></script>
    <script>
        //   引入vue后 会给一个Vue的构造函数,我们new Vue() ,这个构造函数 会返给我们一个结果:viewModel
        let vm = new Vue({   //new的时候传一个对象,返回的结果是一个vm == viewModel
            // 所有挂在vm上的数据都可以实现双向绑定
            el: '#app',  //图中的dom
            //用的querySelector ,当前的vue实例vm 是作用在#app 上的
            //告知vue能管理哪个部分(当前哪个部分的dom 归vue管理),不能挂载html 和body,要挂载普通元素
            data: {    //图中的计划好的数据对象,
                // data中的对象,会被vm所代理,也就是可以通过vm.msg取到对应的内容(取数据 或者 赋值)
                // 用到的核心点:Object.definePrototy  定义属性
                msg: 'hello'

            }
        })
    </script>
</body>
</html>

8、MVVM

  1. {{}} 只能查看数据(数据控制视图),我们需要用到表单元素(input,checkbox,textarea,radio,select )来修改数据,然后结合行间的vue 指令(directive)将数据变化传递vm上
    vue的指令directive 只是dom上的行间属性 ,vue给这类属性赋予了一定的意义,来实现特殊的功能,所有指令都以 v- 开头

{{msg}}{{this.msg}}都是可以的,但是一般不写this ,取值表达式,里面可以写:赋值运算,计算 和 三元表达式。建议里面少写逻辑,有逻辑可以再后面的computed里面写

  1. 在vue中 value 属性默认情况下会被vue忽略掉,selected,checked 都没有意义了
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <div id="app">
        {{msg}}
<!-- 如上的写法只能数据控制视图,没法视图控制数据,要实现视图控制数据,我们需要:表单元素:input,checkbox,textarea,radio,select -->
<!-- 表单元素可以更改数据,然后通过vue 指令directive -->
        
<!-- value 属性默认情况下会被vue忽略掉,selected,checked 都没有意义了 -->
        <input type="text" v-model='msg'> 
        <!-- v-model 会将msg的值赋给输入框,输入框的值改变会影响数据(数据影响视图,视图改变数据) -->
        <!-- vue是声明式的,根本看不到原理: -->
        <!-- Object.defineProperty  ES5的方法 -->

    </div>
    <!-- vue 可以像jq一样引入 -->
    <script src="./node_modules/vue/dist/vue.js"></script>
    <script>
        let vm = new Vue({   //new的时候传一个对象,返回的结果是一个vm == viewModel
            el: '#app',  //图中的dom
            data: {    //图中的计划好的数据对象,
                msg: 'hello'
            }
        })
    </script>
</body>
</html>

9.MVVM 实现核心:Object.defineProperty()

目的: 把一个数据绑到输入框上,当输入框的值改变了,引起数据的变化(视图改变数据),
核心:靠的是Object.defineProperty 里的 get 和 set 方法

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <input type="text" >
    <script src="./node_modules/vue/dist/vue.js"></script>
    <script>
        //目的: 把一个数据绑到输入框上,当输入框的值改变了,引起数据的变化(视图改变数据)
        // 核心靠的是Object.defineProperty 里的get 和 set 方法

        // obj.a = 1;   之前给对象加属性,也可以用Object.defineProperty()来加属性
        // Object.defineProperty(要加属性的对象,属性名,{配置})
        let obj = {};  //一个没有实际意义的对象,我们给它加属性,但内部操作的时候要操作temp,不然操作obj 会一直调用它的相应的方法;
        let temp ={}; //temp 代替obj 取存取
        Object.defineProperty(obj, 'name', {
            // value: '1',  //属性值  ****注意:这里不能写
            // configurable: true, //是否可配置(可删除)  例如 delete obj.name 删除对象中的某属性,可配置就可以删,不可配置就不能删(删不掉)
            // writable: true, //是否可写(可重新赋值) obj.name =1000; 无效,改不了值
            enumerable: false,  //是否可枚举, 不可枚举就无法遍历

            //get()、set()是原生的ES5方法
            get() {   //取值调用:取obj的属性的时候会触发   eg:obj.name
                return temp[name]; //这里return的值就是我们 取到的值
            },

            set(val) {    //赋值调用:给obj的某属性赋值会触发get方法
                //当我们赋值 obj.name='lxz' 的时候,调用set方法,值就是set的参数val
                // val就是我们要赋的值,我们把它赋给obj.name

                // obj.name = val;  //****这里我们得到val,不能这样赋值,不然这样(有一次赋值)会再一次调用set方法,这样会一直循环下去
                // 会报错:Maxumum call  最大调用,死循环了

                // 这里我们可以采用第三方变量temp,我们赋值的时候不去改obj的属性,改temp属性
                temp[name] = val;
                oInput.value =val;  //4.改变数据后,视图里也改变了
            }
        }) 

        var oInput = document.getElementsByTagName('input')[0];
        oInput.value = obj.name;  //1.页面以加载进来,会调用get方法
        oInput.addEventListener('input',function(){  //2.监听input事件
            obj.name = this.value;   //3.给obj.name赋值时,调用set方法
        })
    </script>
</body>

</html>
发布了57 篇原创文章 · 获赞 4 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/Eva3288/article/details/104137837
今日推荐