vuex data is changed, and the page in the component is not rendered
I believe that many newbies in vuex will encounter such problems:
After vuex data is updated, the places where data is used in the plugin are not updated.
Such code
data() { return { tableData: this.$ }; }
Then use tableData in template
<el-table :data="tableData" class="tablePst"> <el-table-column label="Login name" prop="loginname"></el-table-column> <el-table-column label="Real Name" prop="realname"></el-table-column> </el-table>
In this way, the problem of data changes and not rendering will occur.
question
To solve the problem, you have to understand the vue life cycle. Before the page is loaded, tableData gets the value in the store and assigns it to yourself. In this way, tableData only has an initial value. The state in the subsequent vuex will change and will not be assigned to tableData again. Unless the page is refreshed and reloaded and the component life cycle starts again, the latest value can be obtained.
solve
1. Remove the status of tableData in the component and use $ directly in the template so that you can get the latest status value at any time.
<el-table :data="$" class="tablePst"> <el-table-column label="Login name" prop="loginname"></el-table-column> <el-table-column label="Real Name" prop="realname"></el-table-column> </el-table>
2. Use mapState to expose the status in vuex to the component, and then use it. See the documentation for details.vuex mapState official documentation.
Supplementary knowledge:Solve the problem of vue modifying data pages without re-rendering (the view does not refresh after arrays and objects are changed in Vue)
Vue rendering mechanism and various methods to solve the problem of not refreshing data pages
This article does not talk about principles, but only talks about easy-to-understand and easy-to-learn things (I feel that I can learn knowledge, please give me a thumbs up!)
First of all, the bottom layer of vue is to convert data objects into getters and setters, so vue does not support IE8.
1. Let me give you a brief introduction,
(obj, prop, descriptor)
//parameter
obj
The object on which the attributes are to be defined.
prop
The name of the attribute to define or modify.
descriptor
The attribute descriptor to be defined or modified
var obj = {} (obj, 'name', { get: function() { ('My name is'+name); return name; }, set: function(value) { ('Your name'+value) name = value; } }); ='Zhang San';//Your name is Zhang San //My name is Zhang San
From the above we can simply discover. When we assign value to the name attribute of this object, the set method will be triggered, and the get method will be triggered when we obtain the name attribute;
2. Therefore, the properties written in data in vue can be converted into getters and setters. In other words, it is responsive. Other data defined outside data are rendered that cannot be responsive, which means that the page will not be refreshed even if it is changed. Therefore, all data to be rendered on the page must be written in data.
If not needed, it can be defined on this.
var vm = new Vue({ data:{ a:1 } }) // `` is responsive = 2 // `` is non-responsive
3. After a brief introduction, let’s list a few examples that do not refresh. Of course, the above is also a kind of
The first type: modify a certain property of the object
vue will only turn attributes that have been declared in data into response, and non-declared will not respond.
<template> <div> <div v-for='item in list'>{{item}}</div> <button @click='click'>Change</button> <button @click='hadelClick'>Solution</button> </div> </template> <script> export default({ data(){ return{ list:{a:'a',b:'b'}, } }, methods: { click() { // Rendering is not triggered without declaration ='c' }, hadelClick(){ // Solution: Use the $set method provided by vue to trigger rendering this.$set(,'d','d') } } }) </script>
Of course if we want to add multiple properties, we can use () to copy the values of all enumerable properties from one or more source objects to the target object and return the target object. (Simply put, merge it into the first parameter)
= ({},,{c:'c',d:'d'})
The second type: modify a certain property of the array object
<template> <div> <div v-for='item in list'>{{}}</div> <button @click='click'>Change</button> <button @click='hadelClick'>Solution</button> </div> </template> <script> export default({ data(){ return{ list:[{a:'vue'},{a:'react'},{a:'js'}], } }, methods: { click() { //If you want to directly assign a value to an object in the array in this way, it cannot be rendered dynamically (that is, if the data is changed, the page will not be rendered) [0] = {a:'css'} //The page does not render () //[{a:'css'},{a:'react'},{a:'js'}] }, hadelClick(){ // Solution: Use the $set method provided by vue to trigger rendering this.$set([1],'a','css') ()//[{a:'css'},{a:'css'},{a:'js'}] } } }) </script>
Of course, as mentioned in the previous article, vue will traverse the data in data and convert the object into setters and getters. So the array is no exception, so the above operation
Change to:
click(){ [0].a = css //Can still trigger setter. Implement data re-rendering } }
In vue, more array operations are not refreshed. One is to assign values through indexes, and the other is to modify the array length. How to solve it?
The vue official also gave a method
The array API can change the original array and updates can be triggered;
1、push()
2、pop()
3、shift()
4、unshift()
5、splice()
6、sort()
7、reverse()
The second type is to return a new array. This array has fundamentally changed in the reference address. Such an assignment operation can trigger updates (this is the idea of not refreshing, that is, to change the reference address and reassign the value to trigger updates)
Simply put, the API using arrays is to directly use the original array to receive the changed array.
<template> <div> <div v-for='item in list'>{{}}</div> <button @click='click'>Change the original array</button> <button @click='hadelClick'>不Change the original array</button> </div> </template> <script> export default({ data(){ return{ list:[{a:'vue'},{a:'react'},{a:'js'}], } }, methods: { click() { //Change the array and refresh the page ({a:'css'}) }, hadelClick(){ //Reassign value and refresh page = (item=>{ = 'css' return item }) } }) </script>
Finally, provide solutions (if you can't handle them above)
Objects and arrays are both reference-passing. To become new arrays and accept them, you need to change the source.
The first type
let arr = []//New array(item=>{ //Arrays that need to be rendered //Execute your operation and finally put it in arr (item) }) = arr //It is equivalent to returning a new array that can trigger rendering
The second type
//I want to directly change the data in the rendered array, but no rendering//Solution:let arr = (0);//Deep copy, (equivalent to a new array)(item=>{ //Perform your operation}) //Assignment operation = arr
Of course, here is just a brief introduction. For detailed introduction to deep copy, please Baidu.
If none of the above can be executed, but your data is missing and modified, you can use this.$forceUpdate() method (force refresh)
//this.$forceUpdate();//Force refresh <template> <div> <div v-for='item in list'>{{}}</div> <button @click='click'>Change</button> <button @click='hadelClick'>Solution</button> </div> </template> <script> export default({ data(){ return{ list:[{a:'vue'},{a:'react'},{a:'js'}], } }, methods: { click() { [0] = {a:'css'} //The page does not render () //[{a:'css'},{a:'react'},{a:'js'}] }, hadelClick(){ [0] = {a:'css'} //The page does not render () //[{a:'css'},{a:'react'},{a:'js'}] this.$forceUpdate();// Force refresh } } }) </script>
The pitfalls encountered in vuex in the above article, vuex data changes, and pages not rendering operations in the components are all the content I share with you. I hope you can give you a reference and I hope you can support me more.