解决Vue 通过下表修改数组,页面不渲染的问题,vue数组

需要注意的是,Vue之所以能够监听Model状态的变化,是因为JavaScript语言本身提供了Proxy或者Object.observe()机制来监听对象状态的变化。但是,对于数组元素的赋值,却没有办法直接监听,因此,如果我们直接对数组元素赋值:

vm.todos[0] = {
  name: 'New name',
  description: 'New description'
};

会导致Vue无法更新View。

正确的方法是不要对数组元素赋值,而是更新:

vm.todos[0].name = 'New name';
vm.todos[0].description = 'New description';

或者,通过splice()方法,删除某个元素后,再添加一个元素,达到“赋值”的效果:

var index = 0;
var newElement = {...};
vm.todos.splice(index, 1, newElement);

Vue可以监听数组的splice、push、unshift等方法调用,所以,上述代码可以正确更新View。

图片 1

以上这篇解决Vue
通过下表修改数组,页面不渲染的问题就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持帮客之家。

通过下表修改数组,页面不渲染的问题,vue数组
需要注意的是,Vue之所以能够监听Model状态的变化,是因为JavaScript语言本身提供了…

需要注意的是,Vue之所以能够监听Model状态的变化,是因为JavaScript语言本身提供了Proxy或者Object.observe()机制来监听对象状态的变化。但是,对于数组元素的赋值,却没有办法直接监听,因此,如果我们直接对数组元素赋值:

MMVM

MMVM是Model-View-ViewModel的缩写。

对于一个全栈开发工程师来说,懂前端才会开发出更好的后端程序(不懂前端的后端工程师会设计出非常难用的API),懂后端才会开发出更好的前端程序。程序设计的基本思想在前后端都是通用的,两者并无本质的区别。

要编写可维护的前端代码绝非易事。

MVVM最早由微软提出来,它借鉴了桌面应用程序的MVC思想,在前端页面中,把Model用纯JavaScript对象表示,View负责显示,两者做到了最大限度的分离。

把Model和View关联起来的就是ViewModelViewModel负责把Model的数据同步到View显示出来,还负责把View的修改同步回Model

ViewModel如何编写?需要用JavaScript编写一个通用的ViewModel,这样,就可以复用整个MVVM模型了。

之前的jQuery操作DOM需要关注DOM的结构,用更新的数据去修改DOM树的结点内容。

MVVM(仅在前端页面上)的设计思想:仅仅关注Model的变化,让MVVM框架去自动更新DOM的状态,从而把开发者从操作DOM的繁琐步骤中解脱出来!

vm.todos[0] = {
  name: 'New name',
  description: 'New description'
};

流行的MVVM框架

  • Angular:Google出品,名气大,但是很难用
  • Backbone.js:入门非常困难,因为自身API太多
  • Ember:一个大而全的框架,想写个Hello
    world都很困难。
  • Vue.js:入门容易,安装简单,能直接在页面写JavaScript,需要更复杂的功能时又能扩展支持。
    我们选择MVVM的目标应该是入门容易,安装简单,能直接在页面写JavaScript,需要更复杂的功能时又能扩展支持。

会导致Vue无法更新View。

单向绑定

MVVM就是在前端页面上,应用了扩展的MVC模式,我们关心Model的变化,MVVM框架自动把Model的变化映射到DOM结构上,这样,用户看到的页面内容就会随着Model的变化而更新。

图片 2

MVVM模型.png

在项目目录的static目录下新建index.html。在里面使用Vue实现MVVM。

下载vue
2.4.2,注意,vue.js是未压缩的用于开发的版本,它会在浏览器console中输出很多有用的信息,帮助我们调试代码。当开发完毕,需要真正发布到服务器时,应该使用压缩过的vue.min.js,它会移除所有调试信息,并且文件体积更小。

把vue.js重命名为vue-2.4.2.js后拷贝到static/js目录下。在index.html里面引用之。

<script src="/static/js/vue-2.4.2.js"></script>

编写index.html,实例化Vue把V和M关联起来。

<html>
<head>
    <title>Hello Vue</title>
    <script src="/static/js/jquery-2.2.4.js"></script>
    <script src="/static/js/vue-2.4.2.js"></script>
    <script>
        $(function () {
            let vm = new Vue({
                el: '#vm',
                data: {
                    name: 'Tim',
                    age: 22
                }
            });
            window.vm = vm;
        });
    </script>
</head>
<body>
    <div id="vm">
        <p>Hello, {{ name }}</p>
        <p>You are {{ age }} years old!</p>
    </div>
</body>
</html>

要特别注意的是,在<head>内部编写的JavaScript代码,需要用jQuery把MVVM的初始化代码推迟到页面加载完毕后执行,否则,直接在<head>内执行MVVM代码时,DOM节点尚未被浏览器加载,初始化将失败。

上面的代码中,el指定了要把Model绑定到哪个DOM根节点上,语法和jQuery类似。

在该节点以及该节点内部,就是Vue可以操作的View。Vue可以自动把Model的状态映射到View上,但是不能操作View范围之外的其他DOM节点。

浏览器访问http://localhost:8899/static/index.html可以看到结果。

代码把vm绑定到了全局对象window,此时打开控制台,修改window.vm的name或者age属性,可以看到网页内容立即修改了。

这是因为Vue作为MVVM框架会自动监听Model的任何变化,在Model数据变化时,更新View的显示

这种Model到View的绑定我们称为单向绑定

使用css修改后的index.html可以在页面输出JS代码更改Model属性并立即更新网页内容。

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <meta name="description" content="learn javascript by www.liaoxuefeng.com">
    <title>Hello Vue</title>
    <link rel="stylesheet" href="/static/css/bootstrap.css">
    <script src="/static/js/jquery-2.2.4.js"></script>
    <script src="/static/js/vue-2.4.2.js"></script>
    <script>
        $(function () {
            var vm = new Vue({
                el: '#vm',
                data: {
                    name: 'Tim',
                    age: 22
                }
            });
            window.vm = vm;
        });

        function executeJs() {
            try {
                var code = $('#code').val();
                var fn = new Function('var vm = window.vm;\n' + code);
                fn();
            } catch (e) {}
            return false;
        }
    </script>
</head>

<body>
    <header class="navbar navbar-static-top">
        <div class="container">
            <div class="navbar-header">
                <a href="/" class="navbar-brand">Learn JavaScript</a>
            </div>
            <nav class="collapse navbar-collapse" id="bs-navbar">
                <ul class="nav navbar-nav">
                    <li><a target="_blank" href="http://www.liaoxuefeng.com/">Get Courses</a></li>
                    <li><a target="_blank" href="https://github.com/michaelliao/learn-javascript">Source Code</a></li>
                    <li><a target="_blank" href="http://getbootstrap.com/">Resource</a></li>
                </ul>
            </nav>
        </div>
    </header>
    <div id="important" style="color:#cdbfe3; background-color:#6f5499; padding:30px 0; margin:-20px 0 20px 0;">
        <div class="container">
            <h1 style="color:#fff; font-size:60px">Hello Vue!</h1>
            <p style="font-size:24px; line-height:48px">Hello Vue!</p>
        </div>
    </div>

    <div class="container">
        <div class="row">
            <div class="col-md-6">
                <div class="panel panel-default">
                    <div class="panel-heading">
                        <h3 class="panel-title"> MVVM</h3>
                    </div>
                    <div class="panel-body">
                        <div id="vm">
                            <p>Hello, {{ name }}!</p>
                            <p>You are {{ age }} years old!</p>
                        </div>
                        <hr>
                        <h3>Try change the name or age</h3>
                        <form action="#" onsubmit="return executeJs()">
                            <div class="form-group">
                                <textarea id="code" class="form-control" style="font-family: Menlo,Monaco,Consolas,'Courier New',monospace; resize:none;" rows="5">vm.name = 'Jack';</textarea>
                            </div>
                            <button type="submit" class="btn btn-primary">Execute</button>
                        </form>
                    </div>
                </div>
            </div>
            <div class="col-md-6">
                <div class="panel panel-default">
                    <div class="panel-heading">
                        <h3 class="panel-title"> Code</h3>
                    </div>
                    <div class="panel-body">
                        <p>HTML:</p>
                        <pre><div id="vm">
    <p>Hello, {{ name }}!</p>
    <p>You are {{ age }} years old!</p>
</div></pre>
                        <p>JavaScript:</p>
                        <pre>var vm = new Vue({
    el: '#vm',
    data: {
        name: 'Tim',
        age: 22
    }
});</pre>
                    </div>
                </div>
            </div>
        </div>
        <div class="row">
            <div class="col-md-12">
                <h1>Get more courses...</h1>
            </div>
        </div>
        <div class="row">
            <div class="col-md-4">
                <div class="panel panel-default">
                    <div class="panel-heading">
                        <h3 class="panel-title">JavaScript</h3>
                    </div>
                    <div class="panel-body">
                        <p>full-stack JavaScript course</p>
                        <p><a target="_blank" href="http://www.liaoxuefeng.com/wiki/001434446689867b27157e896e74d51a89c25cc8b43bdb3000">Read more</a></p>
                    </div>
                </div>
            </div>
            <div class="col-md-4">
                <div class="panel panel-default">
                    <div class="panel-heading">
                        <h3 class="panel-title">Python</h3>
                    </div>
                    <div class="panel-body">
                        <p>the latest Python course</p>
                        <p><a target="_blank" href="http://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000">Read more</a></p>
                    </div>
                </div>
            </div>
            <div class="col-md-4">
                <div class="panel panel-default">
                    <div class="panel-heading">
                        <h3 class="panel-title">git</h3>
                    </div>
                    <div class="panel-body">
                        <p>A course about git version control</p>
                        <p><a target="_blank" href="http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000">Read more</a></p>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <footer style="background-color:#ddd; padding: 20px 0;">
        <div class="container">
            <p>
                <a target="_blank" href="http://www.liaoxuefeng.com">Website</a> -
                <a target="_blank" href="https://github.com/michaelliao/learn-javascript">GitHub</a> -
                <a target="_blank" href="http://weibo.com/liaoxuefeng">Weibo</a>
            </p>
            <p>This JavaScript course is created by <a target="_blank" href="http://weibo.com/liaoxuefeng">@廖雪峰</a>.</p>
            <p>Code licensed <a target="_blank" href="https://github.com/michaelliao/learn-javascript/blob/master/LICENSE">Apache</a>.</p>
        </div>
    </footer>
</body>

</html>

在Vue中,可以直接写{{ name }}绑定某个属性。如果属性关联的是对象,可以使用.来访问属性,例如{{ address.zipcode }}

另一种单向绑定的方法是使用Vue的指令v-text,写法如下:

<p>Hello, </p>

这种写法是把指令写在HTML节点的属性上,它会被Vue解析,该节点的文本内容会被绑定为Model的指定属性,注意不能再写双花括号{{
}}。

正确的方法是不要对数组元素赋值,而是更新:

双向绑定

单向绑定就是把Model绑定到View,当更新Model时,View就会自动更新。如果更新了View,Model也自动被更新,这种情况就是双向绑定

什么情况下用户可以更新View呢?填写表单就是一个最直接的例子。当用户填写表单时,View的状态就被更新了,如果此时MVVM框架可以自动更新Model的状态,那就相当于我们把Model和View做了双向绑定:

图片 3

双向绑定.png

v-model指令把某个元素如form表单里面的input控件和Model的某个属性作双向绑定。

<html>
<head>
    <title>Hello Vue</title>
    <script src="/static/js/jquery-2.2.4.js"></script>
    <script src="/static/js/vue-2.4.2.js"></script>
    <script>
        $(function () {
            let vm = new Vue({
                el: '#vm',
                data: {
                    email: '',
                    name: ''
                }
            });
            window.vm = vm;
        });
    </script>
</head>
<body>
    <form id="vm" action="#">
        <p><input v-model="email"></p>
        <p><input v-model="name"></p>
    </form>
</body>
</html>

同样地,在控制台使用window.vm.$data查看Model的内容。查看或者设置window.vm.name和window.vm.email的值。可以发现是双向绑定的,也是立即更新的。

除了<input type="text">可以和字符串类型的属性绑定外,其他类型的<input>也可以和相应数据类型绑定:

  • 多个radio可以与字符串绑定。对应的Model是字符串,值是勾选上的radio的value值。

<html>
<head>
    <title>Hello Vue</title>
    <script src="/static/js/jquery-2.2.4.js"></script>
    <script src="/static/js/vue-2.4.2.js"></script>
    <script>
        $(function () {
            let vm = new Vue({
                el: '#vm',
                data: {
                    gender: 's'
                }
            });
            window.vm = vm;
        });
    </script>
</head>
<body>
    <form id="vm" action="#">
        <label><input type="radio" v-model="gender" value="m">Male</label>
        <label><input type="radio" v-model="gender" value="f">Female</label>
        <label><input type="radio" v-model="gender" value="s">Secret</label>
    </form>
</body>
</html>
  • 多个checkbox可以和数组绑定。对应的Model是数组,数组里面的元素是所有勾选上的checkbox的value值。

<html>
<head>
    <title>Hello Vue</title>
    <script src="/static/js/jquery-2.2.4.js"></script>
    <script src="/static/js/vue-2.4.2.js"></script>
    <script>
        $(function () {
            let vm = new Vue({
                el: '#vm',
                data: {
                    language: []
                }
            });
            window.vm = vm;
        });
    </script>
</head>
<body>
    <form id="vm" action="#">
        <label><input type="checkbox" v-model="language" value="zh">Chinese</label>
        <label><input type="checkbox" v-model="language" value="en">English</label>
        <label><input type="checkbox" v-model="language" value="fr">French</label>
    </form>
</body>
</html>
  • 单个checkbox可以和boolean类型变量绑定。对应的Model是布尔值,值是这个check是否勾选上。

<html>
<head>
    <title>Hello Vue</title>
    <script src="/static/js/jquery-2.2.4.js"></script>
    <script src="/static/js/vue-2.4.2.js"></script>
    <script>
        $(function () {
            let vm = new Vue({
                el: '#vm',
                data: {
                    subscribe: false
                }
            });
            window.vm = vm;
        });
    </script>
</head>
<body>
    <form id="vm" action="#">
        <label><input type="checkbox" v-model="subscribe">Hello</label>
    </form>
</body>
</html>
  • 下拉框<select>绑定的是字符串。对应的Model是字符串,值是选择的那个菜单(<option>)的value值。

<html>
<head>
    <title>Hello Vue</title>
    <script src="/static/js/jquery-2.2.4.js"></script>
    <script src="/static/js/vue-2.4.2.js"></script>
    <script>
        $(function () {
            let vm = new Vue({
                el: '#vm',
                data: {
                    city: ''
                }
            });
            window.vm = vm;
        });
    </script>
</head>
<body>
    <form id="vm" action="#">
        <select v-model="city">
            <option value="">未选择</option>
            <option value="bj">Beijing</option>
            <option value="sh">Shanghai</option>
            <option value="gz">Guangzhou</option>
        </select>
    </form>
</body>
</html>

双向绑定最大的好处是我们不再需要用jQuery去查询表单的状态,而是直接获得了用JavaScript对象表示的Model。

Author

发表评论

电子邮件地址不会被公开。 必填项已用*标注