2

For following code: I want the "test1 span" could be changed with javascript. How can I do it? NOTE: the {{msg}} maybe from ajax output.

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <script src="https://cdn.bootcss.com/vue/2.4.2/vue.min.js"></script>
    </head>
    <body>
        <!-- app -->
        <div id="app">
            <span v-html="test"></span>
            <span v-html="test1"></span>
            {{test3}}
        </div>
        <script>
            var app1 = new Vue({
                el: '#app',
                data: {
                    test: '<p style="color: red">THIS IS HTML</p>',
                    test1: '{{msg}}',
                    test3: 20,
                    msg: 10
                }
            })

            function change() {
                app1.msg = Math.random()
                app1.test3 = Math.random()
            }
            setInterval(change, 2000)
        </script>
    </body>
</html>

Modification:
Maybe I need to make my question clear:
For next modify code, when launch the page, you will see Go to Foo link in the page, then you click the link, you will see hello {{msg}}
NOTE: this comes from the remote server: b.html.
I set a timer there, every 2 seconds, change the value of msg, I wish the {{msg}} in page could change to a random number.

main.html

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.js"></script>
        <script src="https://cdn.bootcss.com/vue/2.4.2/vue.min.js"></script>
        <script src="https://cdn.bootcss.com/vue-router/2.7.0/vue-router.min.js"></script>
    </head>
    <body>
        <div id="app">
            <p>
            <router-link to="/foo">Go to Foo</router-link>
            </p>
            <router-view></router-view>
        </div>

        <script>
            const Foo = {
                template: '<div v-html="template1"></div>',

                data: function () {
                    return {
                        template1: null
                    }
                },
                created: function () {
                    this.fetchData()
                },
                watch: {
                    '$route': 'fetchData'
                },
                methods: {
                    fetchData () {
                        var that = this
                        $.get("http://localhost/try/b.html", function(data, status) {
                            that.template1 = data
                        })
                    }
                }
            }
            const routes = [
            { path: '/foo', component: Foo }
            ]

            const router = new VueRouter({
                routes
            })

            const app = new Vue({
                router
            }).$mount('#app')

            function change() {
                app.msg = Math.random()
            }
            setInterval(change, 2000)
        </script>
    </body>
</html>

b.html

<div>
    hello
    {{msg}}
</div>
1
  • Please take the time to evaluate the answers given. Commented Jan 11, 2018 at 11:14

3 Answers 3

1

Use the tools that Vue.js gives you. Put change() in your VM's methods object, then create a created() hook that sets up the interval.

Please note that v-html expects a String, not a Number, so just add .toString() when generating the random number.

var app1 = new Vue({
  el: '#app',
  data: {
    test: '<p style="color: red">THIS IS HTML</p>',
    test1: null,
    test3: 20,
    msg: 10
  },
  watch: {
    msg: function(newVal, oldVal) {
      this.test1 = newVal
    }
  },
  methods: {
    change() {
      this.msg = Math.random().toString()
      this.test3 = Math.random()
    }
  },
  created() {
    setInterval(this.change, 2000)
  }
})
<script src="https://cdn.bootcss.com/vue/2.4.2/vue.min.js"></script>
<div id="app">
  <span v-html="test"></span>
  <span v-html="test1"></span>
  {{ test3 }}
</div>

Instead of a watcher it is even easier to go for a computed property instead.

var app1 = new Vue({
  el: '#app',
  data: {
    test: '<p style="color: red">THIS IS HTML</p>',
    test3: 20,
    msg: 10
  },
  computed: {
    test1() {
      return this.msg.toString()
    }
  },
  methods: {
    change() {
      this.msg = Math.random()
      this.test3 = Math.random()
    }
  },
  created() {
    setInterval(this.change, 2000)
  }
})
<script src="https://cdn.bootcss.com/vue/2.4.2/vue.min.js"></script>
<div id="app">
  <span v-html="test"></span>
  <span v-html="test1"></span> 
  {{ test3 }}
</div>

Sign up to request clarification or add additional context in comments.

4 Comments

where is {{msg}}, my procedure is as follows, when page load, it will first try to ajax.get a static html page from server, the content of this this static html page is {{msg}}, this is just a template; after the template ready, the page will get data content periodically from the server, and I want vuejs to replace the {{msg}} with new data content. So I should see {{msg}} in the code.
Instead you see {{test1}} in the code which returns msg as soon as msg changes.
I change the question to explain my question better.
As I said, {{test1}} will update the HTML with the new content of msg any time msg changes.
0

Use v-model instead of v-html :-

var app1 = new Vue({
    el: '#app',
    data: {
        test: '<p style="color: red">THIS IS HTML</p>',
        test1: '{{msg}}',
        test3: 20,
        msg: 10
    }
})

function change() {
    app1.msg = Math.random()
    app1.test3 = Math.random()
}
setInterval(change, 2000)
<script src="https://cdn.bootcss.com/vue/2.4.2/vue.min.js"></script>
<div id="app">
            <span v-html="test"></span>
            <span v-model="test1">{{msg}}</span>
            {{test3}}
        </div>

7 Comments

I am not sure, but it not works on myside; I can just see test(with red color) & test3(change with random number) works, but can not see test1 completely.
Strange, when I directly run code snippet in stackoverflow, it seems works, but not works on my local, I will double check.
seems you replace <span v-model="test1">{{msg}}</span> in div, my original purpose is as follows, When the page start, it will use ajax to get a static html page from server, it may get the content: {{msg}}, then it will put this html fragment in html through vuejs binding; after get the {{msg}} from web server, I will load real data from another server, I want vuejs to replace {{msg}} with new data. So the div part can not know {{msg}} at first. See my modified question.
I want first get a html fragment, maybe table from remote, then I get the data, I want vuejs expand the table with my data to serval rows. In fact, if the html fragment is just written in advance in main html, it is ok for vuejs to expand with new data; but here, my html fragment is from remote server, that means when vuejs first render html page, my html fragment is not exist there.
I see a similar usage for "mesos web monitor", but they use angularJS, I want to do same things with VueJS.
|
0

Finally I get the answer from here

Vue.compile( template )

this will make the template from remote server be parsed again by vuejs.

main.html

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.js"></script>
        <script src="https://cdn.bootcss.com/vue/2.4.2/vue.min.js"></script>
        <script src="https://cdn.bootcss.com/vue-router/2.7.0/vue-router.min.js"></script>
    </head>
    <body>
        <div id="app">
            <p>
            <router-link to="/foo">Go to Foo</router-link>
            </p>
            <router-view></router-view>
        </div>

        <script>
            const Foo = {
                data: function () {
                    return {
                        template1: null,
                        msg: null
                    }
                },
                created: function () {
                    this.fetchData()
                    setInterval(this.change, 2000)
                },

                render: function(createElement) {
                    if (this.template1)
                    {
                        return this.template1();
                    }
                },
                methods: {
                    change() {
                        this.msg = Math.random()
                    },

                    fetchData () {
                        var that = this
                        $.get("http://localhost/try/b.html", function(data, status) {
                            that.template1 = Vue.compile(data).render
                        })
                    }
                }
            }
            const routes = [
            { path: '/foo', component: Foo }
            ]

            const router = new VueRouter({
                routes
            })

            const app1 = new Vue({
                router
            }).$mount('#app')
        </script>
    </body>
</html>

b.html

<div>
    hello
    {{msg}}
</div>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.