使用 VueJs 从 Razor 重用 @model
问题 对于那些使用 .Net 的人来说,使用 Razor 在服务器端呈现他们的页面是很常见的。而且,很长一段时间以来,当需要进行一些 AJAX 调用或操作一些 DOM 时,我们都将 jQuery 作为盟友。这是默认堆栈。 随着 VueJS 的采用,我们的生活有了很大的改善。但是,每当我们想在Vue项目中表示Razor渲染的对象时,都需要使用Js语法重写整个对象。 在这篇文章中,我打算展示一些如何使
问题
对于那些使用 .Net 的人来说,使用 Razor 在服务器端呈现他们的页面是很常见的。而且,很长一段时间以来,当需要进行一些 AJAX 调用或操作一些 DOM 时,我们都将 jQuery 作为盟友。这是默认堆栈。
随着 VueJS 的采用,我们的生活有了很大的改善。但是,每当我们想在Vue项目中表示Razor渲染的对象时,都需要使用Js语法重写整个对象。
在这篇文章中,我打算展示一些如何使从控制器发送到视图的对象也自动在 Vue 代码中可用。
假设我们有以下结构:
Person.cs
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}
PersonController.cs
public class PersonController : Controller
{
public IActionResult Form()
{
var person = new Person();
return View(person);
}
}
表单输入已经与我们稍后将创建的 Vue 对象的属性绑定。
Form.cshtml
@model Person
<form asp-route="Save" method="post">
<input asp-for="Id" v-model="Model.Id" />
<input asp-for="Name" v-model="Model.Name" />
<input asp-for="Age" v-model="Model.Age" />
</form>
为了让我们在 Vue 项目中使用Person
类,也为了上面的绑定工作,有必要在 Vue 内部重写整个类:
main.js
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
new Vue({
data() {
return {
Model: {
Id: 0,
Name: '',
Age: 0
}
}
},
render: h => h(App),
}).$mount('#app')
显然这是一种非常简单的方法,但仍然有必要以某种方式重写整个Person
类,以便能够访问,如下例所示:
//...
methods: {
changeName () {
this.Model.Name = 'New Name'
}
}
//...
准备工作
我们需要进行 3 次更改才能使事情自动运行。首先,我们将创建一个将要呈现的对象传输为 JSON 格式的方法。在这里,我假设您将创建一个类BaseController
,以便您可以在所有控制器中使用此方法。
BaseController.cs
public class BaseController : Controller
{
protected JsonSerializerSettings jsonSettings;
public BaseController()
{
this.jsonSettings = new JsonSerializerSettings
{
Culture = new CultureInfo("pt-BR"),
DateFormatString = "dd/MM/yyyy",
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
Formatting = Formatting.Indented
};
}
public ViewResult ViewJson(object model, string view = "")
{
// Transformamos o objeto em Json e enviamos para a view usando ViewBags
ViewBag.Model = JsonConvert.SerializeObject(model, this.jsonSettings);
// Depois a view é renderizada normalmente
if (string.IsNullOrWhiteSpace(view))
return View(model);
else
return View(view, model);
}
}
现在对象序列化了,让我们将它添加到一个名为model
的全局 JavaScript 变量中。这个变量稍后将在我们的 Vue 项目中使用。
我们将在布局文件中执行此操作,因为整个系统都将使用此解决方案。
_Layout.cshtml
<html>
<head>
<script>
@if (string.IsNullOrWhiteSpace(ViewBag.Model))
{
<text>const model = null;</text>
}
else
{
<text>const model = @Html.Raw(ViewBag.Model);</text>
}
</script>
</head>
...
</html>
最后,我们需要让全局变量model
可以从 Vue 的根目录访问。
Main.js
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
new Vue({
data() {
return {
Model: model
}
},
render: h => h(App),
}).$mount('#app')
// Sempre adiciono esta linha para deixar o Vue acessível pelo console do navegador
window.vue = vue;
应用更改
现在,只需更改控制器,将方法调用View()
更改为ViewJson()
。
PersonController.cs
public class PersonController : Controller
{
public IActionResult Form()
{
var person = new Person();
//Única alteração necessária nos controllers
return ViewJson(person);
}
}
结论
现在,除了在服务器端呈现的 Razor 页面之外,每个操作都将返回,您还将拥有一个表示在@model
中分配的类的 Vue 对象。
更多推荐
所有评论(0)