Open uniquejava opened 6 years ago
还有一种办法是将以属性加上 $
和_
前缀, 然后通过this.$data.$xx
或this.$data._xx
来访问, vue不会给以_
和$
开始的变量加上proxy.
https://github.com/vuejs/vue-loader/issues/620
Apparently i didn't try all combinations. here are my notes on how this works and doesn't:
// devtool: 'source-map', // .vue is off by a line or 2. <template>, <style> sections are visible. file structure is clean
// devtool: 'cheap-eval-source-map', // .vue lines are accurate. <template>, <style> are not visible. Lots of weird duplicate files, with ?ffcc, ?ddaa, etc. in the suffix.
devtool: 'cheap-module-eval-sourcemap', // .vue lines are accurate, <template>, <style> sections are visible. But file structure is messed up, the actual debuggable js is in root directory, not in its subfolder where it is in actual source.
``
Vue 2 - Mutating props vue-warn
How to call function on child component on parent events
This only works because the parent is not a component but actually a vue app. In reality this is using the vue instance as a bus.
// parent
click(){
this.$emit('update', 7);
}
// child
created: function() {
this.$parent.$on('update', this.setValue);
}
// parent
click: function() {
this.$refs.childComponent.setValue(2.0);
}
我总结的两句话:
<script>
computed: {
readonly() {
return this.conf.status === 'open';
},
startTime() {
return this.conf.date[0].getTime();
},
},
watch: {
// when rows(transcripts) from parent is ready, set mutable variables in vwatch
rows(rows) {
this.filteredRows = this.clone(rows);
},
conf(conf) {
// when conf from parent is ready, set mutable variables in vwatch
// set readonly variables in vcomputed
if (conf) {
if (conf.status === 'open') {
setupWebSocket(this);
}
}
}
}
</script>
1) 前端Node Server在启动时动态修改index.html, 加入一个特殊的 meta
标签: <meta name=VUE_APP_API_URL value="URL Here" />
const connect = require("connect");
const path = require("path");
const fs = require("fs");
const serveStatic = require("serve-static");
// Enable VUE Configuration With Env Values
let apiUrlFromEnv = process.env.VUE_APP_API_URL || "";
let htmlLocation = path.join(__dirname, "public/index.html");
let html = fs.readFileSync(htmlLocation).toString();
html = html.replace(
/<meta name=VUE_APP_API_URL value="[^"]*">/,
`<meta name=VUE_APP_API_URL value="${apiUrlFromEnv}">`
);
fs.writeFileSync(htmlLocation, html);
connect()
.use("/Hello/ui/", serveStatic(path.join(__dirname, "public")))
.listen(6666, function() {
console.log("apiUrlFromEnv=", apiUrlFromEnv);
console.log("UI Server running on 6666...");
});
2) 在http.js中读取这个URL的值
import { getMetaContent } from '@/utils';
// when starting node.js server in docker(frontend), index.html will be injected a special variable named VUE_APP_API_URL.
// thus we can read api url from this meta tag.
let apiUrlInMeta = getMetaContent('VUE_APP_API_URL');
console.log('apiUrlInMeta=', apiUrlInMeta);
// if api url not specified in docker env, we fallback to use the API url specified when building this vue app.
let axios = Axios.create({
baseURL: apiUrlInMeta || process.env.VUE_APP_API_URL
});
3) 工具类
export const getMetaContent = key => {
let m = document.querySelector(`meta[name=${key}]`);
return m ? m.getAttribute('value') : null;
};
灵感来自: How to access environment variables passed to a Vue app in a docker container at runtime?
Dialog组件不要轻易加props - required检验, 组件一旦被包含进页面(不管是否visible), 就已经被实例化. 如果需要的参数只在dialog打开前才传入
就会出现 vue.runtime.esm.js?2b0e:574 [Vue warn]: Invalid prop: custom validator check failed for prop "xxxxx".
解决办法 1) 去掉required校验. 2) 在dialog上加上v-if="visible"
由于子组件不能直接修改父组件通过prop传递过去的值, 所以需要在watch中复制一份prop数据做为form.
即使不使用=号(只通过点的方式)来修改父组件传过来的prop, 也不方便, 因为如果用户想撤销更改会比较麻烦.
如果想在create的时候清空数据, 在打开对话框前(判断是否为create)如果是create, 则给定一分空白数据(触发dialog内部的watch以清空表单)
空白数据需要在create之前(打开dialog前), 通过prop传给dialog, 不要做为prop的默认值(因为不能触发watch), 也不要做为data的返回值.
3~4 有问题, 同一份数据多次赋值并不会多次触发watch事件. 如果想在每次打开的时候会触发watch, 则在关闭时要将prop重置. (太buggy)
关闭窗口时直接销毁dialog, 很有意思的想法.
OK 和 Cancel完全自定. (作为最后一行el-form-item)
结论是dialog只是用来收集和校验数据的, 点OK是把收集到的数据回传到父组件, 由父组件来调用API持久化数据.
.prettierrc
{
"printWidth": 120,
"tabWidth": 2,
"singleQuote": true,
"bracketSpacing": true,
"trailingComma": "es5",
"semi": false,
"useTabs": false,
"htmlWhitespaceSensitivity": "css"
}
/* .vscode/settings.json */
{
"editor.tabSize": 2,
"editor.formatOnSave": true,
"vetur.experimental.templateInterpolationService": false,
"vetur.format.defaultFormatter.html": "prettyhtml",
"vetur.format.defaultFormatterOptions": {},
"editor.snippetSuggestions": "top",
"[json]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[html]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
}
}
参考: How I Resolved Vue.js, VSCode, Vetur, Prettyhtml, and Prettier Formatting and ES Lint Issues
vue.js源码研究: https://medium.com/@oneminutejs
真正的thinking: Vue.js: the good, the meh, and the ugly
如何定义私有(non reactive) 属性
https://github.com/vuejs/vue/issues/1988
I too would really like an explicit place (that isn't manually done oncreated()
to store non-reactive data. I use them all the time (for things like "dictionaries") that are used in the rendered templates (but never need to trigger a re-render).I'm considering doing this:
and then in my component definitions I can do:
vue-router
push一个路由后, 点back, 前一页怎么才能不lost unsaved changes? (除了使用dialog)
https://stackoverflow.com/questions/41764825/preserve-component-state-with-vue-router
watchers为什么newVal和oldVal总是一样
来自Vue - Deep watching an array of objects and calculating the change?
It is well defined behaviour. You cannot get the old value for a mutated object. That's because both the
newVal
andoldVal
refer to the same object. Vue will not keep an old copy of an object that you mutated.Had you replaced the object with another one, Vue would have provided you with correct references.
Read the
Note
section in the docs. (vm.$watch
)More on this here and here.
dialog中的props值不是最新的??
在dialog组件的data()中this.internalValue=props.xxx, 然后关闭dialog, 修改parent中xxx值, 然后再打开dialog, 发现dialog中的internalValue未及时更新. 解决办法, watch(props.xxx){this.internalValue=props.xxx};
子组件中
v-model="a.b"
不好用(不reactive)这个因为在通过props在传递
a
对象到子组件时, 未给它设置b属性, 只有显式的给a.b
一个初值(即使为null),a.b
才会变得reactive -- 就是说所有在v-model
中出现的属性都必须在props中显式定义.How to convert the object of Vue to normal object
https://github.com/vuejs/Discussion/issues/292
提供的思路有:How to set a component non-reactive data in Vue 2?
https://stackoverflow.com/questions/45814507/how-to-set-a-component-non-reactive-data-in-vue-2
Vue sets all the properties in the
data
option to setters/getters to make them reactive. See Reactivity in depthSince you want
myArray
to be static you can create it as a custom option which can be accessed usingvm.$options
you can iterate over this custom options in your template as follows:
Here is the fiddle