PJCHENder
6/21/2017 - 1:46 PM

Vue Reactivity Demo

Vue Reactivity Demo

#posts(v-cloak)   
    .vm-posts(v-if="false")
        .ui.segment.green
            p Post Id: {{ post.id }}
        .ui.form                
                .field
                    label(for="userid") User Id
                    input(type="text" id="userid" v-model="post.userId")
                .field
                    label(for="post-title") Title
                    textarea(rows="2" v-model="post.title")
                .field
                    label(for="post-body") Content
                    textarea(v-model="post.body")
                button.ui.primary.button(@click="saveForm($event)") Save
        .ui.section.divider
        table.ui.striped.table.selectable
            thead
                tr
                    th Index
                    th Id
                    th User Id
                    th Title
                    th Body
            tbody
                tr(v-for="(post, index) in posts" @click="refreshForm(index)")
                    td {{ index }}
                    td {{ post.id }}
                    td {{ post.userId }}
                    td {{ post.title }}
                    td {{ post.body }}
                
const request = window.superagent;
const root = "https://jsonplaceholder.typicode.com";

const postsVm = new Vue({
    el: "#posts",
    data: {
        currentIndex: "",
        posts: [],
        post: {
            userId: "",
            id: "",
            title: "",
            body: ""
        }
    },
    methods: {
        refreshForm(index) {
            this.currentIndex = index; // 暫存用變數
            this.post.userId = this.posts[index].userId;
            this.post.id = this.posts[index].id;
            this.post.title = this.posts[index].title;
            this.post.body = this.posts[index].body;
        },
        saveForm(event) {
            console.log("saveForm");
            console.log("this.currentIndex", this.currentIndex);
            /**
             * 問題一:
             * 使用 index 的方式修改陣列中的內容會壞掉
             * - 資料更新但畫面不更新
             **/
            // this.posts[this.currentIndex] = this.post

            /**
             * 解決方法一:使用 Vue 可觀察到的陣列方法
             * push()、pop()、shift()、unshift()、splice()、sort()、reverse()
             * arr.splice(startIndex, delteCount, addItem)
             **/
            // this.posts.splice(this.currentIndex, 1, this.post)

            /**
             * 解決方法二: 使用 vm.$set
             * vm.$set(array, index, value)
             **/
            // this.$set(this.posts, this.currentIndex, this.post)

            /**
             * 問題二:陣列中的物件內容變成響應式的,by reference
             **/
            // this.$set(this.posts, this.currentIndex, Object.assign({}, this.post))
            this.posts.splice(
                this.currentIndex,
                1,
                Object.assign({}, this.post)
            );

            /**
             * By reference 參考 Code
             **/
//             let obj = {
//                 firstName: "Aaron",
//                 lastName: "Chen"
//             };

//             let obj2 = obj;
//             console.log(obj);
//             console.log(obj2);
//             obj2.firstName = "Kan";
//             console.log(obj);
//             console.log(obj2);
        }
    },
    computed: {
        // postsLength () {
        //     // 提醒:如果畫面中沒有使用到 postsLength ,則不會自動促發 computed
        //     let newPostId = this.posts.length + 1
        //     this.post.id = newPostId
        //     return newPostId
        // }
    },
    created() {
        let vm = this;
        // AJAX request
        //  https://jsonplaceholder.typicode.com/posts/
        request.get(root + "/posts").end((err, res) => {
            vm.posts = res.body;
        });
    }
});
#post(v-cloak)
    .vm-post(v-if="true")
        .ui.form
            .three.fields
                .field
                    label(for="userid") User Id
                    input(type="text" id="userid" v-model="post.userId")
                .field
                    label(for="postid") Post Id
                    input(type="text" id="postid" v-model="post.id")
                .field
                    label(for="post-author") Author
                    input(type="text" id="post-author" v-model="post.author")
            .field
                label(for="post-title") Title
                textarea(rows="2" v-model="post.title")
            .field
                label(for="post-body") Content
                textarea(v-model="post.body")
        .ui.section.divider
        .ui.segments
            .ui.segment
                p Title: {{post.title}}
            .ui.horizontal.segments
                .ui.segment
                    p User Id: {{post.userId}}
                .ui.segment
                    p Post Id: {{post.id}}
                .ui.segment
                    p Author: {{post.author}}
            .ui.segment
                p Body: {{post.body}}
const request = window.superagent;
const root = "https://jsonplaceholder.typicode.com";

const postVm = new Vue({
    el: "#post",
    data: {
        post: {
            userId: "",
            id: "",
            title: ""
        }
    },
    created() {
        let vm = this;
        //  https://jsonplaceholder.typicode.com/posts/1
        request.get(root + "/posts/3").end((err, res) => {
            let response = res.body;
            /**
             * 問題狀況
             * 1. vm.post.body 一開始忘記設定進去
             * 2. vm.post.author 後來新增的欄位
             * 資料已經設定進去,但是畫面沒有更新,可以開 Vue Dev Tool 搭配 $forceUpdate() 
            **/
            vm.post.userId = response.userId;
            vm.post.id = response.id;
            vm.post.title = response.title;
            // vm.post.body = response.body;// 用 vm.$set 要把這行註解掉

            /**
             * 解決辦法 1: 一開始在 data 的地方就補齊
             **/

            /**
             * 解決辦法 2: 使用 Vue.set(object, key, value)
             **/
            // vm.$set(vm.post, "body", response.body)     // 要記得把上面的 vm.post.body 註解掉(因為已經壞掉)
            // vm.$set(vm.post, 'author', '')

            /**
             * 解決辦法 3: 使用 Object.assign 建立新的物件
             **/
            // vm.post = response       // 不建議
            // vm.post = Object.assign({}, response, {author: ''})
        });
    }
});