Skip to content
This repository has been archived by the owner on Dec 12, 2017. It is now read-only.

关于style-scope跟vue-loader不生效以及vue-router设置html5模式后不能访问的问题 #156

Open
zyanho opened this issue Mar 4, 2017 · 5 comments

Comments

@zyanho
Copy link

zyanho commented Mar 4, 2017

cooking version

1.5.0
cooking init pages-vue from slush-cooking-pages-vue

What is Expected?

我引用了vue-router来做路由,然后有一个路径oauth下有
A for: oauth.html#/
B for: oauth.html#/connect/:type
C for: oauth.html#/callback/:type

问题1:

然后,A有个style是设置body的底色,然后我如果在A的vue文件里面style上设置body的底色,B、C因为是同一个html也会有这样的底色,我希望A有底色,B、C没底色。

第一次尝试想通过vue的refs属性来修改,发现在index.tpl里面设置body的ref无效,只允许设置template里面的dom,此方法失败。

然后我搜索了vuejs的issue列表,看到官方说使用<style scoped>来设置,可以设置局部的样式,但是前提是引用了vue-loader,然后我又查了cooking的一些资料
发现本身cooking有默认添加vue-loader的,但是scoped不生效,
然后我添加了
cooking.add('loader.vue', { test: /\.vue$/, loaders: ['vue-loader'] })
scoped不生效,然后我又查issue,添加了
{ use: 'vue', extends: ['vue'] }
scoped不生效

问题2:

因为cooking的配置会生成一个oauth.html的文件
然后vue-router默认通过#来做路由,但是#在某些第三方授权中会被忽视,所以希望能去掉#
然后我查看了vue-router的文档,通过设置
const router = new VueRouter({ mode: 'history', routes: [...] })
但是由于oauth.html是一个文件,通过nginx
try_files $uri $uri/ /index.html;
也不能正确操作,导致不生效,不知道这个#能否通过什么办法去掉

What is actually happening?

问题1:

style scoped不知道如何才能生效,实际上我看自动生成的oauth.js里面是存在
body[data-v-13991498] {background-color: brown;}
以及
<style scoped> body { background-color: brown; }</style>
但是样式就是没有生效。

问题2:

目前是通过oauth.html?1=1#/connect/:type的方式来绕过

希望能得到你的指导,感谢你的付出。

@lincenying
Copy link

问题1和cooking没有任何关系, scoped生效的前提是当前组件有对应的元素, 你组件里根本没有body这个元素, 有啥用, 建议先去了解下scoped的原理

问题2也和cooking没关系, 自行参考nginx的配置方法

    location / {
        try_files $uri $uri/ /index.html;
    }

    location /oauth {
        try_files $uri $uri/ /oauth.html;
    }

@zyanho
Copy link
Author

zyanho commented Mar 4, 2017

@lincenying 感谢你的回复

我发这个issue本身的前提是我已经尽可能在我能想到的范围内尝试过解决方案,但是没有解决到,所以放issue希望得到一些思路,没有意思去冒犯大家。

针对问题1跟问题2的表象可能跟cooking没有关系,但换个角度来看,能解决这些问题也符合cooking更加便利的初衷?出于问题本身的思考,作为一个可以让非前端人员使用上webpack+vue。

根据我上述的解决过程,虽然不懂具体原理,但是猜测scoped不成功跟ref不成功是类似的,就是body不存在在这个生命周期里面,所以也希望能得到一些新的思路
例如我猜测,是否可以通过把css转成js,然后为这个url加载一个单独的js,然后这个js会把css通过document.write或者innerHtml之类的方式写到,但是因为oauth.html是同一个页面,因此如何为某个vue写上js,我还在研究。

针对问题2,不管是dev还是prod的模式,cooking是通过生成一个html页面来作为多页面应用的,因此,你给出的nginx rewrite的配置是不可能成功的,try_files的用法是检查文件是否存在,第一个文件,第二个是文件夹,第三个是都找不到就定位到某个具体文件。

针对我自己的实现,上述也说了,通过?1=1#/xxx ,能大体解决我的需求,但是我觉得有点别扭,所以想问问看,在cooking生成html的前提下,有什么方式可以尝试。

@lincenying
Copy link

第一个问题, 是vue本身的问题, 你让一个打包工具怎么解决????
scoped 会让vue-loader把组件里的对应元素全部添加一个属性, 做这件事情的是vue-loader, 而不是cooking或者webpack, 你这种情况只能用js去改写body的样式, body都在模版文件里, vue根本没办法去操作, 只能通过js去操作dom

第二个问题, 在history模式, 路由是
http://xxx.com/connect/123
connect/123这个文件肯定不存在, 所以要通过路径重写, 把路径定位到对应的文件上

location /connect {
        try_files $uri $uri/ /oauth.html;
}

怎么就不可能成功了?

就算在dev模式下, 你不配置路径重写, 除了index.html这个入口可以用history模式, 其他的你也一样只能用hash模式

@zyanho
Copy link
Author

zyanho commented Mar 4, 2017

@lincenying 没事了,我已经研究出来了,希望能帮到其他需要的人。

针对想为某个vue页面增加style而不影响其他vue,我的做法是在mounted时操作把style写到dom去

const styles = 'body{background-color: yellow;}';
var css = document.createElement('style');
css.type = 'text/css';
if (css.styleSheet) css.styleSheet.cssText = styles;
else css.appendChild(document.createTextNode(styles));
document.getElementsByTagName('head')[0].appendChild(css);

针对cooking使用vue-router
dev环境下nginx使用以下配置

location @oauth {
    rewrite ^ /oauth.html$1;
    proxy_pass http://127.0.0.1:8080;
 }

location ^~ /oauth {
    try_files $uri $uri/ @oauth;
 }

prod环境下nginx使用以下配置

location /oauth {
    root /test-vue/dist/;
    try_files $uri $uri/ /oauth.html =404;
}

此issue可以close了

@cartWalk
Copy link

求解 hostory 模式 打包后的代码 这样设置nginx 还是404呢
server {
listen 8080;
server_name localhost;
location / {
root www;
try_files $uri $uri/ /index.html =404;
}
}

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants